Files
app/DESIGN-GUIDELINES.md
T

8.8 KiB
Raw Blame History

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 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-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 <MotionConfig reducedMotion="user">.

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.
  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 <html> 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.