# Fluksio design guidelines UI reference for the app, its dashboard editor and documentation site. Paths below are relative to this repository. ## Design language Use neutral white and near-black surfaces with a slate-blue primary accent. Reserve terracotta for one secondary action per view. `--card` is the main surface. Separate surfaces with borders and elevation. Controls are pills; cards and panels use a 16px radius. ## Colour tokens | Token | Light | Dark | Use | |---|---|---|---| | `--background` | `#ffffff` | `#0a0a0a` | page | | `--foreground` | `#333232` | `#f5f5f5` | body text | | `--card` / `--popover` | `#ffffff` | `#1a1a1a` | dominant surface; dark lifts above the page | | `--card-foreground` / `--popover-foreground` | `#333232` | `#f5f5f5` | text on those surfaces | | `--primary` | `#4a7189` | `#7ba3b8` | primary fills, active state, focus ring | | `--primary-foreground` | `#ffffff` | `#0a0a0a` | text on `--primary` | | `--primary-nested` | `#152128` | `#345160` | a reading drawn inside a `--primary` fill | | `--brand-secondary` | `#de8f6e` | `#e5a184` | the one secondary call-to-action per view | | `--brand-secondary-foreground` | `#333232` | `#0a0a0a` | text on `--brand-secondary` | | `--secondary` / `--muted` | `#f2f2f2` | `#232323` | recessed surfaces | | `--secondary-foreground` | `#333232` | `#f5f5f5` | text on those | | `--muted-foreground` | `#6b6b6b` | `#a3a3a3` | secondary text, section headers | | `--accent` | `#f5f5f5` | `#262626` | hover / selected surface | | `--accent-foreground` | `#333232` | `#f5f5f5` | text on `--accent` | | `--destructive` | `#b94d4d` | `#cf6666` | destructive actions, failing nodes | | `--status-success` | `#5e8b6d` | `#87b596` | a node's last run succeeded | | `--status-warning` | `#b45309` | `#e8a33d` | a node that works, but degraded, such as a device that is offline | | `--chart-1` … `--chart-8` | see [Chart palette](#chart-palette) | | chart series, in slot order | | `--border` / `--input` | `#e4e4e4` | `#2a2a2a` | hairlines, field borders | | `--ring` | `#4a7189` | `#7ba3b8` | focus ring; always equals `--primary` | | `--sidebar*` | mirrors card / accent / primary | | sidebar surface set | The identity blue `#59849b` stays in the wordmark. Use `--primary` for controls so text on primary fills meets contrast requirements. `--primary-nested` is for stacked readings inside a primary fill, separated by a gutter. - Use tokens in UI components. Custom SVG glyphs may use `currentColor`. - Keep `--sidebar-accent` equal to `--accent`. - Use one `--brand-secondary` action per view. - Name every status in text. Running uses `--primary`, success `--status-success`, failure `--destructive`, and degraded `--status-warning`. Idle has no indicator. - Home's brain graph uses primary discs as its identity. Its outer ring uses `--foreground` for runnable nodes and terracotta for flow faults. Failed nodes keep a terracotta disc until acknowledged. Persistent faults keep their labels visible. ### Chart palette | Slot | Hue | Light | Dark | |---|---|---|---| | 1 | `--primary` | `#4a7189` | `#7ba3b8` | | 2 | orange | `#e26f00` | `#d26600` | | 3 | violet | `#6f49ca` | `#8d71e6` | | 4 | green | `#00721b` | `#55c15e` | | 5 | orchid | `#c66ae1` | `#dd8bf6` | | 6 | ochre | `#966a00` | `#ae7c00` | | 7 | teal | `#00a093` | `#00c0b1` | | 8 | magenta | `#b32474` | `#bf4483` | Take colours in slot order. Line charts stop at five series and show a legend when there is more than one. Reserve red, sage green and amber for status. The terminal UI uses the terminal's named ANSI colours instead. ## The dashboard is exempt User-defined dashboards can choose `fluksio`, `material` or `glass` under `frontend/src/components/Dashboard/ui/`. The default `fluksio` look follows these guidelines. Other looks may change surfaces and motion. Behavior, keyboard handling and accessibility stay in `ui/core/`. A dashboard palette overrides tokens on its own canvas, with colours assigned by position. It must preserve contrast, named status, 44px touch targets and reduced-motion behavior. Fault and success colours keep their meanings. Widgets use container queries to follow their tile size. Dashboard motion presets live in `ui/core/motion.ts`; the app shell uses `frontend/src/lib/motion.ts`. ## Typography Use the self-hosted Inter variable font at `frontend/public/fonts/inter-latin-variable.woff2` for body text, headings and wordmarks. `.font-display` selects it for display text. Use the system monospace stack through `font-mono` for code, message names and payloads. Use Tailwind's size scale. Arbitrary `text-[…]` sizes are banned and checked by the `no-arbitrary-font-size` hook. Section headers use: ```text text-xs font-medium uppercase tracking-[0.5px] text-muted-foreground ``` ## Radius | Utility | Value | Use | |---|---|---| | `rounded-full` | pill | buttons, inputs, toggles, chips, badges | | `rounded-sm` | 8px | checkboxes, small chips, nested items | | `rounded-md` | 12px | menus, popovers, tooltips, textareas | | `rounded-lg` | 16px | cards, panels, dialogs, alerts, sidebar | | `rounded-xl` | 28px | large containers | ## Elevation Use `shadow-e1` for resting cards, `shadow-e2` for floating surfaces, and `shadow-e3` for modals. Avoid arbitrary or stock shadow utilities on surfaces. Borders use `border border-border`, or `border-input` on fields. ## Motion Use the `motion` package with presets from `frontend/src/lib/motion.ts`. Keep JavaScript timings aligned with the CSS easing and duration tokens. - Easing is `emphasized` for entering or expressive movement, `standard` for neutral transitions. - Durations are 150, 200 and 300 ms. One-shot activity feedback uses 500 ms. - Variants are `fadeIn`, `scaleIn`, `slideUp`, `overlayFade` and `listStagger`. - Wrap the app in ``. ## Microcopy Keep captions short. Put explanations in `InfoTip`, `PanelSection.help` or `FieldLabel.help`. A tooltip holds one or two sentences; longer instructions belong in the docs. Help must work by tap as well as hover. Visible supporting text describes state, such as an empty list, a stopped flow or an error. A page may have one descriptive line below its heading. Say what a control does. Keep design rationale in repository documentation. Avoid em dashes in UI strings. Empty-value placeholders and structural separators are allowed. The `no-em-dash` hook checks these rules, with separators listed in `frontend/scripts/no-em-dash.allow.json`. ## Iconography Use Lucide. Custom glyphs belong in `frontend/src/components/icons/` as 24×24 SVGs with no fill, `currentColor` strokes, weight 2 and round caps. ## Shells The authenticated app uses a `bg-card` region with a floating translucent sidebar. The flow editor floats its controls over the node canvas. Both use `bg-card/80 backdrop-blur-md`, a token border and `shadow-e2`. ## Responsive Use `md` at 768px as the mobile boundary. Keep `useIsMobile()` and Tailwind's `md:` usage aligned, with stock breakpoints. 1. Keep the page within the viewport. Give wide tables and charts their own `overflow-x-auto` region. Use `min-w-0` on flex and grid children when content could stretch the page. `frontend/tests/mobile.spec.ts` checks this. 2. Cap floating controls with `max-w-[calc(100vw-2rem)]` and allow wrapping. The editors' dock is the exception below `md`: a bar across the full width, flush with the bottom edge (`bg-card`, top border, no shadow, safe-area inset), whose brand button drops its caption so the usual row fits at 44px. 3. Use 44px touch targets below `md`, 32px above. Use `icon-touch`, `sm-touch` or matching responsive utilities. 4. Turn floating panels into full-screen sheets on phones with the shared `Flow/SidePanel`. Gate canvas side insets behind `md:`. 5. Provide tap or visible alternatives to hover actions. 6. Keep dragging, placing and resizing on desktop. Flow layout is automatic, left-to-right on desktop and top-to-bottom on phones. Rectangular dashboard grids stack to one column on phones. Use `grid gap-* sm:grid-cols-2 lg:grid-cols-N` for card grids and `p-4 sm:p-6 md:p-8` for page gutters. ## Overlay surfaces & content chips Floating surfaces use `bg-card/80 backdrop-blur-md`, a token border and `shadow-e2`. Use token alpha for translucency; panel opacity also fades text. Content chips are transparent at rest and fill on hover or selection. Use `hover:bg-accent/50` where hover and selection need distinct states. Segmented controls use one bordered pill with no dividers, transparent segments and `bg-accent` for the selected segment. ## UI configuration `frontend/components.json` uses shadcn style `new-york`, CSS variables and Lucide icons. Components under `frontend/src/components/ui/` are owned by this repository. Update token definitions, component usage and this reference together when changing the design. ## UX - Keep common actions easy to reach without context menus. - Apply theme through the `.dark` class on `` and the pre-paint theme script so the first frame uses the chosen theme. - A dashboard subtree can use `.theme-light` or `.theme-dark` independently. Menus and tooltips rendered outside it must carry that theme class too.