Design Guide

Semantic classes, tokens, and examples

Color Strategy & Usage Rules

Primary Brand Color (Purple)

Primary actions, main CTAs, brand elements
  • • Primary buttons and CTAs
  • • Active navigation states
  • • Brand highlights and accents
  • • Focus states and interactive elements

Accent Color (Orange)

Highlights, warnings, special emphasis
  • • Text highlights in hero sections
  • • Warning states and alerts
  • • Special offers or promotions
  • • Error states and validation

Semantic Colors (Use Sparingly)

Success

Success messages, completed states, positive metrics

Danger

Errors, destructive actions, critical alerts

Info

Information, links, secondary actions

Warning

Caution, pending states, attention needed

⚠️ Color Usage Rules

  • Maximum 2-3 colors per page/section
  • Purple is primary - use for main actions and brand elements
  • Orange for highlights only - don't overuse
  • Semantic colors for specific states - not decorative
  • Gray scale for content - text, backgrounds, subtle elements
  • White/black for contrast - structure and hierarchy

Design Tokens

Colors

  • Brand: --brand, --brand-contrast
  • Surface: --surface, --surface-muted
  • Text: --text, --text-muted
  • Semantic: --accent, --success, --danger, --warning

Spacing

  • Base: --space-xs (4px) to --space-5xl (128px)
  • Layout: --section-gap, --component-gap
  • Utilities: .space-section, .gap-component

Layout

  • Radii: --radius-sm (4px) to --radius-card (16px)
  • Z-index: --z-dropdown to --z-toast
  • Containers: .container, .container-sm, .container-lg

Typography

  • Space Grotesk: All headings (h1-h6)
  • DM Sans: Body text and UI elements
  • Azeret Mono: KPIs and metrics
  • Responsive: .text-responsive-* utilities

Best Practices & Guidelines

✅ Modern NeoPop Do's

  • Use semantic classes (.btn, .card, .chip-*)
  • Apply modern hover effects (.modern-lift, .modern-glow)
  • Use NeoPop effects sparingly (.btn-neopop, .card-neopop)
  • Keep rounded elements for comfort (chips, cards)
  • Use sharp elements for emphasis (buttons, highlights)
  • Include focus states (.focus-ring, .focus-visible)

❌ Modern NeoPop Don'ts

  • Don't overuse NeoPop effects (too harsh)
  • Don't make everything sharp (uncomfortable)
  • Don't ignore accessibility (motion, contrast)
  • Don't use raw color classes (bg-red-500)
  • Don't skip responsive design
  • Don't create inconsistent hover patterns

Component Structure Guidelines

🏗️ Standard Component Pattern

All components should follow the section + container pattern for consistency and flexibility.

✅ Recommended Structure:

// Option 1: Using SectionWrapper (Recommended)
import { SectionWrapper } from "../section-wrapper";

export default function MyComponent({ children, className = "" }) {
  return (
    <SectionWrapper className={className}>
      {/* Component content */}
      {children}
    </SectionWrapper>
  );
}

// Option 2: Manual structure
export default function MyComponent({ children, className = "" }) {
  return (
    <section className={`w-full ${className}`}>
      <div className="container">
        {/* Component content */}
        {children}
      </div>
    </section>
  );
}

🎯 Benefits:

  • Consistency: All components have the same layout structure
  • Flexibility: Components can be used in different contexts
  • Responsive: Container handles responsive padding/margins
  • Reusable: No layout coupling between parent and child

🔧 Usage Examples:

// Standard usage
<MyComponent>Content</MyComponent>

// Custom styling
<MyComponent className="bg-gray-100 py-16">Content</MyComponent>

// Full-width override
<SectionWrapper contained={false} className="bg-brand">
  <FullWidthContent />
</SectionWrapper>

// Custom container
<SectionWrapper containerClassName="max-w-4xl">
  <NarrowContent />
</SectionWrapper>

Typography

Font Strategy

Space Grotesk: All headings (h1-h6) for modern, clean typography

DM Sans: Body text, labels, and general content for readability

Azeret Mono: KPIs, metrics, and numbers for emphasis and data visualization

Headings (Space Grotesk)

Heading One

Heading Two

Heading Three

Heading Four

