unparty-app UI Standards
Centralized reference for fonts, colors, layouts, and code snippets. Use this doc to build consistent UI fast.
“See also:
styling-project.md(Tailwind architecture),src/app/theunpartytemplate/STYLE.md(iOS design system)”
---
Table of Contents
---
Brand Colors
Defined in src/app/constants/colors.ts.
Core Brand Palette
| Name | Hex | Usage |
|---|---|---|
unparty | #F9C22E | Signature yellow — primary brand accent, interactive highlights |
unpartyblack | #000605 | Deep black — backgrounds, cards on dark |
unpartywhite | #FFF1D6 | Warm off-white — light surface backgrounds |
champion | #E7B12E | Slightly darker yellow — secondary/hover state for brand yellow |
nextyellow | #E4C014 | Alternate yellow — active/pressed state |
Extended Palette
| Name | Hex | Character |
|---|---|---|
electricPurple | #3500D3 | Vivid purple accent |
healpurple | #884455 | Muted rose-purple |
starblack | #753062 | Deep magenta-black |
astroblack | #3D2D59 | Indigo-black |
pushblack | #371B70 | Dark purple |
unpartypurple | #29284E | Midnight purple |
pinkyblack | #6C6BB4 | Lavender-black |
electricBlue | #00FFFF | Cyan accent |
electricGreen | #00FF66 | Neon green accent |
neonYellow | #FFF700 | Pure neon yellow |
Usage in Code
// Import all colors
import { colors, palette } from '@/app/constants/colors';
// Inline style (dynamic theming)
<div style={{ color: colors.unparty }}>...</div>
// Dynamic theme color via hook
import { useTheme } from '@/app/contexts/ThemeContext';
const { colorValue } = useTheme();
<div style={{ color: colorValue }}>...</div>---
CSS Design Tokens
Defined in src/app/globals.css as CSS custom properties.
Base Colors (Light / Dark)
/* Light mode */
--background: #ededed;
--foreground: #171717;
--background-highlight: rgba(0, 0, 0, 0.1);
--text-muted: rgba(23, 23, 23, 0.8);
/* Dark mode (auto-applied via @media prefers-color-scheme: dark) */
--background: #0a0a0a;
--foreground: #ededed;
--background-highlight: rgba(255, 255, 255, 0.1);
--text-muted: rgba(237, 237, 237, 0.8);Tailwind aliases (configured in tailwind.config.ts):
// These resolve to the CSS variables above
className="bg-background text-foreground bg-background-highlight"Depth / Shadow System
Use these to create visual hierarchy — prefer CSS vars over custom box-shadow values.
--depth-raised: 0 2px 4px rgba(0, 0, 0, 0.1); /* Slightly lifted element */
--depth-elevated: 0 4px 8px rgba(0, 0, 0, 0.12); /* Hover state / card */
--depth-floating: 0 6px 12px rgba(0, 0, 0, 0.15); /* Sticky elements */
--depth-modal: 0 8px 16px rgba(0, 0, 0, 0.15); /* Modals / drawers */
--depth-overlay: 0 12px 24px rgba(0, 0, 0, 0.18); /* Dropdowns / overlays */// Usage example
<div style={{ boxShadow: 'var(--depth-elevated)' }}>...</div>Brand Shadow & Glow
--brand-shadow: 0 2px 4px rgba(249, 194, 46, 0.1);
--brand-shadow-strong: 0 4px 8px rgba(249, 194, 46, 0.15);
--brand-glow: 0 0 8px rgba(249, 194, 46, 0.2);
--brand-glow-strong: 0 0 12px rgba(249, 194, 46, 0.25);
--brand-accent: rgba(249, 194, 46, 0.1);
--brand-accent-strong: rgba(249, 194, 46, 0.15);Interactive State Tokens
--focus-ring: 0 0 0 3px rgba(249, 194, 46, 0.3);
--hover-lift: translateY(-1px);
--hover-lift-strong: translateY(-2px);
--active-press: translateY(0) scale(0.98);---
Font System
All fonts are configured in src/app/fonts.ts, tailwind.config.ts, and src/app/globals.css.
Available Font Families
| Tailwind Class | Font | CSS Variable | Character | Weights |
|---|---|---|---|---|
font-mono | System monospace | built-in | Code, data, stats | any |
font-rounded | Nunito | --font-nunito | Friendly, rounded | 200–900 |
font-brandon-grotesque | Brandon Grotesque | local .otf | Premium grotesque | 300–900 |
font-space-grotesk | Space Grotesk | --font-space-grotesk | Modern editorial | 300–700 |
font-vt323 | VT323 | --font-vt323 | Retro terminal | 400 |
font-major-mono | Major Mono Display | --font-major-mono | Display mono | 400 |
font-geist-mono-google | Geist Mono | --font-geist-mono-google | Clean mono | 100–900 |
font-datatype | Datatype | Google Fonts @import | Tech / data | 100–900 |
font-flow-rounded | Flow Rounded | Google Fonts @import | Playful cursive | 400 |
font-google-sans-code | Google Sans Code | Google Fonts @import | Code-focused | 300–800 |
“Local fonts (loaded in
src/app/layout.tsx):GeistVF.woff→--font-geist-sans,GeistMonoVF.woff→--font-geist-mono”
Font Usage Examples
// Most common: monospace for data, stats, labels
<span className="font-mono text-sm">30+</span>
// Rounded / friendly headings
<h1 className="font-rounded text-2xl font-bold">UNPARTY</h1>
// Retro / editorial accent
<span className="font-vt323 text-4xl">STATUS: LIVE</span>
// Modern editorial
<p className="font-space-grotesk text-base font-medium">Description text</p>---
Layout Patterns
Standard Page Container
The primary page pattern — used across most pages:
<div className="mx-auto w-full max-w-5xl">
<div className="flex flex-col gap-6">
{/* Page content here */}
</div>
</div>Page Container with Padding
For pages that need horizontal padding on smaller screens:
<div className="mx-auto w-full max-w-5xl px-4 sm:px-6">
<div className="flex flex-col gap-6">
{/* Page content here */}
</div>
</div>Full-Width Section with Centered Content
<main className="flex flex-col items-center gap-4 pt-2">
<div className="w-full flex flex-col gap-4 px-2 md:gap-6">
{/* Full-width content */}
</div>
</main>Max-Width Reference
| Class | Width | Best For |
|---|---|---|
max-w-sm | 24rem / 384px | Compact forms, small cards |
max-w-md | 28rem / 448px | Forms, modals |
max-w-2xl | 42rem / 672px | Narrow content, small modals |
max-w-3xl | 48rem / 768px | Article text, narrow pages |
max-w-4xl | 56rem / 896px | Articles, forms with sidebars |
max-w-5xl | 64rem / 1024px | Standard page container (most common) |
max-w-6xl | 72rem / 1152px | Wide layouts |
max-w-7xl | 80rem / 1280px | Full content wrapper inside root layout |
max-w-screen-lg | screen width | Outer layout grid (root layout.tsx) |
Two-Column Grid
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>Left</div>
<div>Right</div>
</div>Three-Column Grid (responsive)
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{items.map(item => <Card key={item.id} {...item} />)}
</div>Card / Panel
<div className="rounded-xl bg-gray-50 p-6 dark:bg-black/10">
{/* Card content */}
</div>Card with Brand Glow
<div
className="rounded-xl bg-gray-50 p-6 dark:bg-black/10"
style={{ boxShadow: 'var(--brand-glow)' }}
>
{/* Card content */}
</div>---
Typography Utilities
Text Size Scale
| Class | Size | Common Use |
|---|---|---|
text-xs | 0.75rem | Labels, metadata, timestamps |
text-sm | 0.875rem | Secondary text, captions |
text-base | 1rem | Body text |
text-lg | 1.125rem | Slightly larger body |
text-xl | 1.25rem | Small headings |
text-2xl | 1.5rem | Section headings |
text-3xl | 1.875rem | Page headings |
text-4xl | 2.25rem | Hero / large headings |
text-6xl | 3.75rem | Display / oversized headings |
Common Text Patterns
// Section label / category tag
<span className="font-mono text-xs font-bold uppercase tracking-wider opacity-60">
CATEGORY
</span>
// Stat / number
<div className="font-mono text-lg font-bold" style={{ color: colorValue }}>
42+
</div>
// Body paragraph
<p className="text-sm leading-relaxed opacity-80">
Description text goes here.
</p>
// Prominent heading
<h2 className="font-rounded text-2xl font-bold">
Section Title
</h2>
// Brand-colored inline highlight
<span className="font-bold" style={{ color: colors.unparty }}>
highlighted term
</span>
// Keyword term (uses .keyword-term CSS class from globals.css)
<span className="keyword-term">clickable term</span>---
Component Snippets
Scroll Row Section
Used to display a horizontally scrolling row with a title and optional "more" link:
import ScrollRow from '@/components/HorizontalRow';
import PageAsterisk from '@/app/components/PageAsterick';
<ScrollRow
title="SECTION TITLE"
items={[
<PageAsterisk key="asterisk" />,
// Add components here
]}
moreLink="/more"
maxItems={4}
/>Stats Component
import Stats from '@/app/components/Stats';
// Default values
<Stats />
// Custom values
<Stats waitlistCount={275} vibeMood="HIGH." priorityCategory="HIGH" className="shadow-lg" />Page with Standard Layout (full example)
import AboutComponent from '@/app/components/AboutComponent';
export default function MyPage() {
return (
<main className="flex flex-col items-center gap-4 pt-2">
<div className="mx-auto w-full max-w-5xl">
<div className="flex flex-col gap-6">
<AboutComponent />
</div>
</div>
</main>
);
}Theme-Colored Element
'use client';
import { useTheme } from '@/app/contexts/ThemeContext';
export default function MyComponent() {
const { colorValue } = useTheme();
return (
<div style={{ borderColor: colorValue, color: colorValue }}>
Dynamic themed content
</div>
);
}Responsive Section with Gap Scaling
<section className="flex flex-col gap-4 md:gap-6 lg:gap-8">
{/* Content */}
</section>---
Animation & Transitions
Transition Speed Tokens
--transition-fast: 0.15s ease; /* Button hover, micro-interactions */
--transition-standard: 0.2s ease; /* Most interactive states */
--transition-slow: 0.3s ease; /* Page transitions, modals */Custom Easing
--easing-brand: cubic-bezier(0.25, 0.46, 0.45, 0.94); /* Smooth brand motion */
--easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); /* Playful bounce */CSS Utility Classes (from globals.css)
// Scrolling banner / chyron
<div className="animate-scroll">
Scrolling text content
</div>
// Page enter animation (auto-applied inside .page-transition-wrapper)
<div className="page-transition-wrapper">
{children}
</div>Standard Hover Pattern (Tailwind)
// Lift on hover, press on active
<button className="transition-transform duration-150 hover:-translate-y-0.5 active:scale-[0.98]">
Click me
</button>---
Dark Mode
The app uses @media (prefers-color-scheme: dark) for automatic dark mode. All CSS variable tokens update automatically.
Patterns
// Background: light gray / near-black
<div className="bg-background">...</div>
// Text: dark / light
<p className="text-foreground">...</p>
// Overlay / tinted background
<div className="bg-background-highlight">...</div>
// Manual dark variant via Tailwind
<div className="bg-gray-50 dark:bg-black/10">...</div>
<p className="text-gray-900 dark:text-gray-100">...</p>---
Theme System (Dynamic Colors)
The app includes a runtime color theme system that lets users (or pages) switch the primary accent color.
Using the Theme
'use client';
import { useTheme } from '@/app/contexts/ThemeContext';
export default function ThemedCard() {
const { colorValue, colorPalette, selectedColor, setSelectedColor } = useTheme();
return (
<div style={{ borderLeft: `4px solid ${colorValue}` }}>
<p style={{ color: colorValue }}>Themed accent text</p>
</div>
);
}Available Theme Colors (palette)
// src/app/constants/colors.ts
export const palette = {
unparty: "#F9C22E", // Signature yellow (default)
unpartyblack: "#000605",
unpartywhite: "#FFF1D6",
electricPurple:"#3500D3",
neonYellow: "#FFF700",
astroblack: "#3D2D59",
pinkyblack: "#6C6BB4",
starblack: "#753062",
pushblack: "#371B70",
champion: "#E7B12E",
healpurple: "#884455",
electricGreen: "#00FF66",
electricBlue: "#00FFFF",
anotherlove: "#000108",
};Theme Persistence
The selected theme color is persisted to localStorage under the key unpartySelectedColor automatically.
---
Last updated: 2025-03-21 — See styling-project.md for Tailwind architecture details and src/app/theunpartytemplate/STYLE.md for the iOS design system.