Xpand Design System
A reference for the visual language of the Xpand product. Use this page as the source of truth when building features — it defines the design tokens, documents which CSS custom properties each component consumes, and shows how clients can rebrand the app to match their identity.
All color, typography, and layout values are set in Settings → Theme and emitted as CSS custom properties on :root. Every component reads exclusively from those variables — no hard-coded values exist in module CSS.
Brand style guide and components
Every component has a dedicated documentation page with live examples, a CSS variable table, and developer notes. Click any card to open it.
Color tokens Open ↗
Colors are grouped into Brand, Text, Surface, Borders, and Semantic. Each token is defined in fields.json under theme.global_colors and emitted as a CSS custom property on :root via css/_fonts.css. All components CSS references these variables directly — changing a token in the theme editor updates every module that uses it instantly.
| Swatch | Token | Value | CSS variable | Source path | Where it shows up |
|---|---|---|---|---|---|
| Primary Brand |
#5532F0 |
--color-primary |
theme.global_colors.primary_color.color |
Lead brand color. Drives primary buttons, active nav state, links, focus rings. The single highest-impact token for rebranding. | |
| Secondary Brand |
#EB8223 |
--color-secondary |
theme.global_colors.secondary_color.color |
Supporting brand color. Use for card titles and accents that pair with primary. | |
| Heading Text |
#333333 |
--color-heading |
theme.global_colors.heading_color.color |
Default color for h1–h6 and high-emphasis labels. | |
| Body Text |
#68717A |
--color-body |
theme.global_colors.body_color.color |
Default body copy and form helper text. | |
| Muted Text |
#949494 |
--color-muted |
theme.global_colors.muted_color.color |
Section labels and other low-emphasis copy. | |
| App background Surface |
#EEF2F6 |
--color-app-bg |
theme.global_colors.app_background.color |
Outermost canvas behind sidebars and panels. | |
| Page background Surface |
#F8FAFC |
--color-page-bg |
theme.global_colors.page_color.color |
Subtle page tint used for inputs, modal footers, zebra rows. | |
| Surface Surface |
#FFFFFF |
--color-surface |
theme.global_colors.menu_background.color |
Solid surface for cards, menus, modals, side panels. | |
| Hover surface Surface |
#F1F5F9 |
--color-hover-surface |
theme.global_colors.hover_surface.color |
Tinted hover background for nav links, panel links, clickable rows. | |
| Border Surface |
#BBBBBB |
--color-border |
theme.global_colors.border_color.color |
Default border for inputs, outline buttons, breadcrumb separators. | |
| Divider Surface |
#E5E7EB |
--color-divider |
theme.global_colors.divider_color.color |
Light hairlines for tree menus, side panels, section dividers. | |
| Light grey Surface |
#C4CAD4 |
--color-light-grey |
theme.global_colors.light_grey_color.color |
Subdued borders for select boxes, tree toggles, disabled states. | |
| Table cell Surface |
#E7EBF2 |
--color-table |
theme.global_colors.table_color.color |
Border between table cells and around input addons. | |
| Success Status |
#198754 |
--color-success |
theme.global_colors.success_color.color |
Confirmation states: success badges, positive trend. | |
| Warning Status |
#FFC107 |
--color-warning |
theme.global_colors.warning_color.color |
Caution states: warning badges, attention banners. | |
| Error Status |
#DC3545 |
--color-error |
theme.global_colors.error_color.color |
Destructive states: danger buttons, error labels, destructive links. |
Typography tokens Open ↗
Typography is configured once and inherited by every component. The body and heading font families, base font size, line height, and heading scale (h1–h6) are all defined in theme.typography and exposed as CSS custom properties: --font-body, --font-heading, --font-size-base, and --line-height-base. Individual heading sizes are applied directly to h1–h6 elements in css/_fonts.css.
| Token | Current value | CSS variable | Source path | What it controls |
|---|---|---|---|---|
| Body font | Poppins |
--font-body |
theme.typography.body_font |
Default font family. Applied to body and inherited by every text element that does not override it. |
| Body size | 16px |
--font-size-base |
theme.typography.body_font.size |
Base font-size on body. Most paragraph and form copy inherits this. |
| Heading font | Poppins |
--font-heading |
theme.typography.heading_font |
Family for h1–h6. Pick something with character; pair with a readable body font. |
| Heading weight | 600 |
— |
theme.typography.heading_font.styles |
Default weight for h1–h6. |
| Line height | 1.5 |
--line-height-base |
theme.typography.line_height |
Base body line-height. Increase for more breathing room in dense screens. |
| H1 size | 40px |
— |
theme.typography.h1_size |
Top-level page title size. |
| H2 size | 32px |
— |
theme.typography.h2_size |
Major section heading. |
| H3 size | 26px |
— |
theme.typography.h3_size |
Sub-section heading. |
| H4 size | 22px |
— |
theme.typography.h4_size |
Card titles and component headings. |
| H5 size | 18px |
— |
theme.typography.h5_size |
Sidebar links and small panel headings. |
| H6 size | 14px |
— |
theme.typography.h6_size |
Eyebrows and section headers. |
| Small text size | 12px |
— |
theme.typography.small_size |
Captions, footers, and the .font--small utility. |
Live preview
Heading 1 — the quick brown fox
Heading 2 — jumps over
Heading 3 — the lazy dog
Body paragraph. This block renders against the current theme.typography values. Change them in Settings → Theme and refresh.
Layout tokens
Layout tokens control the global content width and the base border-radius applied
to interactive surfaces. --radius-base is the single token that most
affects the overall “feel” of a brand — set it to 0
for a sharp, enterprise look or raise it for a softer appearance.
| Token | Current value | CSS variable | Source path | What it controls |
|---|---|---|---|---|
| Max content width | 4400px |
— |
theme.layout.max_width |
Maximum width of the main content column. Larger values produce roomier dashboards on wide screens. |
| Base border radius | 5px |
--radius-base |
theme.layout.border_radius |
Corner radius for nav links, panel links, cards, and other interactive surfaces. Set 0 for sharp / neutral, raise for a softer feel. |
Component reference
Each entry below describes a module and lists the CSS custom properties it consumes. All variables resolve from the token definitions above. No module contains hard-coded color or font values.
Buttons Open ↗
Module: buttons.module
Five visual variants: primary, secondary, outline primary, outline secondary, and danger. Supports an optional leading icon, dropdown trigger, and a disabled state.
CSS variables:
--btn-primary-bg— primary button background--btn-primary-text— primary button text and icon color--btn-primary-hover-bg— primary hover / active state--btn-secondary-bg— secondary button background--btn-outline-primary-color— outline-primary border & text--btn-outline-secondary-border— outline-secondary border--btn-danger-bg— danger button background--btn-radius— button corner radius--btn-font-size— button label font size
Input Open ↗
Module: input.module
Single-line text input with optional leading and trailing icon addons, optional tinted background, and five semantic width classes: w-xs (160 px), w-sm (240 px), w-md (380 px), w-lg (560 px), w-full (100%).
CSS variables:
--color-page-bg— tinted input background--color-table— icon addon borders--color-body— icon fill inside addons
Select Open ↗
Module: select.module
Four shapes in one module: simple select, select with a counter badge, input-with-button combo, and numeric counter.
CSS variables:
--color-primary— active highlight and badge--color-surface— dropdown panel background--color-page-bg— input background--color-heading— selected text--color-body— option text--color-light-grey— select border and dividers
Checkbox / Radio / Toggle Open ↗
Module: checkboxes.module
A single control that renders as a radio button, round checkbox, toggle switch, or standard checkbox depending on the selected type. Includes a disabled state.
CSS variables:
--color-primary— checked and “on” state fill
Tabs Open ↗
Module: tab.module
Tabbed navigation with two visual styles. Style 2 adds counter pills to each tab.
CSS variables:
--color-primary— active tab text and underline indicator--color-heading— inactive tab text--color-border— bottom rule and pill background
Breadcrumbs Open ↗
Module: breadcrumb.module
Hierarchy indicator showing a home icon, parent link segments, and the current page. The current page item is non-interactive.
CSS variables:
--color-border— separator icons--color-body— parent link text
Cards Open ↗
Module: cards.module
Five preset dashboard card styles. Each variant uses a distinct accent border on the bottom edge: neutral, primary, danger, success, or brand.
CSS variables:
--color-surface— card background--color-secondary— card title--color-body— card body text--color-primary— primary accent border--color-error— danger accent border--color-success— success accent border--color-border— card outline--color-table— inner dividers
Modal Open ↗
Module: modals.module
A dialog with an editable title, body content, and two footer actions. The confirm action supports a primary or danger variant.
CSS variables:
--color-primary— confirm action button--color-surface— modal background--color-heading— modal title--color-border— header and footer dividers--color-page-bg— modal footer background
Data table Open ↗
Module: tables.module
Data table layout with profile links, status indicator circles, action menus, and archive controls. Status circles must always reference a status token, not a literal color.
CSS variables:
--table-cell-border— cell borders and wrapper frame--table-header-bg— header row background--table-row-hover-bg— row hover background--table-stripe-bg— zebra stripe alternate rows--color-primary— profile links and row action icons--color-error— archive / destructive action--color-success— active status circle
Search panel Open ↗
Module: search.module
Full-screen overlay search with a query field, recent items list, and a people picker. The header avatar background uses --color-primary.
CSS variables:
--color-surface— panel background--color-page-bg— search input background--color-border— input border and dividers--color-primary— avatar background and search highlight--color-body— result item text--color-heading— result item headings
Menu Open ↗
Modules: menu-first.module — full sidebar with labels; menu-second.module — icon rail with slide-out panel.
Two navigation patterns sharing the same active-state indicator: a 3 px --color-primary bar on the left edge of the active link.
CSS variables:
--color-app-bg— sidebar outer background--color-surface— sidebar panel fill--color-heading— nav item labels--color-primary— active indicator bar and active text--table-row-hover-bg— nav link hover background--color-muted— section group labels--color-divider— section separator lines--radius-base— nav link corner radius
Fonts Open ↗
Global: css/_fonts.css
Typography scale applied globally. Heading and body font families, sizes for h1–h6, base font size, and line height are all driven by theme.typography.*.
CSS variables:
--font-body— body copy font family--font-heading— heading font family--font-size-base— base body font size--line-height-base— base line height
Per-client rebranding
All tokens are editable in Settings → Theme. The following sequence covers a full rebrand:
- Set Primary color. This single token drives buttons, active nav state, links, and focus rings — the highest-impact change.
- Set Secondary color to complement the primary — used for secondary buttons and card title text.
- Set Body font and Heading font.
- Adjust App background and Surface if the brand needs a darker or lighter canvas.
- Set Base border radius to
0for a sharp enterprise look or raise it for a softer feel. - Change Success, Warning, and Error only when the brand explicitly requires it — defaults are WCAG AA compliant. Verify any override for contrast.
- Reload this page to confirm the token tables and live previews above reflect the updated brand.