Design System
The shared design token system, component library, and UI patterns used across MavelPoint and MavelCam. Dark & light mode, WCAG AA compliant, built on Astro 5 SSR with React 18 islands.
Color Tokens
Brand, semantic, and utility color definitions. Dark theme uses a #161616 base; light theme uses a #F8F9FA base. All tokens are defined as CSS custom properties.
Brand Colors
The primary and secondary brand colors that define MavelPoint's visual identity.
Lime
#B9F23A
Primary action, CTAs
Indigo
#7B91FF
Secondary, focus rings
Black (Base)
#161616
Page background
White
#FFFFFF
Primary text
Semantic Colors
Status indicators for feedback, validation, and alerts.
Danger
#FF5858
Errors, destructive actions
Success
#34E09B
Confirmations, positive feedback
Warning
#F9E24C
Caution, pending states
Lime Opacity Scale
Used for hover states, backgrounds, and subtle tints.
5%
10%
15%
20%
30%
40%
50%
100%
Indigo Opacity Scale
Used for badges, focus states, and secondary accents.
5%
10%
15%
20%
30%
100%
White Opacity Scale
The backbone of the dark-mode surface hierarchy. Every border, divider, and muted label uses this scale.
5%
Fill
10%
Border
15%
Hover
20%
Active
30%
Muted
40%
Muted
50%
Secondary
60%
Body
70%
80%
90%
100%
Heading
Surface Hierarchy
Layered dark surfaces create depth without color. Use base-fill (white-5) for card backgrounds overlaid on black.
Black (Base)
#161616 -- bg-black -- Page background, lowest layer
Base Fill
rgba(255,255,255,0.05) -- bg-white-5 -- Cards, panels, input backgrounds
Surface Secondary
rgba(255,255,255,0.10) -- bg-white-10 -- Hover states, border color
Surface Tertiary
rgba(255,255,255,0.15) -- bg-white-15 -- Active states, elevated elements
Light Theme Tokens
When the dark class is removed from <html>, these tokens activate. Accent colors are darkened for WCAG AA compliance on the light #F8F9FA background.
Lime (Light)
#4A7C00
Darkened for contrast on #F8F9FA
Indigo (Light)
#4F46E5
Darkened for contrast on #F8F9FA
Background (Light)
#F8F9FA
Page background
Text (Light)
#161616
Primary text
Danger (Light)
#DC2626
Success (Light)
#16A34A
Warning (Light)
#CA8A04
Key Differences from Dark Theme
- • Lime darkened from #B9F23A → #4A7C00 for WCAG AA on light backgrounds
- • Indigo darkened from #7B91FF → #4F46E5 for contrast compliance
- • bg-lime buttons always use bright #B9F23A via CSS override in both themes
- • Semantic colors darkened: Danger #DC2626, Success #16A34A, Warning #CA8A04
- • Shadows use rgba(0,0,0,0.06-0.10) instead of rgba(0,0,0,0.3)
- • Glass effect: rgba(248,249,250,0.85) with backdrop-filter: blur(20px)
- • White opacity scale becomes black opacity scale (rgba(0,0,0,x)) for text/surface layers
Light Theme Opacity Scale (Black-based)
In light mode, the white-* tokens map to rgba(0,0,0,x) for dark text and surfaces on the light background.
| Token | Dark Value | Light Value |
|---|---|---|
| white-5 | rgba(255,255,255,0.05) | rgba(0,0,0,0.03) |
| white-10 | rgba(255,255,255,0.10) | rgba(0,0,0,0.06) |
| white-50 | rgba(255,255,255,0.50) | rgba(0,0,0,0.45) |
| white-60 | rgba(255,255,255,0.60) | rgba(0,0,0,0.55) |
| white (100%) | #FFFFFF | #161616 |
Typography
Matter is the primary font family across all MavelPoint products — headings, body text, buttons, and UI. Inter is the fallback. All sizes are rem-based with responsive scaling.
Font Families
Matter is the primary typeface. Inter is the fallback when Matter is unavailable.
Matter — Primary
Tailwind class: font-matter
Self-hosted woff2. Weights Light–Bold. Used for body text, headings, buttons, and all UI elements. Falls back to Inter, then sans-serif.
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
Inter — Fallback
Tailwind class: font-inter
Google Fonts. Used only when Matter is unavailable.
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
Desktop Type Scale
Heading and body text sizes for screens ≥ 768px. All headings use 130% line height; body uses 150%.
| Token | Size | Line Height | Usage |
|---|---|---|---|
| text-heading2xl-desktop | 48px | 130% | Hero headlines |
| text-headingXl-desktop | 40px | 130% | Page titles (marketing) |
| text-headingLg-desktop | 36px | 130% | Major section headers |
| text-headingMd-desktop | 32px | 130% | Section headers |
| text-headingBase-desktop | 28px | 130% | Subsection headers |
| text-headingSm-desktop | 24px | 130% | Card titles |
| text-headingXs-desktop | 20px | 130% | Minor headings |
| Body Text | |||
| text-textLg-desktop | 20px | 150% | Lead paragraphs |
| text-textMd-desktop | 18px | 150% | Large body text |
| text-textBase-desktop | 16px | 150% | Default body text |
| text-textSm-desktop | 14px | 150% | Secondary body |
| text-textXs-desktop | 12px | 150% | Captions, fine print |
Mobile Type Scale
Reduced sizes for screens below 768px.
| Token | Size | Usage |
|---|---|---|
| headingXl | 20px | Page titles |
| headingLg | 18px | Section headers |
| headingMd | 16px | Card titles |
| textLg | 16px | Lead paragraphs |
| textMd | 14px | Body copy |
| textBase | 12px | Captions, labels |
Button Text Scale
Dedicated sizes for interactive button labels.
Text Color Hierarchy
Three tiers of text prominence for establishing visual hierarchy.
Primary text -- headings, key content
text-white / #FFFFFFSecondary text -- body copy, descriptions
text-white-60Muted text -- captions, timestamps, metadata
text-white-40Disabled text -- inactive labels, placeholders
text-white-30Typography Rules
Rendering, spacing, and capitalization guidelines.
Line Heights
All headings: 130%
All body text: 150%
Font Smoothing
Antialiased on retina displays. Subpixel rendering on non-retina (Windows ClearType).
Windows ClearType
letter-spacing: 0.01em applied for ClearType readability on Windows.
iOS Input Zoom
Inputs forced to 14px minimum to prevent auto-zoom on focus in iOS Safari.
Capitalization
Sentence case everywhere. NEVER all caps for more than 2–3 words. Monospace only for code/technical contexts.
Headlines
Punchy, 6 words or fewer when possible. Body text uses generous line height (1.5–1.7).
Spacing & Layout
Responsive grid system with 7 breakpoints. Column count, gaps, and margins scale with viewport.
Breakpoint System
Seven named breakpoints from mobile to ultra-wide. Tailwind screens override defaults.
| Name | Min Width | Columns | Typical Devices |
|---|---|---|---|
| xs | 360px | 4 | Small phones |
| sm | 768px | 8 | Tablets, large phones landscape |
| md | 1024px | 12 | Laptops, tablets landscape |
| mdMiddle | 1200px | 12 | Small desktops |
| lg | 1440px | 12 | Standard desktops |
| xl | 1536px | 16 | Large desktops |
| 2xl | 1720px | 16 | Ultra-wide monitors |
Border Radius
Consistent rounding tokens from subtle to large.
4px
Badges
8px
Inputs
12px
Cards (xl)
16px
Modals (2xl)
24px
Containers
32px
Pills
Full
Avatars
Shadows
Five elevation levels using black-based box-shadows. All use rgba(0,0,0,0.3) for consistency on dark surfaces.
XS
0 1px 2px
Buttons
S
0 2px 4px
Cards
MD
0 4px 8px
Dropdowns
LG
0 8px 16px
Modals
XL
0 16px 32px
Drawers
Glass Morphism
Used on the header navigation and overlay panels. Combines semi-transparent background with backdrop blur.
glass-effect
Dark: background: rgba(22, 22, 22, 0.8)
Light: background: rgba(248, 249, 250, 0.85)
backdrop-filter: blur(20px)
Apply via the .glass-effect utility class.
Components
Reusable UI components with typed variants, sizes, and states. Built in Astro 5 SSR with React 18 islands for interactivity.
Buttons
4 variant types, 3 color schemes, 3 sizes. All buttons include a minimum 44px touch target on mobile for accessibility.
Primary -- bg-lime text-black
Secondary -- border style
Ghost -- transparent background
Danger -- destructive actions
Focus state: ring-2 ring-indigo ring-offset-2 ring-offset-black. Disabled state: opacity-50 cursor-not-allowed.
Badges
4 color schemes (lime, indigo, danger, default), 3 types (filled, soft, outline), 3 sizes.
Soft (default style)
Filled
Outline
Cards
Four card types for different content patterns. All use surface background with border-white-10 borders.
Card (Base)
Standard content card with title, description, and slot for children. Rounded-xl, border-white-10, bg-white-5.
CardArrow
Navigational card with hover arrow animation. Used for linked feature pages and navigation lists.
→DateCard
Card with a date badge. Used for events, blog posts, and time-sensitive content.
CardBackgroundColorImage
Card with gradient or image background. Used for featured content and hero sections.
Inputs
3 sizes (sm, md, lg) with 3 statuses each (default, error, success). All include focus ring-2 ring-indigo.
Default State
Status Variants
Error messages rendered below using the TextError component in danger red (#FF5858).
Tabs
Generic typed tabs with animated indicator. Built with Headless UI for accessibility and Framer Motion for the sliding underline.
Active tab: text-lime with animated bottom bar. Inactive: text-white-50 with hover:text-white transition. The indicator slides between tabs via Framer Motion layoutId.
Text Components
Typed Heading and Paragraph components with semantic HTML output.
<Heading level=1 size="2xl">
Renders semantic h1-h6 tags
Props: level (1-6), size (xs-2xl), class. Outputs the correct HTML heading element.
<Paragraph size="md">
Body text with consistent line-height and color.
Props: size (sm, md, lg), class. Always renders as a p element.
<TextError>
This field is required.
Renders error messages below form fields. Fixed color: text-danger (#FF5858).
Icons
Phosphor Icons as the primary icon set, extended with custom platform-specific icons for social and streaming services.
Phosphor Icons
Primary icon set. Used for UI actions, navigation, and system feedback. Available in regular, bold, fill, and duotone weights. Default size: 20px for UI, 24px for navigation.
Custom Platform Icons
Brand and platform icons not available in Phosphor: SoundCloud, Beatport, Bandcamp, Resident Advisor, Mixcloud, and other electronic music platforms.
Animations & Effects
Motion design using Framer Motion for React islands and CSS keyframes for static content. All animations respect prefers-reduced-motion.
Keyframe Animations
CSS animations defined in the Tailwind config and global stylesheet.
| Name | Behavior | Usage |
|---|---|---|
| fadeIn | Opacity 0 to 1, translateY 10px to 0 | Page section entrances, card reveals |
| caret-blink | Opacity 0/1 toggle on 1s loop | Text input cursor |
| loader-bounce | Scale and translateY bounce | Loading dots indicator |
| loader-orbit | 360-degree rotation loop | Spinner loading state |
| loader-dash | SVG stroke-dasharray animation | Progress ring indicator |
Framer Motion Patterns
React island animations for interactive components.
Staggered Entrance
Children animate in sequence with a staggerChildren delay of 0.05-0.1s. Each child fades in and slides up. Used on card grids, feature lists, and search results.
Tab Indicator (layoutId)
Shared layout animation that smoothly slides the active indicator between tab positions. Uses Framer Motion layoutId for automatic interpolation.
Marquee / Infinite Scroll
CSS-driven infinite horizontal scroll for partner logos and social proof. Duplicates children to create seamless loop. Pauses on hover.
Reduced Motion
All animations are disabled when the user has prefers-reduced-motion: reduce enabled.
The global stylesheet forces all animation-duration and transition-duration to 0.01ms when reduced motion is preferred. This is applied via a single media query rule on *, *::before, *::after.
Architecture & State
Technical foundation: Astro 5 SSR with React 18 islands for interactive components.
Rendering Model
Astro 5 SSR -- All pages server-rendered, zero JS by default
React 18 Islands -- Interactive components hydrate via client:load or client:visible
Headless UI -- Accessible primitives for dialogs, menus, tabs
State Management
Nanostores -- Shared state across Astro and React islands
URL State -- Search params for filters, pagination, locale
React Context -- Scoped state within island boundaries
Internationalization
5 languages supported via getLangFromUrl() and useTranslations() utilities.
Language detection from URL path prefix. Translation keys co-located with components.
Icon System
Phosphor Icons -- UI and system icons, 4 weight variants
Custom SVGs -- Platform icons (SoundCloud, Beatport, Bandcamp, RA)
Sizing -- 16px inline, 20px UI, 24px navigation, 32px hero
Accessibility
WCAG AA compliance throughout. Every interactive element meets minimum contrast, focus visibility, and touch target requirements.
Contrast Ratios
White on Black
Lime on Black
Indigo on Black
All primary text combinations exceed WCAG AA 4.5:1 minimum. Large text (18px+) exceeds AA 3:1 minimum.
Focus & Touch
Focus Ring
ring-2 ring-indigo ring-offset-2 ring-offset-black on all interactive elements via :focus-visible
Touch Targets
Minimum 44x44px on all buttons, links, and interactive elements per WCAG 2.1 AAA
Semantic HTML
Proper heading hierarchy, landmark regions, ARIA labels on all custom widgets
Keyboard Navigation
Full tab order, arrow key navigation for tabs and menus, Escape to close modals