World Bank Design System Deep-Dive
1. Brand Overview
The World Bank’s design system feels like international governance translated into pixels — serious, understated, and functional. No flashy gradients or gratuitous animations. The whole vibe is “trust me, we handle trillions, and we’re not here to entertain you.” This is aimed at policymakers, economists, NGOs, and journalists. The design reflects the gravitas of the institution: heavy use of blues, whites, and near-black tones, with a rigid typographic hierarchy in Open Sans, clean component edges, and restrained motion.
They lean hard on clarity over style. Buttons are clear, inputs are functional, and links differentiate clearly by color and underline. The color language is corporate blue plus neutrals to establish authority. Accent tones (orange for focus, lighter blues for hover) are used sparingly — almost as if they don’t entirely trust strong visual signals to carry meaning.
What’s interesting: they maintain a full 8px spacing system, but dip into oddball increments like 6px and 15px for certain tweaks. This tells me the design has evolved organically — some old breakpoints and layout patterns persisted, even as the system was formalized. The border radii are also very deliberate: 32px pills for buttons, 8px for cards, and full 50% for avatars/icons. It’s a mixture of sharp structural lines and soft, approachable curves.
Typography locks in a single family (Open Sans) across contexts, with occasional icon font (loopicon). No variable fonts, no crazy weights — just disciplined weights from 400 to 700. The hierarchy is readable but not overly dramatized. Font sizes cap at large-scale headings (48px) and shrink down through logical steps to 12px captions.
This is a design built for stability over innovation. Every element looks like it could survive a massive content migration without breaking. I like it because it’s no-nonsense. But it’s unforgiving — misuse of the palette or spacing grid will stand out immediately.
2. Color System
2.1 Primary Colors
Main brand tone: Deep blue #004370 (rgb(0, 67, 112)). This is the “primary actions” color: buttons, header tops, and key sections. Psychology-wise: blue is trust, stability, and professionalism. Compared to the IMF’s slightly brighter blues, the World Bank's is darker, lending more weight. They complement it with white (#ffffff) for clarity and near-black (#181f25) for headers and text anchors.
Accent colors enter only for functional states: orange #da570e for focus, light blue #066db1 for hover/focus feedback.
2.2 Complete Palette
| Color Name | Hex | Role | Usage |
|---|---|---|---|
| Header Dark | #181f25 | Primary text/headers | Header wrapper, global header |
| White | #ffffff | Background, text | Sections, buttons, dropdowns |
| Primary Blue | #004370 | Action backgrounds | Top wrap header, buttons, landing page |
| Navy Transparent | #000d1a | Overlay, button containers | Button containers |
| Deep Navy | #012740 | Section background | Sections |
| Black | #000000 | Baseline black | Misc text |
| Accent Orange | #da570e | Focus/hover indication | Focus colors |
| Accent Light Blue | #066db1 | Hover/focus indication | Hover states |
| --text-on-primary-disabled | #cde7f9 | Disabled text on primary | Disabled states |
| --text-on-state-info-emphasis | #00538a | Emphasis info text | Info banners |
| --text-on-state-warning-default | #fef3d7 | Default text in warning states | Warning banners |
| --text-on-light-state-error | #c91c25 | Error text on light | Validation errors |
| --text-on-light-link-disabled | #bdccdb | Disabled link text | Disabled links |
| --overlay-color | rgba(255,255,255,0.5) | Overlay backgrounds | Overlay modals |
| --text-on-dark-state-error | #e64750 | Error text on dark | Dark error messages |
| --text-on-dark-link-primary-enabled | #ffffffe5 | Links on dark backgrounds | Dark nav links |
| --text-on-dark-state-suggest | #c17cfe | Suggestion text on dark | Suggestions |
| --text-on-dark-state-warning | #fed881 | Warning text on dark | Dark warning banners |
| --dark-color | #cccccc | Neutral dark | Neutral UI elements |
| --text-on-primary-subdued | #e9f7fd | Subdued text on primary | Low emphasis UI text |
| --text-on-light-emphasis | #000d1af5 | Emphasis text on light | Light emphasis text |
| --text-on-light-default | #000d1ab2 | Default text on light | Light default text |
| --text-on-dark-state-info | #169af3 | Info text on dark | Info banners |
| --text-on-dark-subdued | #fff9 | Subdued text on dark | Low emphasis on dark |
| --text-on-light-state-suggest | #5c01ac | Suggestion text on light | Suggestion banners |
| --nav-menu-footer-color | #99b6c7 | Footer nav menu text | Footer navigation |
| --nav-menu-placeholder-color | #ffffff76 | Placeholder text in nav menus | Placeholders |
| --links-focus-color | #da570e | Focus highlight | Focus outlines |
| --text-on-light-link-hover | #0071bc | Hovered link on light | Hover states |
| --text-on-state-warning-emphasys | #fff7e6 | Warning emphasis text | Warning highlights |
| --brand-dark-blue | #002244 | Brand dark blue | Brand accents |
| --text-on-dark-default | #ffffffbf | Default text on dark | Default dark text |
| --text-on-dark-state-success | #56c606 | Success text on dark | Dark success states |
| --text-on-dark-state-disabled | #ffffff7a | Disabled text on dark | Disabled UI in dark |
| --text-on-state-error-emphasis | #fdf2f2 | Emphasis error text | Error highlights |
| --light-color | #eeeeee | Light neutral | Surfaces |
| --text-on-light-state-success | #388004 | Success text on light | Success banner |
| --text-on-light-subdued | #000d1a91 | Subdued light text | Low emphasis text |
| --text-on-primary-empasis | #ffffff | Emphasis text on primary | Primary CTA |
| --text-on-state-success-emphasis | #f6fef0 | Emphasis success text | Success highlights |
| --brand-blue | #009fda | Secondary brand blue | Highlights |
| --text-on-light-state-warning | #473201 | Warning text on light | Light warning banners |
| --text-on-state-success-default | #edfee2 | Default success text | Success banners |
| --text-on-light-state-disabled | #00294d6b | Disabled text on light | Disabled states |
2.3 Color Relationships
The dark blue #004370 contrasted on white background easily passes WCAG contrast ratios for large and normal text — the ratio is above 7:1. Near-black #181f25 over white is even stronger. Accent orange #da570e is bright enough against white but keep an eye on accessibility when used against blue backgrounds — may drop contrast.
Dark mode isn’t fully implemented but they have clear dark-surface text tokens. Accessibility is baked in via tokens like --text-on-primary-disabled and subdued variants for low-emphasis text.
2.4 Usage Guide
- Use primary blue for interactive elements: buttons, key nav links.
- Use header dark (
#181f25) for text anchors; avoid using pure black except for small text segments. - Accent orange is only for focus outlines or critical hover states — don’t use for brand decoration.
- Keep high contrast: dark text on light, light text on dark — they provide tokens for both.
- Avoid mixing accent light blue
#066db1with primary blue — will look inconsistent.
3. Typography
3.1 Font Families
- Primary:
"Open Sans", roboto, roboto-fallback - Icon:
"loopicon" - Sources: Not from Google/Adobe; likely self-hosted. No variable font variants.
Open Sans dominates headings, links, body text, and buttons. Loopicon appears in small icon labels/captions.
3.2 Type Scale Table
| Element | Font | Size | Weight | Line Height | Transform |
|---|---|---|---|---|---|
| Heading-1 | Open Sans | 48px | 700 | 1.21 | none |
| Heading-1 | Open Sans | 48px | 700 | 1.00 | none |
| Heading-1 | Open Sans | 40px | 700 | 1.12 | none |
| Heading-1 | Open Sans | 40px | 400 | 1.12 | none |
| Heading-1 | Open Sans | 40px | 700 | 1.15 | none |
| Heading-1 | Open Sans | 40px | 400 | 1.12 | uppercase |
| Heading-1 | Open Sans | 36px | 700 | 1.15 | none |
| Button | Open Sans | 28px | 400 | 1.40 | none |
| Heading-1 | Open Sans | 28px | 400 | 1.40 | none |
| Heading-1 | Open Sans | 28px | 700 | 1.16 | none |
| Heading-1 | Open Sans | 26px | 500 | 1.38 | uppercase |
| Link | Open Sans | 24px | 700 | 1.50 | none |
| Heading-1 | Open Sans | 24px | 700 | 1.50 | none |
| Heading-1 | Open Sans | 24px | 500 | 1.25 | none |
| Heading-1 | Open Sans | 24px | 500 | 1.50 | none |
| Heading-1 | Open Sans | 24px | 700 | 1.50 | none |
| Heading-1 | Open Sans | 20px | 700 | 1.20 | none |
| Link | Open Sans | 20px | 400 | 1.25 | none |
| Heading-1 | Open Sans | 20px | 400 | 1.40 | none |
| Button | Open Sans | 20px | 400 | 1.40 | none |
| Heading-1 | Open Sans | 20px | 700 | 1.40 | none |
| Heading-1 | loopicon | 20px | 400 | 1.00 | none |
| Link | loopicon | 18px | 400 | 1.39 | none |
| Button | Open Sans | 16px | 700 | 1.50 | none |
| Caption | Open Sans | 14px | 400 | 1.29 | none |
| Caption | Open Sans | 14px | 700 | 1.70 | none |
| Caption | loopicon | 14px | 400 | 1.00 | none |
| Caption | Open Sans | 13px | 700 | 1.23 | uppercase |
| Caption | Open Sans | 13px | 700 | 1.25 | uppercase |
| Caption | Open Sans | 12px | 700 | 1.40 | none |
3.3 Hierarchy
Hierarchy is mostly built on weight and size. Page titles: 48px/700. Subtitles: 40px variations. Smaller headings drop in logical increments: 36 → 28 → 24 → 20. Captions down to 12–14px. Everything keeps reasonable line heights (1.12–1.50) for readability. No absurdly tight or loose line spacing.
4. Spacing & Layout
4.1 Spacing Scale
Base grid: 8px, but they use micro steps (1px, 6px). Here's the list:
| Value | REM | Count |
|---|---|---|
| 1px | 0.06rem | 1 |
| 4px | 0.25rem | 74 |
| 6px | 0.38rem | 376 |
| 7px | 0.44rem | 4 |
| 8px | 0.50rem | 115 |
| 10px | 0.63rem | 10 |
| 12px | 0.75rem | 21 |
| 14px | 0.88rem | 6 |
| 15px | 0.94rem | 7 |
| 16px | 1.00rem | 60 |
| 20px | 1.25rem | 10 |
| 22px | 1.38rem | 2 |
| 24px | 1.50rem | 22 |
| 32px | 2.00rem | 23 |
| 40px | 2.50rem | 12 |
| 48px | 3.00rem | 13 |
| 58px | 3.63rem | 3 |
| 64px | 4.00rem | 13 |
| 80px | 5.00rem | 5 |
| 96px | 6.00rem | 5 |
4.2 Layout
Breakpoints are extensive: from 320px mobile to 1400px desktop. They even include oddball 830px and 930px — suggests some legacy grids. Vuetify framework confirms a flex/grid-based responsive approach.
5. Visual Elements
-
Border Radius:
- 0px combos: ul, cards (bottom rounding)
- 5px: images
- 8px: cards, divs, imgs — standard soft corner
- 32px: pills — buttons, search clears
- 50%: avatars/icons
- 100px: inputs — extreme pill shaping
- 125px icons — large pill icons
-
Shadows: None. Flat design using borders for depth.
-
Borders: Used for dividers: 1px solid, primarily neutrals or low-opacity variants. Underlines for links (1px).
6. Components
6.1 Buttons
Primary (Blue)
Default: bg #004370, text white, padding 16px 32px, radius 32px, no shadow.
Hover: transparent bg, white text, border 2px accent blue, scale 1.1, opacity 0.7.
Focus: outline 2px orange, bg light accent, border accent blue, translateY(-50%).
Secondary (White bg)
Default: bg white, text primary blue, border transparent.
Hover: transparent bg, white text, border accent blue.
Control Button (Small)
Default: bg transparent, text white, padding 6px, radius 32px.
Hover: bg accent blue, border accent blue, opacity 0.7.
6.2 Links
Three variants:
- White text links — hover remains white.
- Blue underlined links — hover removes underline, turns white.
- Dark text links — hover turns white.
6.3 Forms
Inputs:
- Text/Email: white bg, dark navy text, border neutral, extreme pill radius — one side rounded.
- Focus: text turns grey.
6.4 Cards
Radius 8px, sometimes with bottom-only rounding. Borders for separation, no shadows.
7. Design Tokens
:root {
/* Colors */
--header-dark: #181f25;
--white: #ffffff;
--primary-blue: #004370;
--navy-transparent: #000d1a;
--deep-navy: #012740;
--black: #000000;
--accent-orange: #da570e;
--accent-light-blue: #066db1;
--brand-dark-blue: #002244;
--brand-blue: #009fda;
/* Typography */
--font-primary: "Open Sans", roboto, roboto-fallback;
--font-icon: "loopicon";
/* Spacing */
--space-1: 1px;
--space-4: 4px;
--space-6: 6px;
--space-8: 8px;
--space-10: 10px;
--space-12: 12px;
--space-14: 14px;
--space-15: 15px;
--space-16: 16px;
--space-20: 20px;
--space-22: 22px;
--space-24: 24px;
--space-32: 32px;
--space-40: 40px;
--space-48: 48px;
--space-58: 58px;
--space-64: 64px;
--space-80: 80px;
--space-96: 96px;
/* Radius */
--radius-0: 0px;
--radius-5: 5px;
--radius-8: 8px;
--radius-32: 32px;
--radius-50pct: 50%;
--radius-100: 100px;
--radius-125: 125px;
/* Borders */
--border-underline: 1px solid #bdccdb;
}8. AI Coding Assistant Prompt
# World Bank Design System Specification
You are a World Bank design expert. Build UIs matching their visual language exactly.
## Brand Context
World Bank's design is disciplined, functional, and conservative. Colors are corporate blues, whites, and near-blacks, with accents only for focus and hover. Typography uses Open Sans exclusively, on a strict size/weight scale. Borders and radii are precise, with a flat design approach — no drop shadows.
## Color Palette
- Header Dark: #181f25 — Header wrapper text, primary headings
- White: #ffffff — Page background, cards, dropdowns
- Primary Blue: #004370 — Primary CTAs, buttons, header accents
- Navy Transparent: #000d1a — Overlay backgrounds
- Deep Navy: #012740 — Section backgrounds
- Black: #000000 — Miscellaneous text
- Accent Orange: #da570e — Focus outlines, hover emphasis
- Accent Light Blue: #066db1 — Hover/focus feedback
- Brand Dark Blue: #002244 — Brand accents
- Brand Blue: #009fda — Secondary brand highlight
## Typography
Font Families:
- "Open Sans", roboto, roboto-fallback — all text
- "loopicon" — icons
Type Sizes/Weights:
| Level | Size | Weight | Line Height | Use For |
|-------|------|--------|-------------|---------|
| H1 | 48px | 700 | 1.21 | Page titles |
| H2 | 40px | 700 | 1.12 | Section headings |
| Body Lg | 28px | 400 | 1.40 | Paragraphs |
| Body Sm | 20px | 400 | 1.25 | Small text |
| Caption | 14px | 400 | 1.29 | Footnotes |
## Spacing & Grid
Base unit: 8px
Scale: 1px, 4px, 6px, 8px, 10px, 12px, 14px, 15px, 16px, 20px, 22px, 24px, 32px, 40px, 48px, 58px, 64px, 80px, 96px
## Border Radius
- none: 0px — data tables
- sm: 5px — small images
- md: 8px — cards
- lg: 32px — buttons
- full: 50% — avatars/icons
- extreme pill: 100px — inputs
- large icon pill: 125px — large icons
## Shadows & Depth
Flat design — use borders for separation.
## Component Specifications
### Primary Button
Default:
- Background: #004370
- Color: #ffffff
- Padding: 16px 32px
- Radius: 32px
- Border: 1px solid transparent
Hover:
- Background: transparent
- Color: #ffffff
- Border: 2px solid #004370
- Transform: scale(1.1)
Focus:
- Outline: 2px solid #da570e
- Background: #00437010
Active:
- Transparent background
### Secondary Button
Default:
- Background: #ffffff
- Color: #004370
- Radius: 32px
Hover identical to primary.
### Link
Primary link: #004370, underline
Hover: #ffffff, no underline
### Input Field
Background: #ffffff
Color: rgba(0,13,26,0.698)
Border: 1px solid rgba(0,57,107,0.24)
Radius: side-specific (100px extreme pill)
Padding: 22px 10px 10px 29px
Focus: text color #999999
## Layout & Responsive Rules
Breakpoints: 320px, 768px, 1024px, 1200px, 1400px
Use Vuetify grid structure.
## Interaction Rules
- Transition: 150ms ease for hover/focus changes
- Focus: 2px orange outline
- Hover: opacity 0.7 for buttons
## DO List
- Use only defined palette
- Maintain 8px grid for spacing
- Use Open Sans for all text
- Apply correct border radius per component
- Use hover scale on buttons
## DON'T List
- Add drop shadows
- Mix sharp and rounded corners
- Use colors outside palette
- Apply gradients
## Code Examples
```css
.btn-primary {
background: #004370;
color: #ffffff;
padding: 16px 32px;
border-radius: 32px;
font-weight: 700;
font-size: 16px;
border: 1px solid transparent;
transition: all 150ms ease;
}
.btn-primary:hover {
background: transparent;
color: #ffffff;
border: 2px solid #004370;
transform: scale(1.1);
opacity: 0.7;
}
.btn-primary:focus {
outline: 2px solid #da570e;
}
.input {
background: #ffffff;
color: rgba(0,13,26,0.698);
border: 1px solid rgba(0,57,107,0.24);
border-radius: 100px 0 0 100px;
padding: 22px 10px 10px 29px;
}
```9. Summary
TL;DR — This system is corporate blue discipline. Every element is on a grid, colors are locked to a strict token set, typography is all Open Sans, and no shadows — borders do the work. Perfect for austere, high-trust interfaces.
Brand Keywords: global-institutional, governance-serious, blue-authoritative, flat-trustworthy