Appearance
Your People — Design
This document captures the visual and structural rules for the Your People rebuild. It is the single source of truth that maps the design exploration onto the production codebase (Vue 3 + Tailwind v4 + Headless UI + Iconify MDI + ApexCharts).
1. Tokens
All design tokens live in src/assets/main.css under the Tailwind v4 @theme block.
1.1 Colour
| Token | Hex | Use |
|---|---|---|
primary-500 | #0693E3 | Primary buttons, links, focus rings, active nav fill, chart accent |
primary-600 | #047DC2 | Primary button hover |
primary-700 | #036FAE | Primary text on tinted backgrounds (accent-ink) |
primary-100 | #DDF1FE | Accent-tinted surfaces (selected rows, info pills) |
secondary-400 | #8ED1FC | Light brand decoration, chart secondary series |
bg | #F9F9F9 | Page background |
surface | #FFFFFF | Cards, tables, modals, top nav |
surface-3 | #F3F3F4 | Sidebar nav background, container hover, soft buttons |
border | #ECECEE | All hairlines, table dividers |
ink / ink-2 / ink-3 / ink-4 | #18181B → #A1A1AA | Text scale: heading / body-strong / body / muted |
success-500 | #0E8A5F | Paid, active, healthy |
warning-500 | #B97A0B | Pending, awaiting, expiring |
danger-500 | #C53B3B | Failed, lapsed, destructive |
Rules
- Primary is the only action colour. Don't introduce a second blue.
- Semantic colours are only for status — never for decoration.
secondary-400is a brand accent for charts and illustration. Don't use it for interactive elements.
1.2 Type
Font stack: Geist (sans), Geist Mono (mono). Headings sit at font-weight: 600, body at 400/500.
| Role | Size / weight | Tracking |
|---|---|---|
| Page H1 | 28px / 600 | -0.012em |
| Section title (card) | 13px / 600 | -0.005em |
| Body | 14px / 400 | -0.003em |
| Small / meta | 12px / 400 | 0 |
| Eyebrow | 11px / 600 uppercase | 0.12em |
| KPI value | 28px / 600 tabular-nums | -0.02em |
| Mono (IDs) | 12px / 500 Geist Mono | 0 |
Use font-variant-numeric: tabular-nums for any number that lives in a table column or KPI tile. Use mono for member IDs (70099274), invoice IDs (INV-39281), Stripe IDs (pi_3OkLm7…), and event ticket IDs (YP-A8-2719).
1.3 Radius, shadow, spacing
- Radii:
sm 6px,md 10px,lg 14px. Tables and dropdowns usemd. Pills are fully rounded. - Shadows: deliberately quiet.
shadow-smresting,shadow-mdfloating,shadow-lghero only. - Spacing follows Tailwind defaults. Page padding is
36pxleft/right,18pxtop.
2. Layout
2.1 The shell
Three regions, fixed. Sidebar (left) · Top nav (top) · Content panel (right of sidebar, below top nav).
Sidebar
- Background:
surface-3(#F3F3F4). - 232px wide expanded, 64px collapsed (icon-only).
- Active item: full primary fill (
#0693E3) with white text. No left-border accent. - Inactive items:
ink-2text, hover backgroundsurface(white). - Logo at top: full lockup when expanded, square mark when collapsed.
- Organisation card pinned to bottom.
Top nav
- White surface, single
borderline below. - Contents only: command-centre search (left), help, notifications, signed-in user (name + role).
- No breadcrumbs, no page actions in the top nav.
- Signed-in user is rendered as name + role label, not an avatar circle.
Content panel
padding: 18px 36px 36px.- First child: breadcrumb row (
12.5px, tight margin to page header). - Page header sits next:
eyebrow → H1 → sub, left-aligned. - Page-level action buttons float in the top-right of the content panel, vertically aligned with the H1.
2.2 Breadcrumb
Pet Industry Federation / Members / Manage
Slash separator in ink-4. Trailing crumb in ink bold, earlier crumbs in ink-3.
3. Components
3.1 Buttons
| Variant | Background | Text | Hover | Focus ring |
|---|---|---|---|---|
primary | primary-500 | white | primary-600 | primary-400 |
secondary | surface + border | ink-2 | surface-3 | primary-400 |
danger | danger-500 | white | danger-700 | danger-500 |
Heights: sm 28px, md 32px, lg 40px. Radius sm (6px). Icons inside buttons 14px, 6px gap.
3.2 Cards
border-radius: 10px
border: 1px solid border
background: surface
shadow: shadow-sm
padding: 22px (airy) / 16px (balanced) / 12px (dense)3.3 Tables
- Header row:
surface-2background,11.5px / 500 uppercase 0.07eminink-3. - Body rows:
44pxheight (balanced), border-bottomborder, hoversurface-2. - Numeric columns right-aligned with
tabular-nums. - Strong column (the row's "label") in
ink / 500. Everything else inink-2. - IDs in
monoandaccent-ink(primary-700). - Status column always uses a pill, never raw text.
3.4 Pills & badges
Fully rounded, 2px / 8px padding, 11.5px / 500. A pip dot precedes the label.
| Pill | Background | Text |
|---|---|---|
| Neutral | surface-3 | ink-2 |
| Positive | success-50 | success-500 |
| Warning | warning-50 | warning-500 |
| Negative | danger-50 | danger-500 |
| Info | primary-100 | primary-700 |
3.5 KPI tile
Four metrics across the top of analytical screens. Always a single row, equal width.
label ← 12px / 500 ink-3
value +delta ← 28px tabular-nums + 11.5px positive/negative
sparkline ← 30px high, primary (or danger if metric is bad)3.6 Filter chip
Pill-shaped, 28px tall, 12px / 500. Active state: solid ink background, white text.
3.7 Forms
- Inputs: 28–32px tall,
surface-2background,1px border,radius-sm. - Labels above inputs,
11.5px / ink-3. - Validation messages below,
12px / danger-500.
4. States
Every list, table, and detail screen must implement the three states.
| State | Component | Visual |
|---|---|---|
| Loading | <StateSkeleton> | Shimmer rectangles matching the eventual layout. Don't show a spinner over an empty screen. |
| Empty | <StateEmpty> | Centred icon + title + body + primary CTA + secondary action. |
| Error | <StateError> | Tinted banner card (danger-50 background, danger-500 border). |
5. Icons
Use MDI via Iconify. Default size 1em. Sidebar 16px, button icons 14px.
vue
<Icon icon="mdi:account-multiple-outline" />| Role | Icon |
|---|---|
| Dashboard | mdi:view-dashboard-outline |
| Members | mdi:account-multiple-outline |
| Events | mdi:calendar-month-outline |
| Financials / Payments | mdi:credit-card-outline |
| Marketing | mdi:bullhorn-outline |
| Selections / Filters | mdi:filter-variant |
| Reports | mdi:chart-bar |
| Settings | mdi:cog-outline |
| Search | mdi:magnify |
| Notifications | mdi:bell-outline |
| Help | mdi:help-circle-outline |
| Add / New | mdi:plus |
| Download / Export | mdi:download-outline |
6. Charts
Use ApexCharts through vue3-apexcharts. Colours primary-500 + ink-2. Grid 1px dashed border. Tooltips surface with border 1px. Line stroke 2px, area fill 12%.
7. Density
Density is a per-component prop on <AppCard> (and any future surface that adopts the same scale). It controls card padding; table row height is set on the table itself when a denser variant is needed.
| Density | Card padding | Table row | Default |
|---|---|---|---|
airy | 22px | 52px | ← yes |
balanced | 16px | 44px | |
dense | 12px | 36px |
8. Mock data conventions
- Default demo organisation: Pet Industry Federation (PIF).
- Default user: Alex Rivera, System Administrator.
- Money:
£prefix, 2 decimal places in tables. - Dates:
DD MMM YY(11 May 27). - Member IDs: 8-digit numeric.
- Invoice IDs:
INV-NNNNN. - Stripe IDs:
pi_…,cus_…,ch_…(15-char truncated,…suffix).
9. Definitely don't
- Don't add a second blue.
- Don't use emoji as iconography.
- Don't put action buttons in the top nav. They live in the content panel, inline with the H1.
- Don't put breadcrumbs in the top nav. They live in the content panel, above the page header.
- Don't render avatars in the top nav. Use the name + role pattern.
- Don't introduce raw
gray-*Tailwind classes — useink-*,surface-*,border-*tokens. - Don't ship a list view without an empty and loading state.
- Don't gradient-fill an icon, button, or surface.