<h1>Heading One</h1>
<h2>Heading Two</h2>
<h3>Heading Three</h3>
<h4>Heading Four</h4>

Body Text (DM Sans)

Body paragraph using default p styling. This is the standard body text style for content.

<p>Body paragraph using default p styling.</p>

KPIs & Metrics (Azeret Mono)

99.9%
Uptime
1M+
Active Users
<div className="kpi-value">99.9%</div>
<div className="kpi-label">Uptime</div>

<div className="stat-number">1M+</div>
<div className="stat-label">Active Users</div>

Buttons

Color Variants

<button className="btn btn-purple">Primary Brand</button>
<button className="btn btn-orange">Accent</button>
<button className="btn btn-red">Red</button>
<button className="btn btn-blue">Blue</button>
<button className="btn btn-green">Green</button>
<button className="btn btn-black">Neutral</button>

Semantic State Buttons

<button className="btn btn-success">Success</button>
<button className="btn btn-danger">Danger</button>
<button className="btn btn-warning">Warning</button>
<button className="btn btn-info">Info</button>

Using the Button Component

Recommended: Use the Button component for consistency

import Button from 'components/button';

<Button 
  buttonColor="purple" 
  buttonClassNames="!px-6 !py-3"
  href="/example"
>
  Button Component
</Button>
  • Use the Button component instead of custom markup.
  • Prefer semantic sizes via utility classes on buttonClassNames (e.g., !px-6 !py-3).
  • Use buttonColor variants to map intent; avoid hard-coded colors.

Chips & Badges

Chips

NeutralPrimarySuccessDangerWarning
<span className="chip chip-neutral">Neutral</span>
<span className="chip chip-primary">Primary</span>
<span className="chip chip-success">Success</span>
<span className="chip chip-danger">Danger</span>
<span className="chip chip-warning">Warning</span>

Badges

NeutralPrimarySuccessDangerWarning
<span className="badge badge-neutral">Neutral</span>
<span className="badge badge-primary">Primary</span>
<span className="badge badge-success">Success</span>
<span className="badge badge-danger">Danger</span>
<span className="badge badge-warning">Warning</span>
  • Chips/badges should display metadata/state only. Do not use for CTAs.
  • Use group-hover:bg-brand on the parent when you need a hover accent.

Cards & Surfaces

Card Variants

Card

Base card with rounded-card and shadow-elev-1.

Hoverable

Adds translate and shadow-elev-2 on hover.

Muted Surface

For subtle sections and icon containers.

<div className="card p-6">
  <h3 className="mb-2">Card</h3>
  <p className="text-gray">Base card with rounded-card and shadow-elev-1.</p>
</div>

<div className="card card-hoverable p-6">
  <h3 className="mb-2">Hoverable</h3>
  <p className="text-gray">Adds translate and shadow-elev-2 on hover.</p>
</div>

<div className="surface-muted rounded-card p-6">
  <h3 className="mb-2">Muted Surface</h3>
  <p className="text-gray">For subtle sections and icon containers.</p>
</div>

Links & Focus

Link Variants

<a href="#" className="nav-link">Nav link</a>
<a href="#" className="nav-link focus-ring">Focusable link</a>
<a href="#" className="rl-link">Rich text link</a>

Guidelines

  • Prefer semantic classes over long Tailwind chains.
  • Add new utilities to global.css when patterns repeat.
  • Use tokens and Tailwind aliases for theme consistency.
  • Avoid component-scoped color constants.

Canonical Components (& Reuse Map)

Actions & Links

  • components/button.tsx: Primary/secondary CTAs. Use btn + color variants.
  • Nav links: nav-link + focus-ring. Do not re-style anchors.

Content Blocks

  • Cards/surfaces: card, card-hoverable, surface-muted.
  • Chips/badges: chip-*, badge-* utilities.

Rich Text

  • PortableText: use StyledPortableText or StyledPortableTextBlogs.
  • Headings/paragraphs inside rich text: rely on rl-prose-* utilities.

Navigation

  • Navbar links: navLink.tsx, navLink-with-dropdown.tsx.
  • Sticky nav: sticky-navigation.tsx with nav-link and text-brand active state.

Deprecations: Avoid creating new ad-hoc variants of buttons/cards. Prefer extending semantic utilities if a new pattern is needed.