π Roman's Pizza Design System
Design tokens, Lucide icons, and component classes β one source of truth for all RP digital products.
Gradients
All gradients follow a single rule: lightest colour at the top, darkest at the bottom. This creates natural visual hierarchy β the eye tracks downward through increasing weight β and anchors heavier UI elements (tables, footers, chart axes) with a darker, more grounded base.
Gradient tokens
--g-blue
Buttons, hero cards, badges, CTAs
--g-sidebar
Sidebar nav, dark panels
Surface gradient
Inline use β subtle depth on cards
Direction rule
Correct β light top, dark bottom
Incorrect β dark top, light bottom
Usage in CSS
/* Use the token β never repeat the raw gradient */
.my-hero { background: var(--gradient-brand-blue); }
.my-panel { background: var(--gradient-sidebar); }
/* Custom one-off: always light β dark, top β bottom */
.my-banner {
background: linear-gradient(180deg, #0260c9 0%, #014085 100%);
}Colours
Brand
#014085
#012d5e
#0260c9
#ed1c24
#c41820
Semantic Status
Rating Scale
Typography
Page Heading β 1.875rem / 800
Section Title β 1.375rem / 700
Card Heading β 1rem / 600
Body text β 0.875rem / 400. Inter is the typeface across all RP products.
Small / muted β 0.75rem
LABEL CAPS β 0.6875rem / 700 / UPPERCASE
Spacing & Radii
| Token | Value | Use |
|---|---|---|
| --spacing-card | 1.375rem | Internal card padding |
Radius Tokens
Shadows
Motion
| Token | Value |
|---|---|
| --transition-fast | 150ms ease |
| --transition-base | 250ms ease |
| --ease-settle | cubic-bezier(0.25, 0.46, 0.45, 0.94) |
| --ease-spring | cubic-bezier(0.175, 0.885, 0.32, 1.275) |
Buttons
Badges
Cards
Stat Grid
Total Reviews
1,248
+12% vs last month
Avg Rating
4.3
out of 5
Promoters
68%
Semantic Tints
Success
Warning
Error
Info
Accent Left-Border
Success
Warning
Error
Chips
Bar Charts
Tables
| Branch | Reviews | Avg Rating | Status |
|---|---|---|---|
| Sandton City | 312 | 4.6 | Active |
| Rosebank | 198 | 4.1 | Pending |
| Midrand | 87 | β | Archived |
Inputs
Modals
Rate Your Order
This is the modal card component. Backdrop fade and slide-up animate on mount.
Empty States
No reviews yet
Once customers leave reviews they'll appear here. Share your link to get started.
Loading States
Icons
Why Lucide SVG icons exclusively
aria-label or are hidden with aria-hidden="true" when decorative, giving full control over the announcement.
currentColor, meaning icons respond to semantic colour tokens (--color-success, --color-error, etc.) and work correctly in dark mode without any extra markup.
width/height attributes map directly to the design grid. Emoji size is controlled by font-size and behaves inconsistently inside flex and grid layouts.
Click any icon to copy its usage snippet. Install: npm i lucide or see How to Use.
Loading iconsβ¦
Dark Mode
Add data-theme="dark" to <html> (or any ancestor) to switch the full token set to dark values. No extra stylesheet needed β all tokens are overridden via CSS custom properties.
Implementation
/* Toggle in JS */
document.documentElement.dataset.theme = 'dark';
/* Or respect system preference */
const dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (dark) document.documentElement.dataset.theme = 'dark';Light vs Dark preview
Light (default)
Total Reviews
1,248
Dark
Total Reviews
1,248
Token changes in dark mode
| Token | Light | Dark | Role |
|---|---|---|---|
| --color-background | #f0f4f8 | #0a0f1a | Page background |
| --color-surface | #ffffff | #111827 | Card / panel background |
| --color-surface-dim | #f8f9fa | #1a2233 | Subtle surface / table header |
| --color-surface-container | #f3f4f6 | #1e293b | Secondary control background |
| --color-on-surface | #0f172a | #f1f5f9 | Primary text |
| --color-on-surface-muted | #64748b | #94a3b8 | Secondary / placeholder text |
| --color-outline | #cbd5e1 | #334155 | Border β inputs |
| --color-outline-variant | #e2e8f0 | #1e293b | Border β subtle / cards |
Icon colour utilities
Apply these classes directly to any Lucide <svg>. Use the parent .icon-hover--* classes to change icon colour on hover.
<!-- Colour class on the svg --> <svg data-lucide="check-circle" width="20" height="20" class="icon--ok"></svg> <svg data-lucide="alert-triangle" width="20" height="20" class="icon--warn"></svg> <!-- Icon button variants --> <button class="icon-btn"><svg data-lucide="copy" width="16" height="16"></svg></button> <button class="icon-btn icon-btn--blue"><svg data-lucide="download" width="16" height="16"></svg></button> <button class="icon-btn icon-btn--danger"><svg data-lucide="trash-2" width="16" height="16"></svg></button> <!-- Hover: change icon colour when parent is hovered --> <a class="icon-hover--blue" href="/"> <svg data-lucide="home" width="18" height="18"></svg> Home </a>
How to Use
CDN
<link rel="stylesheet" href="https://design.romanspizza.co.za/rp-style.css"> <script src="lucide.min.js"></script> <script>lucide.createIcons();</script>
npm
npm install lucide rp-design-system
// In your JS entry:
import { createIcons, icons } from 'lucide';
import 'rp-design-system/dist/rp-style.css';
createIcons({ icons });Icon usage
<!-- Add a data-lucide attribute, then call createIcons() once --> <svg data-lucide="star" width="20" height="20"></svg> <button class="rp-btn rp-btn--primary"> <svg data-lucide="download" width="14" height="14"></svg> Download </button>