Design System
Drop Frontend — Design System Documentation
ExtractedProject: from{{PROJECT_NAME}}
actualVersion: source{{VERSION}}
code:Date: globals.css,{{DATE}}
layout.tsx,Author: brand-guide.md,{{AUTHOR}}
colors.css,Status: design-system-reference.md.Draft | In Review | Approved
Reviewers: {{REVIEWERS}}
Document History
| Version |
Date |
Author |
Changes |
| 0.1 |
{{DATE}} |
{{AUTHOR}} |
Initial draft |
Colors1. Design Principles
| Principle |
Description |
| Clarity first |
Every UI element must communicate its purpose without explanation |
| Consistent over clever |
Prefer familiar patterns over novel interactions |
| Accessible by default |
WCAG AA compliance is a baseline, not a feature |
| Density-aware |
Support comfortable and compact density modes |
| TODO: Add principle |
{{DESCRIPTION}} |
2. Color System
2.1 Primitive Palette (Raw Values)
/* Brand Colorsprimitives — do NOT use directly in components */
--color-brand-50: {{#F0F9FF}};
--color-brand-100: {{#E0F2FE}};
--color-brand-500: {{#0EA5E9}};
--color-brand-600: {{#0284C7}};
--color-brand-900: {{#0C4A6E}};
--color-neutral-0: #FFFFFF;
--color-neutral-50: {{#F8FAFC}};
--color-neutral-100: {{#F1F5F9}};
--color-neutral-400: {{#94A3B8}};
--color-neutral-700: {{#334155}};
--color-neutral-900: {{#0F172A}};
--color-neutral-1000: #000000;
2.2 Semantic Tokens (fromLight Mode)
/* Background */
--color-bg-primary: var(--color-neutral-0);
--color-bg-secondary: var(--color-neutral-50);
--color-bg-elevated: var(--color-neutral-0);
/* Text */
--color-text-primary: var(--color-neutral-900);
--color-text-secondary: var(--color-neutral-700);
--color-text-disabled: var(--color-neutral-400);
--color-text-inverse: var(--color-neutral-0);
/* Interactive */
--color-interactive-primary: var(--color-brand-500);
--color-interactive-primary-hover: var(--color-brand-600);
--color-interactive-primary-active: var(--color-brand-700);
/* Semantic */
--color-success: {{#10B981}};
--color-warning: {{#F59E0B}};
--color-error: {{#EF4444}};
--color-info: {{#3B82F6}};
2.3 Semantic Tokens (Dark Mode)
[data-theme="dark"] {
--color-bg-primary: var(--color-neutral-900);
--color-bg-secondary: var(--color-neutral-800);
--color-text-primary: var(--color-neutral-50);
/* TODO: Complete dark mode token mapping */
}
2.4 Contrast Ratios (WCAG)
| Pair |
Ratio |
WCAG AA (4.5:1) |
WCAG AAA (7:1) |
| Text primary on bg primary |
{{X:1}} |
{{Pass/Fail}} |
{{Pass/Fail}} |
| Text secondary on bg primary |
{{X:1}} |
{{Pass/Fail}} |
{{Pass/Fail}} |
| Interactive on bg primary |
{{X:1}} |
{{Pass/Fail}} |
{{Pass/Fail}} |
| White on brand-500 |
{{X:1}} |
{{Pass/Fail}} |
{{Pass/Fail}} |
TODO: Run contrast checks with globals.css{{axe | Colour Contrast Analyser}} and brand/colors.css)fill table.
3. Typography
3.1 Font Families
| Token |
HexValue |
Usage |
--color-drop-primaryfont-heading |
#0B6E35{{Inter, sans-serif}} |
ForestH1–H4, Green — buttons, links, active states, logo |
--color-drop-secondary |
#D4A017 |
Gold — logo arrow accent, premium elements |
--color-drop-accent |
#10B981 |
Emerald — success states, positive amounts |
--color-drop-dark |
#1A1A1A |
Near-black — headings, primarydisplay text |
--color-drop-lightfont-body |
#FAFCF8{{Inter, sans-serif}} |
Off-whiteBody —copy, pagelabels, backgroundsUI |
--color-drop-errorfont-mono |
#EF4444{{JetBrains Mono, monospace}} |
RedCode, —technical error states, negative amountsdata |
Neutral3.2 PaletteType (used directly in Tailwind classes)Scale
HexToken |
Size |
Weight |
Line Height |
Letter Spacing |
Usage |
#EEEEEE--text-display |
Login48px |
page700 |
background1.1 |
-0.02em |
Hero headings |
#F9FAFB--text-h1 |
Input36px |
field700 |
backgrounds1.2 |
-0.01em |
Page titles |
#E5E7EB--text-h2 |
Input28px |
borders,600 |
dividers1.25 |
-0.01em |
Section headings |
#D1D5DB--text-h3 |
Horizontal22px |
rule600 |
dividers1.3 |
0 |
Subsections |
#9CA3AF--text-h4 |
Muted18px |
text,600 |
inactive1.4 |
nav0 |
Card headings |
#6B7280--text-body-lg |
Secondary18px |
text,400 |
placeholders1.6 |
0 |
Lead paragraphs |
#374151--text-body |
Dark16px |
text400 |
on1.6 |
light0 |
backgroundsDefault body copy |
--text-body-sm |
14px |
400 |
1.5 |
0 |
Secondary text, captions |
--text-label |
14px |
500 |
1.4 |
0.01em |
Form labels, UI labels |
--text-caption |
12px |
400 |
1.4 |
0.02em |
Timestamps, meta |
--text-code |
14px |
400 |
1.6 |
0 |
Inline code |
shadcn/ui
TODO: ThemeVerify Tokensscale (fromagainst globals.cssFigma :root)—
--background:update #FAFCF8;values --foreground:if #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;
--ring: #0B6E35;
--radius: 0.75rem;
Custom Utility Classes
.bg-gradient-brand {
background: linear-gradient(135deg, #0B6E35 0%, #D4A017 100%);
}
mismatched.
Typography4. Spacing & Layout
Fonts4.1 Spacing Scale (from4px layout.tsx:7-18)Base Unit)
FontToken |
Variable |
WeightValue |
Usage |
Fraunces |
--font-frauncesspace-0 |
400-900 (variable)0px |
Display/headings, logo wordmark, brand text |
DM Sans |
--font-dm-sansspace-1 |
400-700 (variable)4px |
BodyMicro text,gaps, UIicon labels, inputs (default body font)padding |
Geist--space-2 |
Mono8px |
Tight inline spacing |
--font-geist-monospace-3 |
400-700 (variable)12px |
Code,Compact monospaceform elements |
--space-4 |
16px |
Default content spacing |
--space-5 |
20px |
Card padding (compact) |
--space-6 |
24px |
Card padding, section padding |
--space-8 |
32px |
Large section gaps |
--space-10 |
40px |
Feature section padding |
--space-12 |
48px |
Section separation |
--space-16 |
64px |
Page-level padding |
--space-20 |
80px |
Hero sections |
Font4.2 UsageGrid PatternsSystem
ContextProperty |
Tailwind Class |
ExampleValue |
LogoColumn wordmarkcount |
font-[family-name:var(--font-fraunces)] text-3xl font-bold |
"drop" on login12 |
PageColumn headinggutter |
text-xl24px font-semibold(mobile: text-[#1A1A1A] |
Dashboard greeting16px) |
SectionContainer headingmax-width |
text-lg font-semibold text-[#1A1A1A] |
"Siste transaksjoner"1280px |
BodyContainer textside padding |
Default24px (DMmobile: Sans16px) |
inherited
from
body)
4.3 Responsive Breakpoints
| Name |
Min Width |
Target Devices |
xs |
General0px |
contentSmall phones |
Label |
text-sm font-medium text-[#1A1A1A] |
Form480px |
labelsLarge phones |
Muted text |
text-sm text-[#6B7280]md |
Descriptions,768px |
timestampsTablets |
Small text |
text-xs text-[#9CA3AF]lg |
Footers,1024px |
hintsSmall laptops |
Amount (large) |
text-2xl font-bold text-[#1A1A1A]xl |
Balance1280px |
displayDesktops |
Amount (list)2xl |
text-sm font-semibold + color1536px |
TransactionLarge amountsdisplays |
Spacing5. &Component Library
5.1 Primitive Components (Atoms)
| Component |
Status |
Variants |
Storybook |
| Button |
`{{Done |
WIP |
Planned}}` |
| Input |
`{{Done |
WIP |
Planned}}` |
| Select |
`{{Done |
WIP |
Planned}}` |
| Checkbox |
`{{Done |
WIP |
Planned}}` |
| Radio |
`{{Done |
WIP |
Planned}}` |
| Toggle/Switch |
`{{Done |
WIP |
Planned}}` |
| Textarea |
`{{Done |
WIP |
Planned}}` |
| Badge |
`{{Done |
WIP |
Planned}}` |
| Avatar |
`{{Done |
WIP |
Planned}}` |
| Tooltip |
`{{Done |
WIP |
Planned}}` |
| Spinner |
`{{Done |
WIP |
Planned}}` |
| Divider |
`{{Done |
WIP |
Planned}}` |
5.2 Composite Components (Molecules)
| Component |
Status |
Storybook |
| Card |
{{Status}} |
{{URL}} |
| Modal / Dialog |
{{Status}} |
{{URL}} |
| Dropdown Menu |
{{Status}} |
{{URL}} |
| Table |
{{Status}} |
{{URL}} |
| Pagination |
{{Status}} |
{{URL}} |
| Toast / Notification |
{{Status}} |
{{URL}} |
| Form Field (label + input + error) |
{{Status}} |
{{URL}} |
| Search Bar |
{{Status}} |
{{URL}} |
| Breadcrumb |
{{Status}} |
{{URL}} |
| Tabs |
{{Status}} |
{{URL}} |
| Accordion |
{{Status}} |
{{URL}} |
| Date Picker |
{{Status}} |
{{URL}} |
5.3 Layout Components
| Component |
Description |
Container |
Max-width wrapper with responsive padding |
Stack |
Vertical flex stack with configurable gap |
Inline |
Horizontal flex row with configurable gap/alignment |
Grid |
CSS grid layout wrapper |
PageLayout |
Full-page layout with sidebar/header/main/footer slots |
Section |
Content section with standard vertical rhythm |
6. Iconography Guidelines
Page
Structure
| Item |
Standard |
| Library |
`{{Lucide React |
| Delivery |
Inline SVG via component (no sprite, no icon font) |
| Sizes |
16px (sm), 20px (md, default), 24px (lg), 32px (xl) |
| Stroke width |
1.5px at 24px, scaled proportionally |
| Color |
Inherits min-h-screen bg-[#FAFCF8]currentColor — Standardnever pagehardcoded |
background
px-6
pb-24Interactive —icons |
PageMust paddinghave (bottomvisible forfocus BottomNavring clearance)+ pt-644×44px —touch Toptarget |
padding
(below
safeCustom area)icons |
max-w-smSVG mx-autooptimized —via ContentSVGO, maxplaced widthin onsrc/components/icons/ |
login/onboarding
Card Pattern
rounded-2xl bg-white p-6 shadow-sm — Standard card
rounded-xl bg-white p-4 shadow-sm — Compact card
Bottom Nav Clearance
pb-24 — All pages with BottomNav add bottom padding
TheAccessibility BottomNavrule: itselfIcons isconveying meaning must have fixedaria-label. bottom-0Decorative left-0 right-0 withicons: h-16 border-t bg-whitearia-hidden="true".
Component7. PatternsMotion & Animation Standards
Primary7.1 Duration Tokens
| Token |
Value |
Usage |
--duration-instant |
50ms |
Micro-feedback (checkbox check) |
--duration-fast |
100ms |
Button states, hover |
--duration-normal |
200ms |
Modals, dropdowns |
--duration-slow |
300ms |
Page transitions, large panels |
--duration-slower |
500ms |
Onboarding, loading states |
7.2 Easing Tokens
| Token |
Value |
Usage |
--ease-default |
cubic-bezier(0.4, 0, 0.2, 1) |
General UI |
--ease-enter |
cubic-bezier(0, 0, 0.2, 1) |
Elements entering |
--ease-exit |
cubic-bezier(0.4, 0, 1, 1) |
Elements leaving |
--ease-spring |
cubic-bezier(0.34, 1.56, 0.64, 1) |
Playful, emphasis |
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
9.1 CSS Custom Properties (Source of Truth)
/* tokens/colors.css */
:root {
--color-brand-500: #0EA5E9;
/* ... */
}
Secondary / Outline Button
<button className="flex h-12 flex-1 items-center justify-center gap-9.2 rounded-xlTailwind borderConfig border-[#E5E7EB] bg-white text-sm font-medium text-[#1A1A1A] hover:bg-[#F9FAFB]">
Text Input
<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]" />
<div className="relative">
<Icon className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#6B7280]" />
<input className="... pl-10" />
</div>
Error Message
<p className="rounded-md bg-[#EF4444]/10 p-2 text-sm text-[#EF4444]">{error}</p>
Link
<Link className="text-xs font-medium text-[#0B6E35] hover:underline">
Badge (Primary)
<span className="rounded-full bg-[#0B6E35]/10 px-2 py-0.5 text-xs font-medium text-[#0B6E35]">
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 AmountExtension
// Positivetailwind.config.ts
(received)export <spandefault className="text-sm{
font-semiboldtheme: text-[#10B981]">+{amount}</span>
extend: {
colors: {
brand: {
500: 'var(--color-brand-500)',
// Negative...
(sent)}
<span}
className="text-sm}
font-semibold}
text-[#EF4444]">-{amount}</span>}
Tab9.3 FilterJavaScript/TypeScript (using shadcn Tabs)Constants
<Tabs// defaultValue="all">tokens/colors.ts <TabsList— className="for use in charting libraries, canvas, etc.
export const colors = {
brand500: '#0EA5E9',
// ...">
<TabsTrigger} value="all">Alle</TabsTrigger>as <TabsTrigger value="remittance">Overforinger</TabsTrigger>
</TabsList>
</Tabs>const;
Token Iconography
update System:process:
LucideFigma React
Size:→ h-4Style w-4Dictionary (inline),export h-5→ w-5CSS/JS/Tailwind (nav/buttons),files h-6→ w-6PR (feature icons)
Color: currentColor (inherits from parent text color)
Custom: Drop Icons (drop-icons.tsx)
Size: 24px default, configurable via size prop
Style: Outlined, 2px stroke, round caps, currentColor
9 domain-specific icons for financial features
Social Login Icons
BankID: Inline SVG, green rounded rect with "ID" text
Vipps: Inline SVG, orange circle with "V" text
review.
Responsive10. DesignComponent Documentation Standard
grid-cols-1/**
md:grid-cols-3* Button component for featuresprimary user actions.
*
* @example
* <Button variant="primary" onClick={handleSubmit}>Save Changes</Button>
*/
Props table: Every prop must have: type, default, required flag, description.
AnimationApproval