Design SystemComponents

Components

Reusable UI patterns shared across ONCE products. Each component uses the brand color tokens and follows the dark-first design approach.

Buttons

Primary Button

Solid background with --once-blue. Used for the most important action on any screen.

<Button className="bg-once-blue hover:bg-once-blue/80 text-once-white">
  Get Started
</Button>

Outline Button

Transparent with a border. Used for secondary actions that sit alongside a primary button.

<Button
  variant="outline"
  className="border-once-blue/40 text-once-white hover:bg-once-blue/10"
>
  Learn More
</Button>

Button Pair

When two actions appear together, the primary button leads:

Cards

Cards use a translucent blue background with a subtle border. They elevate slightly on hover.

<Card className="bg-once-blue/10 border-once-blue/20">
  {/* Content */}
</Card>

Release Manager

Upload, validate, and distribute your music to all major platforms in one flow.

Card Grid

Cards arrange in a responsive grid using auto-fit with a minimum of 240px per column.

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}

Text Hierarchy

Text hierarchy on dark backgrounds is built using opacity on --once-white, not separate color values.

Primary text — 100%Secondary text — 70%Muted text — 60%Subtle text — 50%Very subtle text — 40%
LevelClassOpacityTypical use
Primarytext-once-white100%Headings, key labels
Secondarytext-once-white/7070%Body paragraphs
Mutedtext-once-white/6060%Descriptions
Subtletext-once-white/5050%Captions, timestamps
Very subtletext-once-white/4040%Decorative labels

Borders

Borders follow a three-step scale using --once-blue with opacity:

StateClassValue
Defaultborder-once-blue/20Resting card and divider borders
Hoverborder-once-blue/40Hovered cards and interactive elements
Activeborder-once-blueFocused / selected elements

Badges

Badges are pill-shaped labels used for status communication.

Early Access Badge

Animated glow effect with a pulsing dot:

Early Access

Patron Badge

Purple tint for patron-exclusive features:

Patron

Card Badges

Smaller badges that sit inside card headers:

<div className="card-header-row">
  <h3>Feature Name</h3>
  <span className="card-badge">PATRON</span>
</div>

Mobile Bottom Sheet (Slide-Up Modal)

On mobile screens, modals and dialogs use a bottom sheet pattern — the panel slides up from the bottom of the viewport and anchors there, with only the top corners rounded. On larger screens (md and above) the same modal centers in the viewport with full border-radius as usual.

This pattern is used for every modal and dialog on mobile. It keeps the content within thumb reach, feels native on phones, and avoids tiny centered panels on narrow viewports.

How it works

The technique is pure Tailwind — no JS animations required:

ConcernMobileDesktop (md:)
Alignmentitems-end (flex-end → bottom)md:items-center (centered)
Paddingp-0 (edge-to-edge)md:p-4 or md:p-6
Border-radiusrounded-t-2xl (top corners only)md:rounded-xl (all corners)
Max heightmax-h-[90vh]md:max-h-[80vh] or md:max-h-none

Example

{/* Backdrop */}
<div
  className="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm flex items-end md:items-center justify-center p-0 md:p-4"
  onClick={onClose}
>
  {/* Panel */}
  <div
    className="w-full max-w-lg bg-white rounded-t-2xl md:rounded-xl shadow-2xl border border-gray-100 flex flex-col max-h-[90vh] md:max-h-[80vh] overflow-hidden"
    onClick={(e) => e.stopPropagation()}
  >
    {/* Header */}
    <div className="flex items-center justify-between px-5 py-4 border-b border-gray-100">
      <h3 className="text-lg font-semibold">Modal Title</h3>
      <button onClick={onClose} className="p-2 rounded hover:bg-gray-100">✕</button>
    </div>
 
    {/* Scrollable content */}
    <div className="flex-1 overflow-y-auto p-5">
      {/* ... */}
    </div>
 
    {/* Footer */}
    <div className="border-t border-gray-200 bg-gray-50 px-5 py-3 flex justify-end gap-2">
      <button onClick={onClose}>Cancel</button>
      <button>Confirm</button>
    </div>
  </div>
</div>

Key classes at a glance

  • Backdrop: fixed inset-0 … flex items-end md:items-center justify-center p-0 md:p-4
  • Panel: rounded-t-2xl md:rounded-xl max-h-[90vh] md:max-h-[80vh]

On mobile the panel hugs the bottom edge with rounded top corners; on desktop it floats centered with uniform border-radius.

Status Colors

Use the utility colors for feedback states — never for decoration.

Approval—mr-approval
Warning—mr-warning
Rejection—mr-rejection