diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index 81a41e0c..005438b1 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -23,23 +23,23 @@ through `@theme inline`, so `bg-`, `text-`, `border-`, `ring-`, `fill-` and `stroke-` all accept them, including opacity modifiers such as `bg-success/10`. One token class replaces a light + dark pair. -| Token | Use for | Replaces | -| --------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------- | -| `background`, `foreground` | page surface and primary text | `bg-white`, `text-gray-700/800/900`, `dark:text-gray-200/300` | -| `card`, `card-foreground` | raised surfaces (cards, dialogs, dropdowns) | `bg-white dark:bg-[#2b2c31]` | -| `popover`, `popover-foreground` | floating menus and popovers | same as card | -| `muted`, `muted-foreground` | quiet fills and secondary text, icons, placeholders, timestamps | `bg-gray-100/200`, `text-gray-400/500/600`, `dark:text-gray-400` | -| `accent`, `accent-foreground` | hover and selected fills | `hover:bg-gray-100`, `dark:hover:bg-gray-700` | -| `border`, `input`, `ring` | dividers, field borders, focus rings | `border-gray-200/300`, `dark:border-gray-600/700` | -| `primary`, `primary-foreground` | brand purple: primary actions, links, selected states | `bg-purple-*`, `text-purple-*`, `#7D54D1`, `#A076F6` | +| Token | Use for | Replaces | +| --------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `background`, `foreground` | page surface and primary text | `bg-white`, `text-gray-700/800/900`, `dark:text-gray-200/300` | +| `card`, `card-foreground` | raised surfaces (cards, dialogs, dropdowns) | `bg-white dark:bg-[#2b2c31]` | +| `popover`, `popover-foreground` | floating menus and popovers | same as card | +| `muted`, `muted-foreground` | quiet fills and secondary text, icons, placeholders, timestamps | `bg-gray-100/200`, `text-gray-400/500/600`, `dark:text-gray-400` | +| `accent`, `accent-foreground` | hover and selected fills | `hover:bg-gray-100`, `dark:hover:bg-gray-700` | +| `border`, `input`, `ring` | dividers, field borders, focus rings | `border-gray-200/300`, `dark:border-gray-600/700` | +| `primary`, `primary-foreground` | brand purple: primary actions, links, selected states | `bg-purple-*`, `text-purple-*`, `#7D54D1`, `#A076F6` | | `secondary`, `secondary-foreground` | pressed and active toggles (a brand tint), secondary buttons, the question bubble | `bg-accent` on an active icon button | -| `destructive`, `destructive-foreground` | errors, failed states, dangerous actions | `text-red-*`, `bg-red-50/100`, `#B42318`, `#E60000` | -| `success`, `success-foreground` | completed, active, healthy | `text-green-*`, `text-emerald-*`, `bg-green-50/100` | -| `warning`, `warning-foreground` | paused, pending review, degraded | `text-amber-*`, `text-yellow-*`, `text-orange-*`, `bg-amber-50/100` | -| `info`, `info-foreground` | running, informational | `text-blue-*`, `bg-blue-50/100` | -| `sidebar-*` | the navigation rail | | -| `chart-1` to `chart-5` | data series only, never UI chrome (see below) | | -| `answer-bubble` | assistant message background | | +| `destructive`, `destructive-foreground` | errors, failed states, dangerous actions | `text-red-*`, `bg-red-50/100`, `#B42318`, `#E60000` | +| `success`, `success-foreground` | completed, active, healthy | `text-green-*`, `text-emerald-*`, `bg-green-50/100` | +| `warning`, `warning-foreground` | paused, pending review, degraded | `text-amber-*`, `text-yellow-*`, `text-orange-*`, `bg-amber-50/100` | +| `info`, `info-foreground` | running, informational | `text-blue-*`, `bg-blue-50/100` | +| `sidebar-*` | the navigation rail | | +| `chart-1` to `chart-5` | data series only, never UI chrome (see below) | | +| `answer-bubble` | assistant message background | | Status colours are tuned to stay vivid rather than turning brown or olive, so their contrast is low. Against white in light mode, `destructive` and @@ -89,11 +89,11 @@ Patterns: ### Button (`ui/button.tsx`) -| Prop | Values | -| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `variant` | `default`, `secondary`, `outline`, `outline-primary`, `ghost`, `ghost-muted`, `ghost-destructive`, `link`, `destructive`, `destructive-outline`, `combobox`, `sidebar-item`, `tab`, `section-toggle` | -| `size` | `xs`, `sm`, `default`, `lg`, `field`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `inline` | -| `shape` | `default` (rounded-md), `pill` (rounded-full, wider padding) | +| Prop | Values | +| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `variant` | `default`, `secondary`, `outline`, `outline-primary`, `ghost`, `ghost-muted`, `ghost-destructive`, `ghost-on-accent`, `ghost-destructive-on-accent`, `link`, `destructive`, `destructive-outline`, `combobox`, `sidebar-item`, `tab`, `section-toggle` | +| `size` | `xs`, `sm`, `default`, `lg`, `field`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `inline` | +| `shape` | `default` (rounded-md), `pill` (rounded-full, wider padding) | - Round brand buttons (`rounded-3xl px-5`, `rounded-full px-6`): `shape="pill"`, plus `size="lg"` if they were `px-6`. @@ -102,6 +102,14 @@ Patterns: - Icon actions that remove something (a trash can on a member or shared resource row) are `variant="ghost-destructive"`: muted at rest, red on hover, so the warning shows even where the click deletes without asking. +- Icon buttons on a row that is already `bg-accent` or `bg-sidebar-accent` + while you point at it (a highlighted Command item, a card or tile with + `hover:bg-accent`, a hovered sidebar row) are `variant="ghost-on-accent"` + (delete: `ghost-destructive-on-accent`). They hover with a + `foreground/15` (`destructive/15`) tint, which shows on accent where + ghost's accent square would not. +- Icons are `lucide-react` at the default stroke (2). Don't pass + `strokeWidth`, and don't use an `` for a glyph lucide has. - Bordered purple buttons (`border-primary text-primary hover:bg-primary`): `variant="outline-primary"`. - Tiny inline actions (`h-auto px-2 py-1 text-xs`): `size="xs"`. @@ -117,9 +125,10 @@ Patterns: while `data-placeholder` is set (`data-placeholder={value ? undefined : ''}`). Pass only layout (`w-full justify-between`) and keep the chevron as the last child. -- A button or picker that sits in a row of fields is `size="field"`: 42px, - the height of `Input` (default) and `SelectTrigger size="lg"`, so a form - column has one height. With `shape="pill"` its text starts 21px in, like +- A button or picker that sits in a row of fields is `size="field"`: 42px. + `Input` and `SelectTrigger` take `size="field"` too (the same 42px as + Input `default` and SelectTrigger `lg`), so a form column has one name for + one height; prefer `field` in new form rows. With `shape="pill"` its text starts 21px in, like the Input and Select pills beside it. The agent form's pickers are `combobox field pill`, its Add button `outline-primary field pill`. - Rows in the navigation sidebar (`hover:bg-sidebar-accent … pl-3 gap-2.5 @@ -136,20 +145,37 @@ rounded-3xl`) are `variant="sidebar-item"`: left-aligned, full-radius, normal gives it `foreground` text and a `primary` underline. Padding-free tabs (a sub-nav with `gap-6`) add `size="inline"`, which keeps 4px above the line; the row draws the 1px baseline, and `-mb-px` lays the underline over it. - Tabs that switch a panel in place use `ui/tabs` instead. + Use them for a row of route links (the agent sub-nav: a `