Design System Documentation

Design System Documentation

Project: Drop — Fintech Payment App Version: 0.1.0 Date: 2026-02-23 Author: John (AI Director, ALAI) Status: In Review Reviewers: Alem Bašić (CEO)

Document History

Version Date Author Changes
0.1 2026-02-23 John Initial draft from source code + brand guide analysis

1. Design Principles

Principle Description
Clarity first Every UI element must communicate its purpose without explanation. Amounts are large and legible. Actions are labeled.
Scandinavian minimal Generous whitespace, no visual noise. Forest green + white — nothing extra.
Trust through transparency Fees visible before every transaction. No hidden costs. PSD2 disclosures shown explicitly.
Mobile-first The app is a mobile PWA. max-w-sm containers, pb-24 for BottomNav clearance, touch targets ≥ 44×44px.
Accessible by default WCAG AA compliance is a baseline requirement, not an optional enhancement.
Light mode only (Phase 1) Background is always off-white (#FAFCF8) or white. Dark mode is Phase 2.

2. Color System

2.1 Primitive Palette (Raw Values)

/* Brand primitives — defined in brand/colors.css and globals.css */

/* Green scale */
--color-green-primary:   #0B6E35;   /* Forest Green — primary brand */
--color-green-dark:      #095C2C;   /* Hover/pressed state */
--color-green-light:     #E8F5E9;   /* Light green tint, badges */

/* Gold scale */
--color-gold-primary:    #D4A017;   /* Gold accent, logo arrow, premium elements */
--color-gold-light:      #FFF8E1;   /* Gold tint */

/* Neutral scale */
--color-neutral-0:       #FFFFFF;   /* White — cards, elevated surfaces */
--color-neutral-50:      #FAFCF8;   /* Off-white — page background */
--color-neutral-100:     #F9FAFB;   /* Input field backgrounds */
--color-neutral-200:     #F3F4F6;   /* Section backgrounds, shadcn secondary */
--color-neutral-300:     #E5E7EB;   /* Input borders, card borders, dividers */
--color-neutral-400:     #D1D5DB;   /* Horizontal rule dividers */
--color-neutral-500:     #9CA3AF;   /* Muted text, inactive nav items */
--color-neutral-600:     #6B7280;   /* Secondary text, placeholders */
--color-neutral-700:     #374151;   /* Dark text on light backgrounds */
--color-neutral-900:     #1A1A1A;   /* Near-black — headings, primary text */
--color-neutral-1000:    #000000;

/* Semantic */
--color-success:         #10B981;   /* Emerald — success, positive amounts */
--color-error:           #EF4444;   /* Red — error states, negative amounts */
--color-warning:         #D97706;   /* Warning — pending transactions */
--color-info:            #2563EB;   /* Info — PSD2 banners */

2.2 Semantic Tokens (Light Mode — from globals.css :root)

:root {
  /* shadcn/ui CSS variable tokens */
  --background:           #FAFCF8;
  --foreground:           #1A1A1A;
  --primary:              #0B6E35;
  --primary-foreground:   #FFFFFF;
  --secondary:            #F3F4F6;
  --secondary-foreground: #1A1A1A;
  --accent:               #F3F4F6;
  --accent-foreground:    #1A1A1A;
  --muted:                #F3F4F6;
  --muted-foreground:     #6B7280;
  --destructive:          #EF4444;
  --border:               #E5E7EB;
  --input:                #E5E7EB;
  --ring:                 #0B6E35;
  --radius:               0.75rem;

  /* Drop custom semantic tokens */
  --color-drop-primary:   #0B6E35;
  --color-drop-secondary: #D4A017;
  --color-drop-accent:    #10B981;
  --color-drop-dark:      #1A1A1A;
  --color-drop-light:     #FAFCF8;
  --color-drop-error:     #EF4444;
}

2.3 Semantic Tokens (Dark Mode)

/* Phase 2 — Dark mode TBD */
[data-theme="dark"] {
  /* TBD — requires design review */
  /* Drop is light-mode-first. Dark mode planned for Phase 2. */
}

2.4 Brand Gradient

.bg-gradient-brand {
  background: linear-gradient(135deg, #0B6E35 0%, #D4A017 100%);
}

2.5 Contrast Ratios (WCAG)

Pair Text Color Background Ratio WCAG AA (4.5:1) WCAG AAA (7:1)
Primary text on page bg #1A1A1A #FAFCF8 ~18.6:1 Pass Pass
Secondary text on page bg #6B7280 #FAFCF8 ~4.7:1 Pass Fail
Primary button text #FFFFFF #0B6E35 ~5.0:1 Pass Fail
Success text #10B981 #FFFFFF ~3.0:1 Fail (large text only) Fail
Error text #EF4444 #FFFFFF ~3.9:1 Fail (large text only) Fail
Muted text #9CA3AF #FFFFFF ~2.9:1 Fail Fail

Action items: Success (#10B981), error (#EF4444), and muted (#9CA3AF) colors fail WCAG AA for small text. These are used for semantic indicators (amount colors, hints) — always paired with a non-color indicator. Full audit in accessibility-audit.md.


3. Typography

3.1 Font Families

Token Value Usage
--font-fraunces Fraunces, Georgia, "Times New Roman", serif Display/headings, logo wordmark, brand text
--font-dm-sans "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif Body text, UI labels, inputs (default body font)
--font-geist-mono "Geist Mono", "JetBrains Mono", "Fira Code", "Courier New", monospace Code, monospace elements

Why these fonts:

3.2 Type Scale

Token Size Weight Line Height Letter Spacing Usage
Display 56px 700 (Fraunces) 1.1 -0.02em Hero headlines (landing page)
H1 40px 600 (Fraunces) 1.2 -0.01em Page titles
H2 32px 600 (Fraunces) 1.3 -0.005em Section headers
H3 24px 500 (Fraunces) 1.3 normal Sub-sections
H4 20px 600 (DM Sans) 1.4 normal Card titles
Body Large 18px 400 (DM Sans) 1.7 normal Lead paragraphs
Body 16px 400 (DM Sans) 1.6 normal Default text
Body Small 14px 400 (DM Sans) 1.5 normal Secondary content, captions
Label 14px 500 (DM Sans) 1.4 0.01em Form labels, UI labels
Caption 12px 500 (DM Sans) 1.4 0.02em Timestamps, meta, hints

3.3 In-App Tailwind Typography Patterns

Context Tailwind Class Example
Logo wordmark font-[family-name:var(--font-fraunces)] text-3xl font-bold "drop" on login
Page heading text-xl font-semibold text-[#1A1A1A] Dashboard greeting
Section heading text-lg font-semibold text-[#1A1A1A] "Siste transaksjoner"
Form label text-sm font-medium text-[#1A1A1A] "E-post"
Body text Inherited DM Sans General content
Muted text text-sm text-[#6B7280] Descriptions, timestamps
Small text text-xs text-[#9CA3AF] Footers, hints
Balance (large) text-2xl font-bold text-[#1A1A1A] Balance display
Amount (list) text-sm font-semibold + color Transaction amounts

4. Spacing & Layout

4.1 Spacing Scale (4px Base Unit — Tailwind defaults)

Tailwind Value Usage
p-1 4px Micro gaps
p-2 8px Tight inline spacing
p-3 12px Compact elements
p-4 16px Default content spacing
p-6 24px Card padding, section padding
p-8 32px Large section gaps
px-6 24px Page horizontal padding (standard)
pb-24 96px Bottom padding (BottomNav clearance)

4.2 Page Structure Patterns

/* Standard authenticated page */
min-h-screen bg-[#FAFCF8]      /* Off-white background */
px-6 pb-24 pt-6               /* Padding: horizontal 24px, bottom 96px (nav), top 24px */

/* Login / onboarding (centered) */
min-h-screen bg-[#EEEEEE]      /* Slightly darker bg for auth pages */
max-w-sm mx-auto               /* 384px max width, centered */

/* Card pattern (standard) */
rounded-2xl bg-white p-6 shadow-sm

/* Card pattern (compact) */
rounded-xl bg-white p-4 shadow-sm

4.3 Responsive Breakpoints (Tailwind defaults)

Name Min Width Usage
Default 0px Mobile — primary design target
sm 640px Larger phones
md 768px Tablets — landing page 2-column grid
lg 1024px Desktop — landing page 3-column grid

Note: The app is mobile-first. max-w-sm containers keep content readable on wider screens.

4.4 Bottom Nav

The BottomNav is fixed bottom-0 left-0 right-0 with h-16 border-t bg-white. All pages that include BottomNav must add pb-24 to their content container.


5. Component Library

5.1 Custom Drop Components

Component File Status Description
BottomNav components/bottom-nav.tsx Done Fixed 5-tab navigation
DropLogo components/drop-logo.tsx Done Forward-D SVG mark
DropWordmark components/drop-logo.tsx Done "drop" in Fraunces
DropLogoFull components/drop-logo.tsx Done Logo mark + wordmark
DropAppIcon components/drop-logo.tsx Done App icon — rounded green square
CookieConsent components/cookie-consent.tsx Done GDPR consent banner + modal
PrePaymentDisclosure components/pre-payment-disclosure.tsx Done PSD2 pre-payment modal
PWARegister components/pwa-register.tsx Done Service Worker registration
drop-icons components/drop-icons.tsx Done 9 custom fintech icons

5.2 shadcn/ui Primitive Components (Atoms)

Component File Radix Primitive Status
Alert ui/alert.tsx — (div-based) Done
Avatar ui/avatar.tsx @radix-ui/react-avatar Done
Badge ui/badge.tsx — (cva variants) Done
Button ui/button.tsx @radix-ui/react-slot Done
Card ui/card.tsx — (div-based) Done
Dialog ui/dialog.tsx @radix-ui/react-dialog Done
Input ui/input.tsx — (input element) Done
ScrollArea ui/scroll-area.tsx @radix-ui/react-scroll-area Done
Select ui/select.tsx @radix-ui/react-select Done
Separator ui/separator.tsx @radix-ui/react-separator Done
Sheet ui/sheet.tsx @radix-ui/react-dialog Done
Skeleton ui/skeleton.tsx — (pulse animation) Done
Sonner ui/sonner.tsx sonner toast library Done
Tabs ui/tabs.tsx @radix-ui/react-tabs Done

5.3 Layout Components

Component Description
Page wrapper min-h-screen bg-[#FAFCF8] px-6 pb-24 pt-6
Auth wrapper min-h-screen flex items-center justify-center bg-[#EEEEEE]
Card rounded-2xl bg-white p-6 shadow-sm
Scroll area ScrollArea from shadcn/ui for transaction lists

6. Iconography Guidelines

Item Standard
Primary library lucide-react
Delivery Inline SVG via React component
Sizes h-4 w-4 (inline/small), h-5 w-5 (nav/buttons), h-6 w-6 (feature icons)
Stroke width 1.5px at 24px (Lucide default)
Color currentColor — inherits from parent text color
Custom icons components/drop-icons.tsx — 9 domain-specific icons
Social auth Inline SVG — BankID (green rounded rect, "ID"), Vipps (orange circle, "V")

Custom Drop Icons:

Export Description
IconSendMoney Arrow going up-right from horizontal line
IconQrScan QR code frame with scan corners
IconVirtualCard Credit card outline
IconShield Shield with checkmark
IconFastTransfer Lightning bolt
IconCorridors Globe with meridians
IconWallet Wallet outline (unused — no wallet in pass-through model)
IconHistory Clock with arrow
IconTopUp Plus inside circle (unused — no top-up in pass-through model)

Accessibility rule: Icons conveying meaning must have aria-label. Decorative icons: aria-hidden="true".


7. Motion & Animation Standards

7.1 Duration Tokens

Usage Value
Button hover transition-colors (CSS default ~150ms)
Focus states transition-colors on border/ring
Loading states Text replacement ("Logger inn...", "Sender...") or Skeleton
Scanner frame animate-pulse on scan page corners
Complex animations None in Phase 1 — simplicity-first

7.2 Easing Tokens

Token Value Usage
--ease-default cubic-bezier(0.4, 0, 0.2, 1) General UI transitions
--ease-enter cubic-bezier(0, 0, 0.2, 1) Elements entering
--ease-exit cubic-bezier(0.4, 0, 1, 1) Elements leaving

7.3 Reduced Motion

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Rule: Every animated component MUST respect prefers-reduced-motion.


8. Accessibility Requirements Per Component

Requirement Buttons Inputs Modals BottomNav Transaction List
Keyboard accessible Required Required Required Required Required
Focus visible ring-[#0B6E35] focus:border-[#0B6E35] Focus trap Required Required
ARIA role button textbox dialog nav list/listitem
Screen reader label Visible text or aria-label <label> associated aria-labelledby aria-label="Navigasjon"
Error state Text message text-[#EF4444]
Touch target h-12 (48px) h-11 (44px) h-16 (64px) min-h-[44px]

9. Design Token Format

9.1 CSS Custom Properties (Source of Truth)

/* src/app/globals.css */
:root {
  --color-drop-primary:   #0B6E35;
  --color-drop-secondary: #D4A017;
  --color-drop-accent:    #10B981;
  --color-drop-dark:      #1A1A1A;
  --color-drop-light:     #FAFCF8;
  --color-drop-error:     #EF4444;
  /* shadcn/ui tokens... */
}

9.2 Tailwind Config Extension

// tailwind.config.ts
export default {
  theme: {
    extend: {
      colors: {
        drop: {
          primary:   '#0B6E35',
          secondary: '#D4A017',
          accent:    '#10B981',
          dark:      '#1A1A1A',
          light:     '#FAFCF8',
          error:     '#EF4444',
        }
      },
      fontFamily: {
        fraunces: ['var(--font-fraunces)', 'Georgia', 'serif'],
        sans:     ['var(--font-dm-sans)', 'system-ui', 'sans-serif'],
        mono:     ['var(--font-geist-mono)', 'monospace'],
      }
    }
  }
}

9.3 JavaScript/TypeScript Constants (for charting/canvas)

// For use in non-CSS contexts (future charts, canvas)
export const dropColors = {
  primary:   '#0B6E35',
  secondary: '#D4A017',
  accent:    '#10B981',
  dark:      '#1A1A1A',
  light:     '#FAFCF8',
  error:     '#EF4444',
} as const;

Token update process: Figma → update globals.css CSS variables → update Tailwind config → PR review.


10. Component Code Patterns

Primary Button

<Button className="h-12 w-full rounded-xl bg-[#0B6E35] text-sm font-semibold text-white shadow-sm hover:bg-[#095C2C]">
  Send penger
</Button>

Outline Button

<button className="flex h-12 flex-1 items-center justify-center gap-2 rounded-xl border border-[#E5E7EB] bg-white text-sm font-medium text-[#1A1A1A] hover:bg-[#F9FAFB]">
  Avbryt
</button>

Text Input with Left Icon

<div className="relative">
  <Mail className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#6B7280]" />
  <input
    className="h-11 w-full rounded-lg border border-[#E5E7EB] bg-[#F9FAFB] pl-10 pr-3 text-sm outline-none focus:border-[#0B6E35] focus:ring-1 focus:ring-[#0B6E35]"
    type="email"
    placeholder="din@epost.no"
  />
</div>

Error Message

<p className="rounded-md bg-[#EF4444]/10 p-2 text-sm text-[#EF4444]">
  {error}
</p>

Primary Badge

<span className="rounded-full bg-[#0B6E35]/10 px-2 py-0.5 text-xs font-medium text-[#0B6E35]">
  Primær konto
</span>

Avatar (Initials)

<div className="flex h-10 w-10 items-center justify-center rounded-full bg-[#0B6E35] text-sm font-bold text-white">
  {initials}
</div>

Transaction Amount (Positive / Negative)

// Positive (received)
<span className="text-sm font-semibold text-[#10B981]">+1 250,00 NOK</span>

// Negative (sent)
<span className="text-sm font-semibold text-[#EF4444]">-500,00 NOK</span>

Approval

Role Name Date Signature
Author John (AI Director) 2026-02-23
Lead Designer
Frontend Lead
Accessibility Reviewer

Revision #6
Created 2026-02-18 08:44:24 UTC by John
Updated 2026-05-31 20:01:59 UTC by John