Pairty™ Design Tokens
v1.1.0
Pairty™ Design System
Human Venture Capital Platform
The single source of truth for brand colors, typography, spacing, and component styles. Now includes comprehensive landing page patterns and accessibility guidelines.
Colors
The Pairty color palette is built around three brand colors with supporting background, text, and semantic colors.
Brand Colors
Pairty Blue
#0049E7
--color-brand-primary
Buttons, links, CTAs, primary actions
Bright Blue
#249AE3
--color-brand-secondary
Info states, secondary highlights
Pairty Teal
#47EBE0
--color-brand-accent
Success accents, gradient endpoints
Background Colors
Off White
#EAEAEC
--color-background-light
Light mode backgrounds
Charcoal
#262626
--color-background-dark
Dark mode backgrounds
Dark Alt
#111122
--color-background-dark-alt
Mobile app dark (legacy)
Deep Dark
#0a0a0a
--color-background-deep
Website deep dark
Text Colors
Primary Light
#262626
--color-text-primary-light
Body text on light backgrounds
Primary Dark
#EAEAEC
--color-text-primary-dark
Body text on dark backgrounds
Muted Light
#6b7280
--color-text-muted-light
Secondary text on light
Muted Dark
#9ca3af
--color-text-muted-dark
Secondary text on dark
Semantic Colors
Success
#22c55e
--color-success
Success states, confirmations
Warning
#fbbf24
--color-warning
Warnings, caution states
Error
#ef4444
--color-error
Errors, destructive actions
Info
#249AE3
--color-info
Informational messages
Usage
CSS Variables
.button {
background: var(--color-brand-primary);
color: var(--color-text-primary-dark);
}Tailwind Classes
<button className="bg-pairty-blue text-white"> Click me </button>
Typography
Typographic scale and font families for consistent text styling across platforms.
Font Families
Display
Neue Haas Grotesk Display, Inter, system-ui, sans-serif
Headlines, hero text
⚠️ Commercial font - using Inter as fallback until licensed
Body
Inter, system-ui, sans-serif
Body text, UI elements
Body Mobile
Nunito Sans, system-ui, sans-serif
Mobile app body text (legacy)
⚠️ Consider standardizing to Inter
Mono
JetBrains Mono, monospace
Code, data, numbers
Font Sizes
| Token | Web | Mobile | Line Height | Preview |
|---|---|---|---|---|
| xs | 0.75rem | 12px | 1rem | The quick brown fox |
| sm | 0.875rem | 14px | 1.25rem | The quick brown fox |
| base | 1rem | 16px | 1.5rem | The quick brown fox |
| lg | 1.125rem | 18px | 1.75rem | The quick brown fox |
| xl | 1.25rem | 20px | 1.75rem | The quick brown fox |
| 2xl | 1.5rem | 24px | 2rem | The quick brown fox |
| 3xl | 1.875rem | 30px | 2.25rem | The quick brown fox |
| 4xl | 2.25rem | 36px | 2.5rem | The quick brown fox |
| 5xl | 3rem | 48px | 1 | The quick brown fox |
Font Weights
light
300
normal
400
medium
500
semibold
600
bold
700
extrabold
800
black
900
Type Scale
Display Heading
H1 Heading
H2 Heading
H3 Heading
H4 Heading
Large body text for emphasis
Regular body text for paragraphs and UI.
Small text for captions and secondary info.
Extra small text for labels and metadata.
Usage
CSS Variables
.heading {
font-family: var(--font-display);
font-size: var(--font-size-4xl);
font-weight: 700;
}Tailwind Classes
<h1 className="font-display text-4xl font-bold"> Heading </h1> <p className="font-body text-base"> Body text </p>
Spacing & Layout
Consistent spacing scale for margins, padding, gaps, and layout measurements.
Spacing Scale
0
0px
px
1px
0.5
2px
1
4px
1.5
6px
2
8px
2.5
10px
3
12px
3.5
14px
4
16px
5
20px
6
24px
7
28px
| Token | Value | Pixels | Preview |
|---|---|---|---|
| 0 | 0 | 0px | |
| px | 1px | 1px | |
| 0.5 | 0.125rem | 2px | |
| 1 | 0.25rem | 4px | |
| 1.5 | 0.375rem | 6px | |
| 2 | 0.5rem | 8px | |
| 2.5 | 0.625rem | 10px | |
| 3 | 0.75rem | 12px | |
| 3.5 | 0.875rem | 14px | |
| 4 | 1rem | 16px | |
| 5 | 1.25rem | 20px | |
| 6 | 1.5rem | 24px | |
| 7 | 1.75rem | 28px | |
| 8 | 2rem | 32px | |
| 9 | 2.25rem | 36px | |
| 10 | 2.5rem | 40px | |
| 11 | 2.75rem | 44px | |
| 12 | 3rem | 48px | |
| 14 | 3.5rem | 56px | |
| 16 | 4rem | 64px | |
| 20 | 5rem | 80px | |
| 24 | 6rem | 96px |
Border Radius
none
0
sm
0.25rem
md
0.375rem
lg
0.5rem
xl
0.75rem
2xl
1rem
3xl
1.25rem
Mobile nav radius
4xl
1.875rem
Mobile content radius
full
9999px
Breakpoints
Usage
CSS Variables
.card {
padding: var(--spacing-lg);
border-radius: var(--radius-xl);
margin-bottom: var(--spacing-md);
}Tailwind Classes
<div className="p-6 rounded-xl mb-4"> <h2 className="mb-2">Title</h2> <p className="mt-4">Content</p> </div>
Gradients
Brand gradients for creating depth and visual interest. Updated with landing page patterns.
Text Gradients
Text Heading
--gradient-text-heading
Section headlines (from Figma)
Text Hero
--gradient-text-hero
Hero headline text
Network Worth
--gradient-text-network-worth
Network value display
Background Gradients
Section Background
--gradient-background-section
Landing page sections
Section Alt
--gradient-background-section-alt
Alternate section backgrounds
Card Hover
--gradient-background-card-hover
Feature card hover state
CTA Gradients
--gradient-cta-animated
--gradient-cta-animated-reverse
Overlay Gradients
Border Gradients
--gradient-border-member-card
Member card gradient border
--gradient-border-footer-top
Footer top glow border
Usage
CSS
.section {
background: linear-gradient(to bottom, #0a1628, #0f1a2e);
}
.gradient-text {
background: linear-gradient(278deg, #47EBE0 28.45%, #0049E7 100.49%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.gradient-border {
background:
linear-gradient(#0c1829, #0c1829) padding-box,
linear-gradient(to bottom, #1e3a5f, #0a1628) border-box;
border: 1px solid transparent;
}Tailwind Classes
{/* Background */}
<div className="bg-gradient-section">
Section content
</div>
{/* Text */}
<h1 className="bg-gradient-text-heading
bg-clip-text text-transparent">
Gradient Heading
</h1>
{/* CTA with swap */}
<button className="bg-gradient-cta
hover:bg-gradient-cta-reverse">
Download
</button>Animations
Keyframe animations, transitions, and Framer Motion easing for consistent motion.
Tailwind Animation Examples
Fade In
animate-fade-in
Element entrance
Slide Up
animate-slide-up
Content reveal on scroll
Scale In
animate-scale-in
Modal entrance
Float
animate-float
Hero floating elements
Float Delayed
animate-float-delayed
Secondary floating elements
Shimmer
animate-shimmer
CTA button shimmer effect
Special Effects
Banner Shimmer
Top banner announcement effect
Live Ping Indicator
Real-time activity indicator
Pulse Glow
Attention-grabbing glow effect
Gradient Shift
Animated gradient backgrounds
Transitions
Fast
150ms ease
Hover states, small interactions
Base
300ms ease
Default transitions
Slow
500ms ease
Page transitions, feature card hovers
Framer Motion Easing
smooth
[0.25, 0.46, 0.45, 0.94]
Page transitions, stagger animations (Framer Motion)
spring
stiffness: 300, damping: 30
Modal entrance, banner appearance (Framer Motion)
tween
type: "tween", duration: 0.4
Standard page transitions (Framer Motion)
Tailwind Keyframe Definitions
// tailwind.config.ts
module.exports = {
theme: {
extend: {
animation: {
'gradient-shift': 'gradient-shift 3s ease infinite',
'banner-shimmer': 'banner-shimmer 3s linear infinite',
'shimmer': 'shimmer 2s linear infinite',
'ping-slow': 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
'float': 'float 6s ease-in-out infinite',
'float-delayed': 'float 6s ease-in-out 2s infinite',
'pulse-glow': 'pulse-glow 2s ease-in-out infinite',
'fade-in': 'fade-in 0.5s ease-out',
'slide-up': 'slide-up 0.5s ease-out',
'scale-in': 'scale-in 0.3s ease-out',
},
keyframes: {
'gradient-shift': {
'0%, 100%': { backgroundPosition: '0% 50%' },
'50%': { backgroundPosition: '100% 50%' },
},
'shimmer': {
'0%': { backgroundPosition: '-200% 0' },
'100%': { backgroundPosition: '200% 0' },
},
'float': {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-20px)' },
},
'pulse-glow': {
'0%, 100%': { boxShadow: '0 0 20px rgba(71, 235, 224, 0.3)' },
'50%': { boxShadow: '0 0 40px rgba(71, 235, 224, 0.6)' },
},
// ... more keyframes
},
},
},
};Landing Page Patterns
Design patterns extracted from the Pairty web landing page.
Glassmorphic Patterns
Feature Cards
Feature cards use glassmorphism with backdrop blur and subtle borders. On hover, they transition to a gradient background with all text turning white.
Default State
Glass background with subtle border and blur effect.
Hover State
Gradient background replaces glass, all text becomes white.
Interactive
Hover to see the transition effect.
/* Feature Card CSS */
.feature-card {
border-radius: 24px;
padding: 2rem;
background: rgba(12, 24, 41, 0.9);
backdrop-filter: blur(25px);
border: 1px solid rgba(30, 58, 95, 0.6);
transition: all 0.5s ease;
}
.feature-card:hover {
background: linear-gradient(135deg, #0049E7, #47EBE0);
border-color: transparent;
}Glass Utilities
Light Glass
Use for subtle overlays on dark backgrounds
glass.light: bg-white/5, backdrop-blur-[12px], border-white/10Dark Glass
Use for stronger contrast overlays
glass.dark: bg-black/40, backdrop-blur-[12px], border-white/5Modal Glass
Use for modal and dialog backgrounds
glass.modal: bg-[#0a1628]/95, backdrop-blur-[8px], border-[#1e3a5f]/60Floating CTA Glass
Use for floating action buttons and CTAs
glass.floatingCTA: bg-[#262626]/95, backdrop-blur-[16px], border-white/10FAQ Accordion
Glassmorphic accordion with smooth expand/collapse animation.
Member Card
Complex glassmorphic card with gradient border and multi-color glow shadow.
Sarah Chen
Premium Member
Glow Effects
Section Layouts
Asymmetric Grid Layout
The landing page uses 55/45 and 60/40 asymmetric splits for visual interest.
Content area (text, CTAs)
Visual area (images, graphics)
/* Asymmetric grid using Tailwind */
<div className="grid md:grid-cols-12 gap-8">
<div className="md:col-span-7">Content</div>
<div className="md:col-span-5">Visual</div>
</div>Section Badge
Pill-shaped badges introduce each section with a label.
<span className="inline-flex items-center px-4 py-2 rounded-full
bg-[rgba(255,255,255,0.05)] border border-[rgba(255,255,255,0.1)]
text-sm text-pairty-teal">
✨ Features
</span>Gradient Headlines
Headlines use gradient text with optional text-shadow for glow effect.
Heading Gradient (278deg)
Hero Gradient (90deg)
With Text Glow
/* Gradient text with optional glow */
.gradient-heading {
background: linear-gradient(278deg, #47EBE0 28.45%, #0049E7 100.49%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 40px rgba(71, 235, 224, 0.5); /* optional glow */
}Ambient Background Glow
Large blurred circles create ambient atmosphere behind content.
Video Background Pattern
Hero sections can use video backgrounds with gradient overlays.
/* Video background with overlay */
.hero-video {
position: absolute;
inset: 0;
object-fit: cover;
}
.hero-overlay {
position: absolute;
inset: 0;
background: linear-gradient(135deg,
rgba(15, 15, 15, 0.95) 0%,
rgba(26, 26, 26, 0.85) 40%,
rgba(38, 38, 38, 0.7) 100%);
}
/* Always include poster for loading state */
<video poster="/images/hero-poster.jpg" ...>Dynamic Hero Corners
Hero sections have rounded corners at bottom that animate on scroll.
/* Dynamic corners based on scroll */
const cornerRadius = isScrolled ? '4rem' : '2rem';
<section style={{ borderRadius: `0 0 ${cornerRadius} ${cornerRadius}` }}>
...
</section>Section Backgrounds
Alternating section gradients create visual rhythm.
Modal Patterns
Modal Glassmorphism
Modals use a glassmorphic background with spring animation on entrance.
Modal Title
Modal content goes here. The background uses the glass.modal token with reduced blur for readability.
/* Modal with Framer Motion spring animation */
<motion.div
initial={{ scale: 0.95, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.95, opacity: 0 }}
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
className="modal-content"
>
{/* Modal content */}
</motion.div>
/* Modal glass styling */
.modal-content {
border-radius: 24px;
padding: 2rem;
background: rgba(10, 22, 40, 0.95);
backdrop-filter: blur(8px);
border: 1px solid rgba(30, 58, 95, 0.6);
}Multi-Step Verification Flow
Authentication modals with platform selection and OTP verification.
Step 1: Platform Selection
Step 2: OTP Verification
Enter the 6-digit code sent to your device
Platform Selection Cards
Selection cards with selected/unselected states.
/* Selected state */
.card-selected {
border: 2px solid #47EBE0;
background: rgba(71, 235, 224, 0.1);
}
/* Unselected state */
.card-unselected {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.05);
}
.card-unselected:hover {
border-color: rgba(255, 255, 255, 0.2);
}OTP Input Pattern
Individual character inputs with auto-focus and auto-advance.
/* OTP input styling */
.otp-input {
width: 48px;
height: 56px;
text-align: center;
font-size: 1.25rem;
font-weight: 700;
border-radius: 12px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
color: white;
transition: border-color 150ms ease;
}
.otp-input:focus {
border-color: #47EBE0;
outline: none;
}
/* Auto-advance logic */
const handleChange = (index: number, value: string) => {
if (value && index < 5) {
inputRefs[index + 1].current?.focus();
}
};Interaction Patterns
Header Scroll Show/Hide
Header hides on scroll down (after 300px), shows on scroll up (after 10px).
const [isHeaderVisible, setIsHeaderVisible] = useState(true);
const [lastScrollY, setLastScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
const currentScrollY = window.scrollY;
if (currentScrollY > 300 && currentScrollY > lastScrollY) {
setIsHeaderVisible(false); // Scrolling down
} else if (currentScrollY < lastScrollY - 10) {
setIsHeaderVisible(true); // Scrolling up
}
setLastScrollY(currentScrollY);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [lastScrollY]);Scroll-Spy Navigation
Navigation highlights active section based on scroll position.
// Using Intersection Observer for scroll-spy
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
},
{ rootMargin: '-50% 0px -50% 0px' }
);
sections.forEach((section) => observer.observe(section));Top Banner with Shimmer
Announcement banner with shimmer animation and live indicator.
/* Banner shimmer animation */
@keyframes banner-shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Live ping indicator */
<span className="relative flex h-2.5 w-2.5">
<span className="absolute inline-flex h-full w-full
rounded-full bg-emerald-500 opacity-75 animate-ping" />
<span className="relative inline-flex h-2.5 w-2.5
rounded-full bg-emerald-500" />
</span>Auto-Cycling Carousel
Infinite scroll carousel that pauses on hover.
/* Carousel auto-scroll */
@keyframes carousel {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
.carousel-track {
animation: carousel 20s linear infinite;
}
.carousel-track:hover {
animation-play-state: paused;
}Hover Transitions
Consistent hover timing across components.
Motion Patterns
Framer Motion Easing
Standardized easing curves for consistent motion across the app.
smooth
[0.25, 0.46, 0.45, 0.94]Page transitions, stagger animations
spring
stiffness: 300, damping: 30Modal entrance, banner appearance
tween
type: "tween", duration: 0.4Page transitions
// easing constants
export const EASING = {
smooth: [0.25, 0.46, 0.45, 0.94],
spring: { stiffness: 300, damping: 30 },
tween: { type: 'tween', duration: 0.4 },
};
// Usage
<motion.div
transition={{ ease: EASING.smooth, duration: 0.5 }}
>
<motion.div
transition={{ type: 'spring', ...EASING.spring }}
>PageTransition Component
Wrapper for smooth page transitions using AnimatePresence.
'use client';
import { motion, AnimatePresence } from 'framer-motion';
import { usePathname } from 'next/navigation';
const pageVariants = {
initial: { opacity: 0, y: 20 },
animate: {
opacity: 1,
y: 0,
transition: {
duration: 0.4,
ease: [0.25, 0.46, 0.45, 0.94]
}
},
exit: {
opacity: 0,
y: -20,
transition: { duration: 0.3 }
}
};
export function PageTransition({ children }) {
const pathname = usePathname();
return (
<AnimatePresence mode="wait">
<motion.div
key={pathname}
variants={pageVariants}
initial="initial"
animate="animate"
exit="exit"
>
{children}
</motion.div>
</AnimatePresence>
);
}FadeIn Scroll Animation
Elements fade in when they enter the viewport using whileInView.
'use client';
import { motion } from 'framer-motion';
interface FadeInProps {
children: React.ReactNode;
delay?: number;
direction?: 'up' | 'down' | 'left' | 'right';
}
export function FadeIn({
children,
delay = 0,
direction = 'up'
}: FadeInProps) {
const directionOffset = {
up: { y: 20 },
down: { y: -20 },
left: { x: 20 },
right: { x: -20 },
};
return (
<motion.div
initial={{
opacity: 0,
...directionOffset[direction]
}}
whileInView={{
opacity: 1,
x: 0,
y: 0
}}
viewport={{ once: true, margin: '-50px' }}
transition={{
duration: 0.5,
delay,
ease: [0.25, 0.46, 0.45, 0.94]
}}
>
{children}
</motion.div>
);
}StaggerContainer Pattern
Parent container that staggers child animations.
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.2,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
ease: [0.25, 0.46, 0.45, 0.94]
}
},
};
// Usage
<motion.div
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
{items.map((item) => (
<motion.div key={item.id} variants={itemVariants}>
{item.content}
</motion.div>
))}
</motion.div>Spring Configurations
Physics-based spring animations for natural motion.
Modal Entrance
transition: {
type: 'spring',
stiffness: 300,
damping: 30
}Bouncy Elements
transition: {
type: 'spring',
stiffness: 400,
damping: 10
}CSS Animations (Tailwind)
Tailwind keyframe animations for simple effects.
Floating CTA Patterns
MobileBottomCTA
Sticky bottom CTA that appears after scrolling past the header. Uses safe-area-inset for notched devices.
/* MobileBottomCTA styling */
.mobile-bottom-cta {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 50;
background: rgba(38, 38, 38, 0.95);
backdrop-filter: blur(16px);
border-top: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px 24px 0 0;
padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom));
}
/* Show/hide based on scroll */
const [showCTA, setShowCTA] = useState(false);
useEffect(() => {
const handleScroll = () => {
// Show after scrolling past header
setShowCTA(window.scrollY > 500);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);CookieConsent
Floating cookie consent banner with glassmorphic styling.
We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies.
/* CookieConsent styling */
.cookie-consent {
position: fixed;
bottom: 1rem;
left: 1rem;
right: 1rem;
max-width: 450px;
z-index: 50;
border-radius: 16px;
padding: 1.5rem;
background: rgba(38, 38, 38, 0.95);
backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
@media (min-width: 768px) {
.cookie-consent {
left: auto;
}
}Safe Area Handling
Bottom padding accounts for device safe areas (notch, home indicator).
/* Safe area padding */
.floating-cta {
padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}
/* Tailwind */
className="pb-[calc(1rem+env(safe-area-inset-bottom))]"
/* Or using custom property */
:root {
--safe-area-bottom: env(safe-area-inset-bottom, 0px);
}
.floating-cta {
padding-bottom: calc(1rem + var(--safe-area-bottom));
}Z-Index Layering
Floating elements layer below modals but above content.
Visibility Logic
Floating CTAs have conditional visibility based on scroll position.
// MobileBottomCTA visibility
const [showMobileCTA, setShowMobileCTA] = useState(false);
useEffect(() => {
const handleScroll = () => {
// Only show on mobile, after scrolling past hero
const isMobile = window.innerWidth < 768;
const scrolledPastHero = window.scrollY > 500;
setShowMobileCTA(isMobile && scrolledPastHero);
};
window.addEventListener('scroll', handleScroll);
window.addEventListener('resize', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
window.removeEventListener('resize', handleScroll);
};
}, []);
// CookieConsent visibility
const [showCookie, setShowCookie] = useState(false);
useEffect(() => {
const consent = localStorage.getItem('cookieConsent');
if (!consent) {
// Delay showing for better UX
setTimeout(() => setShowCookie(true), 1500);
}
}, []);Icon Patterns
Gradient Stroke Icons
SVG icons with gradient strokes using inline SVG defs.
/* SVG with gradient stroke */
<svg viewBox="0 0 56 56" fill="none">
<path
stroke="url(#iconGradient)"
stroke-width="1.5"
stroke-linecap="round"
d="..."
/>
<defs>
<linearGradient
id="iconGradient"
x1="7" y1="7" x2="49" y2="49"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#0049E7"/>
<stop offset="1" stop-color="#47EBE0"/>
</linearGradient>
</defs>
</svg>Hover State Icon Switching
Icons switch from gradient to solid white on hover within feature cards.
/* Icon hover switching */
.feature-card:hover .icon path {
stroke: #ffffff;
}
/* React implementation */
<path
stroke={isHovered ? '#ffffff' : 'url(#iconGradient)'}
className="transition-colors duration-500"
...
/>Icon Sizes
Standard icon sizes used across the application.
Dollar Icon Asset
Available in gradient and dark variants at assets/icons/
dollar-icon.svgGradient version for dark backgrounds
dollar-icon-dark.svgDark solid version for light backgrounds
Calculator Patterns
ROI Calculator
Interactive calculator with glassmorphic container and selection cards.
Calculate Your Network Value
Selection Card States
Interactive selection cards with clear visual feedback.
/* Selection card tokens */
component.roiCalculator.scenarioCard: {
borderRadius: "12px",
borderDefault: "2px solid rgba(255, 255, 255, 0.1)",
borderSelected: "2px solid #47EBE0",
backgroundSelected: "rgba(71, 235, 224, 0.1)"
}
/* Tailwind implementation */
<button className={cn(
"p-4 rounded-xl border-2 transition-all",
isSelected
? "border-pairty-teal bg-[rgba(71,235,224,0.1)]"
: "border-[rgba(255,255,255,0.1)] bg-[rgba(255,255,255,0.05)]"
)}>
...
</button>Value Display Formatting
Large numerical values use gradient text for emphasis.
/* Network worth gradient text */
.value-display {
background: linear-gradient(90deg, #47EBE0 0%, #249AE3 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 2.25rem;
font-weight: 700;
}
/* Gradient token */
gradient.text.networkWorth: "linear-gradient(90deg, #47EBE0 0%, #249AE3 100%)"Calculator Container
Glassmorphic container styling for calculator widgets.
/* Calculator container tokens */
component.roiCalculator: {
borderRadius: "24px",
background: "rgba(255, 255, 255, 0.05)",
border: "1px solid rgba(255, 255, 255, 0.1)"
}
/* CSS */
.calculator-container {
border-radius: 24px;
padding: 2rem;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.1);
}Components & Assets
Reusable components, logos, and mobile patterns.
Components
DaisyUI components styled with Pairty brand tokens, plus landing page patterns.
Landing Page Components
See dedicated pattern sections for detailed documentation:
Buttons
Landing Page CTA Style:
Button Token Values
- • Min height:
44px(touch target) - • Padding X:
1.5rem - • Padding Y:
1rem - • Border radius:
0.5rem(DaisyUI) /0.75rem(Landing)
Cards
Basic Card
Card content goes here with proper spacing.
Image Card
Card with gradient header.
Glassmorphic Card
Landing page feature card style with blur effect.
Form Elements
Landing Page Input Style:
Input Token Values
- • Height:
44px(prevents iOS zoom) - • Font size:
16px - • Focus ring:
2px solid #47EBE0
Badges & Alerts
Landing Page Section Badge:
✨ FeaturesComponent Tokens
// components.json (selected tokens)
{
"button": {
"paddingX": "1.5rem",
"paddingY": "1rem",
"borderRadius": "0.5rem",
"minHeight": "44px",
"shimmer": {
"gradient": "linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent)",
"animation": "shimmer 2s linear infinite"
}
},
"featureCard": {
"padding": "2rem",
"borderRadius": "24px",
"background": { "default": "rgba(12, 24, 41, 0.9)" },
"backdropBlur": "25px",
"border": { "default": "1px solid rgba(30, 58, 95, 0.6)" }
},
"sectionBadge": {
"paddingX": "1rem",
"paddingY": "0.5rem",
"borderRadius": "9999px",
"background": "rgba(255, 255, 255, 0.05)",
"textColor": "#47EBE0"
}
}Logo & Branding
Logo variants, clearspace rules, and app icon specifications.
Brand Symbol
The Pairty™ symbol features the stylized P letterform with gradient arc motif, representing the connection between people.
Logo Variants
Horizontal Dark
For dark backgrounds
horizontal-dark.svg
Horizontal Light
For light backgrounds
horizontal-light.svg
Vertical Dark
Square layouts, splash screens
vertical-dark.svg
Vertical Light
Light square layouts
vertical-light.svg
Symbol Only
App icons, favicons
symbol-only.svg
Clearspace Rules
Maintain clearspace equal to the logo stroke width on all sides.
Color Usage
Symbol: Always uses brand gradient
Wordmark: Off White (#EAEAEC) on dark, Charcoal (#262626) on light
App Icon Sizes
16x16
Web favicon
32x32
Web favicon
180x180
Apple touch icon
192x192
Android/PWA
512x512
PWA, Play Store
1024x1024
iOS App Store
Logo Don'ts
Don't blur or distort
Don't change colors
Don't rotate logo
Asset Files
| File | Format | Usage |
|---|---|---|
| horizontal-dark.svg | SVG | Web, dark backgrounds |
| horizontal-light.svg | SVG | Web, light backgrounds |
| symbol-only.svg | SVG | Icons, favicons |
| app-icon-*.png | PNG | App stores, PWA |
Logo Usage
Logo Variants
Three logo variants available for different contexts.
variant="full"variant="symbol"variant="text"Theme Variants
Logo adapts to light and dark backgrounds.
theme="dark"theme="light"Default Dimensions
Standard logo sizing for different contexts.
120px100px32px48pxClear Space
Minimum padding around logo equal to the height of the symbol.
Usage Examples
Common logo placement patterns.
© 2025 Pairty. All rights reserved.
Logo Component
interface LogoProps {
variant?: 'full' | 'symbol' | 'text';
theme?: 'light' | 'dark';
className?: string;
}
export function Logo({
variant = 'full',
theme = 'dark',
className
}: LogoProps) {
const textColor = theme === 'dark' ? 'text-white' : 'text-pairty-charcoal';
return (
<div className={cn('flex items-center gap-2', className)}>
{variant !== 'text' && (
<div className="w-10 h-10 rounded-lg bg-gradient-to-br from-pairty-blue to-pairty-teal" />
)}
{variant !== 'symbol' && (
<span className={cn('text-2xl font-bold', textColor)}>
Pairty
</span>
)}
</div>
);
}Logo Don'ts
Mobile Patterns
Platform-specific patterns and tokens for React Native mobile apps.
Bottom Navigation
Token Values
- Background:
rgba(0, 0, 0, 0.95) - Active:
#0049E7(brand blue) - Inactive:
rgba(255, 255, 255, 0.6) - Border radius:
20px(top corners) - Padding:
12px vertical, 20px horizontal
⚠️ Current Inconsistency
Mobile app uses iOS system blue #007AFF instead of brand blue #0049E7. This should be updated for brand consistency.
Touch Targets
Minimum
44×44px
Comfortable
48×48px
Large
56×56px
WCAG 2.2 Success Criterion 2.5.8: Target size minimum of 24×24 CSS pixels, with 44×44px recommended for mobile touch interfaces.
Safe Areas
iOS Safe Areas
Android Safe Areas
Mobile Typography
| Token | Web (rem) | Mobile (px) | Usage |
|---|---|---|---|
| xs | 0.75rem | 12px | Labels, metadata |
| sm | 0.875rem | 14px | Captions, secondary text |
| base | 1rem | 16px | Body text, inputs |
| lg | 1.125rem | 18px | Emphasized body |
| xl | 1.25rem | 20px | Section headings |
Input font size: Use 16px minimum for inputs on mobile to prevent iOS Safari zoom.
Mobile Dark Background
linear-gradient(135deg, #111122, #121220, #101020)
#262626 (Brand Standard)
React Native Usage
// Import tokens
import { colors, spacing, mobile } from '@pairty/design-tokens';
// StyleSheet example
const styles = StyleSheet.create({
container: {
padding: spacing[4], // 16px
backgroundColor: colors.background.dark,
},
button: {
minHeight: mobile.touchTarget.min, // 44px
backgroundColor: colors.brand.primary,
borderRadius: spacing[2], // 8px
},
bottomNav: {
backgroundColor: mobile.bottomNav.background,
borderTopLeftRadius: mobile.bottomNav.borderRadius,
borderTopRightRadius: mobile.bottomNav.borderRadius,
paddingBottom: Platform.select({
ios: mobile.safeArea.bottom.ios,
android: mobile.safeArea.bottom.android,
}),
},
activeTab: {
color: colors.brand.primary, // Use #0049E7, not #007AFF
},
inactiveTab: {
color: mobile.bottomNav.inactiveColor,
},
});Utilities & Accessibility
CSS utilities, accessibility patterns, and guidelines.
Utility Classes
.glass Utility
Quick glassmorphism effect for overlays and cards.
.glass {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.1);
}Glow Utilities
Box shadow utilities for glow effects.
.glow-teal {
box-shadow: 0 0 30px rgba(71, 235, 224, 0.25);
}
.glow-teal-strong {
box-shadow: 0 0 40px rgba(71, 235, 224, 0.3);
}
.glow-blue {
box-shadow: 0 0 25px rgba(0, 73, 231, 0.2);
}
.glow-blue-strong {
box-shadow: 0 0 40px rgba(0, 73, 231, 0.3);
}.gradient-border Utility
Creates gradient borders using background-clip technique.
.gradient-border {
background:
linear-gradient(#0c1829, #0c1829) padding-box,
linear-gradient(to bottom, #1e3a5f, #0a1628) border-box;
border: 1px solid transparent;
}Text Selection
Brand-colored text selection for consistent experience.
This text simulates selection - try selecting other text to see the effect.
::selection {
background-color: rgba(71, 235, 224, 0.3);
color: #ffffff;
}
::-moz-selection {
background-color: rgba(71, 235, 224, 0.3);
color: #ffffff;
}Focus Ring
Accessible focus indicators using brand teal color.
:focus-visible {
outline: 2px solid #47EBE0;
outline-offset: 2px;
}
/* Tailwind */
focus-visible:ring-2 focus-visible:ring-pairty-teal focus-visible:ring-offset-2Reduced Motion
Respect user preferences for reduced motion.
/* Global reduced motion support */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* Tailwind variant */
motion-reduce:transition-none
motion-reduce:animate-none.text-gradient Utility
Gradient text effect for headings and emphasis.
Gradient Text Example
.text-gradient {
background: linear-gradient(to right, #47EBE0, #0049E7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Tailwind */
bg-gradient-to-r from-pairty-teal to-pairty-blue bg-clip-text text-transparentAccessibility
Color contrast ratios, focus states, and accessibility guidelines.
Color Contrast Ratios
| Combination | Preview | Ratio | WCAG Level |
|---|---|---|---|
| Charcoal on Off White | Sample | 12.6:1 | AAA |
| Pairty Blue on Off White | Sample | 7.2:1 | AAA |
| Off White on Charcoal | Sample | 12.6:1 | AAA |
| Pairty Teal on Charcoal | Sample | 8.4:1 | AAA |
| Bright Blue on Off White | Sample | 3.2:1 | AA Large |
| Pairty Teal on Off White | Sample | 1.4:1 | Fail |
WCAG Guidelines
- Level AA: 4.5:1 for normal text, 3:1 for large text
- Level AAA: 7:1 for normal text, 4.5:1 for large text
- Large text: 18pt+ or 14pt+ bold
Focus States
Focus Token Values
- Color:
#47EBE0(Pairty Teal) - Width:
2px - Style:
solid - Offset:
2px
Touch Targets
24×24px
WCAG Minimum
44×44px
Recommended
48×48px
Material Design
Pairty Standard: All interactive elements must have a minimum touch target of44×44px on mobile devices.
Reduced Motion
Respect user preferences for reduced motion using the prefers-reduced-motion media query.
/* CSS */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* React Native */
import { AccessibilityInfo } from 'react-native';
const [reduceMotion, setReduceMotion] = useState(false);
useEffect(() => {
AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion);
}, []);Color Blindness Considerations
Do
- ✓Use icons with color indicators
- ✓Add text labels to color-coded elements
- ✓Use patterns in addition to colors
- ✓Ensure sufficient contrast
Don't
- ✗Rely on color alone to convey meaning
- ✗Use red/green as the only differentiator
- ✗Use low contrast color combinations
Screen Reader Guidelines
Web (ARIA)
<button aria-label="Close dialog" aria-pressed="false" > <CloseIcon /> </button> <img src="logo.svg" alt="Pairty logo" /> <nav aria-label="Main navigation"> ... </nav>
React Native
<TouchableOpacity
accessible={true}
accessibilityLabel="Close dialog"
accessibilityRole="button"
>
<CloseIcon />
</TouchableOpacity>
<Image
source={logo}
accessibilityLabel="Pairty logo"
/>Accessibility Patterns
Reduced Motion Support
Respect user preferences for reduced motion with CSS media query.
Default Motion
Reduced Motion
Animation disabled
/* Global reduced motion support */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* Framer Motion hook */
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
animate={{ x: 100 }}
transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.5 }}
/>
);
}
/* Token reference */
effects.reducedMotion: {
duration: "0.01ms",
iterations: "1"
}Focus Ring Styling
Visible focus indicators using brand teal color for keyboard navigation.
/* Focus ring styling */
:focus-visible {
outline: 2px solid #47EBE0;
outline-offset: 2px;
}
/* Remove default focus, add custom */
button:focus {
outline: none;
}
button:focus-visible {
outline: 2px solid #47EBE0;
outline-offset: 2px;
}
/* Token reference */
effects.focus: {
ring: "2px solid #47EBE0",
offset: "2px"
}Text Selection
Brand-colored text selection for consistent visual experience.
Try selecting this text to see the custom selection color. The selection uses our brand teal color at 30% opacity with white text.
This simulates the selection appearance
/* Custom text selection */
::selection {
background-color: rgba(71, 235, 224, 0.3);
color: #ffffff;
}
::-moz-selection {
background-color: rgba(71, 235, 224, 0.3);
color: #ffffff;
}
/* Token reference */
color.selection: {
background: "rgba(71, 235, 224, 0.3)",
text: "#ffffff"
}Touch Target Minimums
WCAG 2.2 requires minimum 44x44px touch targets for mobile accessibility.
/* Touch target tokens */
mobile.touchTarget: {
min: 44, // WCAG 2.2 minimum
comfortable: 48, // Better for mobile
large: 56 // Primary actions
}
/* Ensure minimum size */
.interactive-element {
min-width: 44px;
min-height: 44px;
}Color Contrast
Text colors maintain WCAG AA contrast ratios against backgrounds.
Common ARIA Patterns
Semantic ARIA attributes used throughout the application.
/* Modal dialog */
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
<h2 id="modal-title">Modal Title</h2>
</div>
/* Accordion */
<button
aria-expanded={isOpen}
aria-controls="accordion-content"
>
Toggle
</button>
<div id="accordion-content" hidden={!isOpen}>
Content
</div>
/* Navigation */
<nav aria-label="Main navigation">
<a href="#" aria-current={isActive ? 'page' : undefined}>
Link
</a>
</nav>
/* Live region for dynamic content */
<div aria-live="polite" aria-atomic="true">
{statusMessage}
</div>
/* Loading states */
<button aria-busy={isLoading} disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>