Skip to main content

Design System


title: Design System owner: vizu last-updated: 2026-05-16 supersedes: docs/frontend/DESIGN-SYSTEM.md (2026-02-25 — teal palette, retired) status: canonical

Bilko Design System

Source:

RETIRED:Extracted Thefrom previousapps/web/tailwind.config.ts DESIGN-SYSTEM.md documented a teal (#00E5A0) palette. That document is wrong and archived. The canonical+ brand isidentity plumspec (#8B6BBF).Design SeeLanguage: docs/branding/branding/bilko-brand-guidelines.mdModern forBalkan theaccounting authoritativeSaaS brand source.clean, professional, accessible


1. Color Palette — Canonical Plum

Source

Primary ofBrand truth: bilko-brand-guidelines.md (2026-05-16). Tokens below are the Tailwind 4 @theme mapping.

CSS Custom Properties (@theme block in globals.css)Colors

@themePrimary:        {#00E5A0  /*(Vibrant teal-green — primary CTA, links, active states)
Primary plumDark:   scale#00B380  */(Darker --color-primary:variant #8b6bbf;for /*hover Plumstates)
Primary Light:  #33EBB3  (Lighter variant for backgrounds)

Status Colors

Success:        #22C55E  (Green CTAs, activesuccess states, linkspaid */invoices, --color-primary-hover:positive #5b3e8a;metrics)
/*Warning:        Deep#F59E0B  Plum(Amberhoverwarnings, onpending primaryitems, elementsaging */invoices)
--color-primary-light:Error:          #c4a8e0;#EF4444  /* Light Plum(Redsubtleerrors, backgrounds,overdue chipsinvoices, */negative --color-primary-subtle:actions)
#ede5f8;Info:           /*#3B82F6  Plum tint(Bluefocusinformational rings,messages, hoverneutral surfacesdata)
*/
/*

Text AccentColors

*/
Text --color-accent:Primary:   #f2c87a;#111113  /* Gold(Near-blackhighlights,body accenttext, dots,headings)
iconsText */Secondary: --color-accent-hover:#6B7280  #e8ae4a; /* Gold dark(Gray-600hoversecondary ontext, accentlabels)
elementsText */Muted:     /*#888888  Surface(Gray-500 /— muted text, placeholders)

Background Colors

Background Light:   #FAFAFA  (Off-white — main content area background)
Background */Surface: --color-surface:#FFFFFF  #f9f7fc; /* Light Lavender — preferred background */
  --color-surface-dark: #14111f; /* Dark mode background */
  --color-bg: #ffffff; /* Pure white(White — card backgrounds, modalsmodals)
*/
/*

Border Color

Border:         #E5E7EB  (Gray-200 — borders, dividers)

Chart Colors

Chart Revenue:  #22C55E  (Green — revenue bars/lines)
Chart Expense:  #EF4444  (Red — expense bars/lines)
Chart Profit:   #3B82F6  (Blue — profit bars/lines)
Chart Neutral:  #6B7280  (Gray — neutral data points)

Sidebar Colors (Dark Theme)

Sidebar BG:         #111113  (Near-black — sidebar background)
Sidebar Text:       #FAFAFA  (Off-white — sidebar text)
Sidebar Text */Muted: --color-text-primary:#888888  #231c33;(Gray /* Darkinactive plum-tonedmenu items)
Sidebar Active:     #00E5A0  (Primary green — active menu item)
Sidebar Hover:      #1F1F23  (Slightly lighter black — hover state)

Usage:

  • Sidebar = dark (#111113) with light text
  • Content area = light (#FAFAFA) with dark text
  • Cards = white (#FFFFFF) surface on light backgrounds */ --color-text-secondary: #6b7280; /* Mid gray — labels, secondary copy */ --color-text-light: #e4def0; /* On dark backgrounds */ --color-text-muted: #9ca3af; /* Muted, disabled states */ /* Semantic */ --color-success: #22c55e; --color-warning: #f59e0b; --color-error: #ef4444; --color-info: #3b82f6; /* Border */ --color-border: #e5e1ef; /* Plum-tinted border */ --color-border-strong: #c4a8e0; /* Stronger border for focused elements */ /* Sidebar */ --color-sidebar-bg: #14111f; /* Dark plum sidebar */ --color-sidebar-text: #e4def0; --color-sidebar-active: #8b6bbf; /* Chart colors */ --color-chart-1: #8b6bbf; --color-chart-2: #f2c87a; --color-chart-3: #5b3e8a; --color-chart-4: #c4a8e0; --color-chart-5: #ede5f8; }

    Color Rules (from brand guidelines)

    • Never use --color-primary (#8B6BBF) as body text on white — WCAG contrast fails at small sizes (3.6:1).
    • Gold Accent (#F2C87A) is for highlights only — never as a primary CTA color.
    • Surface (#F9F7FC) is preferred over pure white for page backgrounds.
    • Focus rings must use --color-primary-hover (#5B3E8A) at minimum 3:1 contrast against adjacent color (WCAG 2.4.11).

    Retired Colors

    The following colors appeared in the old DESIGN-SYSTEM.md and are explicitly retired. Do not use:

    Retired hexLabel in old docReason
    #00E5A0Primary teal-greenWrong brand
    #00B380Primary dark tealWrong brand
    #33EBB3Primary light tealWrong brand
    #111113Sidebar darkReplaced by #14111F

    2. Typography

    Fonts: National Park (headings) · Work Sans (body, UI) · DM Mono (numbers, data, code)

    Type Scale

    @theme {
      --font-heading: 'National Park', system-ui, sans-serif;
      --font-body: 'Work Sans', system-ui, sans-serif;
      --font-mono: 'DM Mono', 'Courier New', monospace;
    
      --text-xs: 0.75rem; /* 12px — fine print */
      --text-sm: 0.875rem; /* 14px — labels, secondary */
      --text-base: 1rem; /* 16px — body copy */
      --text-lg: 1.125rem; /* 18px — large body, lead */
      --text-xl: 1.25rem; /* 20px — small headings */
      --text-2xl: 1.5rem; /* 24px — H3 */
      --text-3xl: 2rem; /* 32px — H2 */
      --text-4xl: 3rem; /* 48px — H1 landing */
    }
    

    Usage Rules

    • Headings: National Park Bold. Use for h1h3 and the logo wordmark.
    • Body: Work Sans Regular/SemiBold. All UI copy, labels, table cells.
    • Mono: DM Mono Regular. Invoice numbers, amounts, account codes, code blocks.
    • Minimum body size: 16px (1rem). Never below 12px (WCAG 1.4.4).background

    3.Typography

    Font Family

    Sans Serif: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif
    

    Source: Google Fonts Inter (variable font) Fallback: System UI fonts for performance

    Font Sizes

    xs:   12px  (Small badges, captions)
    sm:   14px  (Table cells, secondary text, form labels)
    base: 16px  (Body text, default)
    lg:   18px  (Subheadings, emphasized text)
    xl:   20px  (Section titles)
    2xl:  24px  (Card titles, small headings)
    3xl:  32px  (Page headings)
    4xl:  40px  (Hero text, large numbers)
    

    Font Weights

    normal:    400  (Body text)
    medium:    500  (Emphasis, table headers)
    semibold:  600  (Subheadings, button text)
    bold:      700  (Headings, metric numbers)
    

    Type Scale Usage

    • Headings:
      • Page title: text-3xl font-bold (32px, 700)
      • Section title: text-2xl font-bold (24px, 700)
      • Card title: text-base font-semibold (16px, 600)
    • Body:
      • Default: text-base font-normal (16px, 400)
      • Table cells: text-sm font-medium (14px, 500)
      • Muted text: text-sm text-text-muted (14px, #888888)
    • Numbers:
      • Metrics: text-3xl font-bold (32px, 700)
      • Totals: text-2xl font-bold (24px, 700)
      • Amounts: text-base font-medium (16px, 500)

    Spacing System (8px Grid)

    xs:  4px   (Tight spacing, icon gaps)
    sm:  8px   (Input padding, small gaps)
    md:  16px  (Default spacing, card padding)
    lg:  24px  (Section spacing)
    xl:  32px  (Large section spacing)
    2xl: 48px  (Major section breaks)
    3xl: 64px  (Hero spacing)
    

    BaseUsage:

    unit:
    • Card padding: p-6 (24px)
    • Form field gap: space-y-4 (16px)
    • Section spacing: space-y-6 (24px)
    • Grid gap: gap-6 (24px)

    8pxConsistency:. All spacing valuesuses are8px multiplesincrements of(4px, 8px.8px, Never16px, use24px, arbitrary32px, pixel48px, values.64px)

    @theme {
      --spacing-xs: 4px; /* 0.5 × base */
      --spacing-sm: 8px; /* 1 × base */
      --spacing-md: 16px; /* 2 × base */
      --spacing-lg: 24px; /* 3 × base */
      --spacing-xl: 32px; /* 4 × base */
      --spacing-2xl: 48px; /* 6 × base */
      --spacing-3xl: 64px; /* 8 × base */
    }
    

    4. Border Radius

    @theme {
      --radius-sm:   6px;6px   --radius-(Small elements, badges)
    md:   8px;8px   --radius-(Buttons, inputs, cards)
    lg:   12px;12px  --radius-xl:(Modals, 16px;large --radius-cards)
    full: 9999px;9999px /*(Circular pills,elements, badges */
    }pills)
    

    Usage:

    • Cards: rounded-md (8px)
    • Buttons: rounded-md (8px)
    • Inputs: rounded-md (8px)
    • Badges: rounded-sm (6px)
    • User avatar: rounded-full (circular)

    5. Shadows

    @themeCard {
      --shadow-card: 0 1px 3px rgba(35, 28, 51, 0.08), 0 1px 2px rgba(35, 28, 51, 0.06);
      --shadow-modal: 0 4px 24px rgba(35, 28, 51, 0.16);
      --shadow-dropdown:Shadow:     0 2px 8px rgba(35,0, 28,0, 51,0, 0.08)   (Subtle card elevation)
    Modal Shadow:    0 8px 24px rgba(0, 0, 0, 0.12);  }(Dialog/modal elevation)
    Dropdown Shadow: 0 4px 16px rgba(0, 0, 0, 0.10)  (Dropdown menu elevation)
    

    Usage:

    • Cards: shadow-card
    • Modals/dialogs: shadow-modal
    • Dropdown menus: shadow-dropdown

    Philosophy: Subtle shadows for depth, avoid heavy shadows (material design style)


    6. Dark Mode StrategyBreakpoints

    Bilko uses CSS prefers-color-scheme for automatic dark mode, togglable via a data-theme attribute on <html>.

    @mediasm:  640px   (prefers-color-scheme:Small dark)tablets, {large :rootphones)
    {md:  --color-bg:768px   #14111f;(Tablets)
    --color-surface:lg:  #1e1929;1024px  --color-text-primary:(Small #e4def0;desktops, --color-border:large #3a2f55;tablets)
    }xl:  }1280px  [data-theme='dark'] {
      --color-bg: #14111f;
      --color-surface: #1e1929;
      --color-text-primary: #e4def0;
      --color-border: #3a2f55;
    }(Desktops)
    

    Mobile-First Strategy:

    • Base styles = mobile (< 640px)
    • sm: = small tablet (640px+)
    • md: = tablet/desktop toggle (768px+)
    • lg: = desktop layout (1024px+)
    • xl: = wide desktop (1280px+)

    OPENResponsive QUESTIONPatterns:

    OQ-3:
      Dark mode is not implemented in
    • Grid: apps/web/grid-cols-1 md:grid-cols-2 lg:grid-cols-3
    • Sidebar: hidden md:block as(hide ofon 2026-05-16.mobile)
    • The
    • Filters: tokenflex-col systemsm:flex-row above(stack ison themobile, plannedrow architecture.on Timelinetablet+)
    • for implementation is not assigned.


7.Component shadcn/uiTokens

Variant

Button

API
    via
  • Height: cva40px (default), 32px (sm), 48px (lg), 40px (icon)
  • Padding: 16px horizontal (default), 12px (sm), 20px (lg)
  • Border Radius: 8px (md)
  • Font: 14px medium (default), 12px (sm), 16px (lg)
  • Variants:
    • Default: Primary green background, white text
    • Outline: Border only, transparent background
    • Ghost: No border, no background, hover shows background
    • Destructive: Error red background, white text

Input

  • Height: 40px
  • Padding: 12px horizontal
  • Border: 1px solid #E5E7EB (border color)
  • Border Radius: 8px (md)
  • Font: 14px normal
  • Focus: Primary color ring (2px)

Card

  • Background: #FFFFFF (surface)
  • Border: 1px solid #E5E7EB
  • Border Radius: 8px (md)
  • Shadow: 0 2px 8px rgba(0, 0, 0, 0.08)
  • Padding: 24px (default content padding)

Badge

  • Padding: 4px 8px
  • Border Radius: 6px (sm)
  • Font: 12px medium
  • Variants:
    • Default: Gray background
    • Success: Green background
    • Warning: Amber background
    • Destructive: Red background
    • Secondary: Light gray

Table

  • Row Height: 48px (default)
  • Cell Padding: 12px horizontal, 16px vertical
  • Border: 1px solid #E5E7EB (between rows)
  • Hover: Light gray background (#FAFAFA)
  • Header: Medium font weight, secondary text color

Icon System

AllLibrary: shadcn/uiLucide componentsReact use(v0.469.0) class-variance-authoritySize: Consistent 16px (cvaw-4 h-4) foror variant20px composition.(w-5 Theh-5) cn() utility merges Tailwind classes with conflict resolution via tailwind-merge.Usage:

Button
  • Buttons: verified16px cvaicon definition+ 8px gap from text
  • Menu items: 20px icon + 12px gap from text
  • Standalone: 24px or larger

Common Icons:

  • Plus (fromadd components/ui/button.tsx)actions)
  • Search (search inputs)
  • Menu (mobile sidebar toggle)
  • User (user menu)
  • Bell (notifications)
  • ChevronDown/Right (expandable sections)
  • Check (success, reconciliation)
  • X (close, delete)
  • Download (export actions)
  • Send (send email)

Chart Design Tokens

Chart Colors (Recharts)

importRevenue:  {#22C55E  cva,(Green typebars)
VariantPropsExpense:  }#EF4444  from(Red 'class-variance-authority'bars)
importProfit:   {#3B82F6  cn(Blue }bars)
fromNeutral:  '@/lib/utils'#6B7280  const buttonVariants = cva(
  // Base styles(Grayalwayswhen appliedno 'inline-flexsemantic items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
        destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
        outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
        ghost: 'hover:bg-accent hover:text-accent-foreground',
        link: 'text-primary underline-offset-4 hover:underline',
      },
      size: {
        default: 'h-10 px-4 py-2',
        sm: 'h-11 rounded-md px-3',
        lg: 'h-11 rounded-md px-8',
        icon: 'h-11 w-11',
      },
    },
    defaultVariants: { variant: 'default', size: 'default' },
  },
)meaning)

AddingChart a Custom VariantTypography

//
    Extend
  • Axis buttonVariantsLabels: 12px normal
  • Tooltip: 14px medium
  • Legend: 12px normal

Chart Layout

  • Responsive Container: 100% width, fixed height (250px default)
  • Cartesian Grid: Dashed, #E5E7EB stroke
  • Tooltip Background: White with border
  • Border Radius: 8px (md)

Accessibility

Color Contrast

  • All text colors meet WCAG AA standards
  • Primary text (#111113) on white = 16.17:1 (AAA)
  • Secondary text (#6B7280) on white = 4.69:1 (AA)
  • Primary green (#00E5A0) on white = 2.92:1 (fails — used for aaccents "plum-outline"only, not body text)

Focus Indicators

  • All interactive elements have visible focus ring
  • Focus ring color: Primary green (#00E5A0)
  • Focus ring width: 2px

Semantic HTML

  • Proper heading hierarchy (h1 → h2 → h3)
  • Form labels properly associated with inputs
  • ARIA labels on icon-only buttons
  • Table headers properly scoped

Design Principles

  1. Clarity over Decoration — Data-first, minimal ornamentation
  2. Consistent Spacing — 8px grid, predictable rhythm
  3. Accessible by Default — WCAG AA minimum, Radix UI primitives
  4. Mobile-First — Responsive from 375px+ (iPhone SE)
  5. Dark Sidebar + Light Content — Clear visual separation
  6. Primary Color as Accent — Green (#00E5A0) for actions, not backgrounds
  7. Subtle Shadows — Elevation without heaviness
  8. Data-Dense UI — Tables, charts, metrics — optimized for information density

Brand Identity Alignment

From ~/system/specs/bilko-brand-identity.md:

  • Primary Color: #00E5A0 (implemented)
  • Typography: Inter (implemented)
  • Tone: Modern, professional, Balkan-focused (implemented)
  • Dark Sidebar: #111113 (implemented)
  • Logo Placement: Top left sidebar (implemented)

Future Tokens (Phase 2)

When implementing API integration:

  • Loading States: Skeleton component colors
  • Error States: Error message backgrounds (#FEF2F2, light red)
  • Success States: Success message backgrounds (#F0FDF4, light green)
  • Toast Notifications: Background, text, border colors
  • Dark Mode: Full dark theme variant const(optional)
  • buttonVariants
= cva(/* base */, { variants: { variant: { // ... existing variants 'plum-outline': 'border-2 border-primary text-primary hover:bg-primary-subtle', }, }, })

cn() Usage Rule

Always compose class lists with cn() — never with template literals or string concatenation:

// Correct
<div className={cn('base-class', condition && 'conditional-class', className)} />

// Wrong
<div className={`base-class ${condition ? 'conditional-class' : ''} ${className}`} />