BOOTH // NEXT

Setup Guide

One-time setup for using BOOTH // NEXT components. Add these to your project, then copy any component from the theme.

1
Install dependencies

The cn() utility combines clsx and tailwind-merge for conditional class names. Install both packages.

BASH
npm install clsx tailwind-merge
2
Add utility function

Create lib/utils.ts with the cn() helper. Every component imports this for class name merging.

TS
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]): string {
  return twMerge(clsx(inputs))
}
3
Add design tokens

Add the BOOTH // NEXT design tokens to your globals.css. These define colors, fonts, and animation tokens used by every component in the theme.

CSS
@theme {
  /* ── Colors ─────────────────────────────────────────── */
  --color-booth-ivory:         #F7F0E0;
  --color-booth-ivory-alt:     #EEE5CE;
  --color-booth-ivory-deep:    #E4D8BB;
  --color-booth-red:           #C8203A;
  --color-booth-red-dark:      #A01830;
  --color-booth-red-light:     #E8364F;
  --color-booth-teal:          #1E8A82;
  --color-booth-teal-dark:     #156860;
  --color-booth-teal-light:    #2AADA3;
  --color-booth-ink:           #1C1207;
  --color-booth-ink-mid:       #3D2E18;
  --color-booth-ink-muted:     #7A6A50;
  --color-booth-chrome:        #C4B89A;
  --color-booth-chrome-light:  #DDD3BC;
  --color-booth-white:         #FDFAF3;
  --color-booth-text:          #1C1207;
  --color-booth-text-muted:    #7A6A50;

  /* ── Fonts ──────────────────────────────────────────── */
  --font-display: 'Righteous', sans-serif;
  --font-body:    var(--font-dm-sans);
  --font-mono:    var(--font-dm-mono);

  /* ── Animations ─────────────────────────────────────── */
  --animate-float:       booth-float 4s ease-in-out infinite;
  --animate-pulse-dot:   booth-pulse-dot 2.5s ease-in-out infinite;
}
4
Add component styles

Each component may need its own CSS classes in your globals.css. Copy the styles for the components you use.

CSS
/* ─── Buttons ────────────────────────────────────────── */

.btn-base {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             8px;
  font-family:     var(--font-body);
  font-weight:     600;
  border:          2px solid transparent;
  border-radius:   999px;
  cursor:          pointer;
  text-decoration: none;
  line-height:     1;
  transition:      background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
  white-space:     nowrap;
}

.btn-base:hover  { transform: translateY(-1px); text-decoration: none; }

.btn-base:active { transform: translateY(1px); }

.btn-sm { font-size: 13px; padding: 7px 16px; }

.btn-md { font-size: 15px; padding: 11px 22px; }

.btn-lg { font-size: 15px; padding: 14px 32px; }

.btn-primary {
  background:   var(--color-booth-red);
  color:        var(--color-booth-white);
  border-color: var(--color-booth-red);
}

.btn-primary:hover {
  background:   var(--color-booth-red-light);
  border-color: var(--color-booth-red-light);
  color:        var(--color-booth-white);
}

.btn-secondary {
  background:   rgba(30, 138, 130, 0.15);
  color:        var(--color-booth-teal-light);
  border-color: rgba(30, 138, 130, 0.35);
}

.btn-secondary:hover {
  background:   rgba(30, 138, 130, 0.25);
  border-color: rgba(30, 138, 130, 0.5);
  color:        var(--color-booth-teal-light);
}

.btn-ghost {
  background:   transparent;
  color:        var(--color-booth-chrome-light);
  border-color: rgba(196, 184, 154, 0.35);
}

.btn-ghost:hover {
  border-color: var(--color-booth-chrome-light);
  color:        var(--color-booth-white);
}

.btn-primary--light {
  background:   var(--color-booth-red);
  color:        var(--color-booth-white);
  border-color: var(--color-booth-red);
}

.btn-primary--light:hover {
  background:   var(--color-booth-red-light);
  border-color: var(--color-booth-red-light);
}

.btn-secondary--light {
  background:   transparent;
  color:        var(--color-booth-teal-dark);
  border-color: var(--color-booth-teal);
}

.btn-secondary--light:hover {
  background:   rgba(30, 138, 130, 0.08);
  color:        var(--color-booth-teal-dark);
}

.btn-ghost--light {
  background:   transparent;
  color:        var(--color-booth-ink-mid);
  border-color: var(--color-booth-ivory-deep);
}

.btn-ghost--light:hover {
  border-color: var(--color-booth-ink-muted);
  color:        var(--color-booth-ink);
}
CSS
/* ─── Badges ─────────────────────────────────────────── */

.badge {
  display:         inline-flex;
  align-items:     center;
  gap:             4px;
  font-family:     var(--font-mono);
  font-weight:     500;
  font-size:       10px;
  letter-spacing:  0.1em;
  text-transform:  uppercase;
  padding:         3px 9px;
  border-radius:   999px;
  border:          1px solid transparent;
}

.badge--red {
  background:   rgba(200, 32, 58, 0.08);
  color:        var(--color-booth-red);
  border-color: rgba(200, 32, 58, 0.2);
}

.badge--teal {
  background:   rgba(30, 138, 130, 0.08);
  color:        var(--color-booth-teal);
  border-color: rgba(30, 138, 130, 0.2);
}

.badge--chrome {
  background:   rgba(196, 184, 154, 0.12);
  color:        var(--color-booth-ink-muted);
  border-color: rgba(196, 184, 154, 0.25);
}

.badge--ink {
  background:   rgba(28, 18, 7, 0.06);
  color:        var(--color-booth-ink-mid);
  border-color: rgba(28, 18, 7, 0.12);
}
CSS
/* ─── Text Variants ──────────────────────────────────── */

.text-body    { font-size: 14px; line-height: 1.6;  font-weight: 400; color: var(--color-booth-ink-muted); }

.text-caption { font-size: 12px; font-weight: 500;  color: var(--color-booth-ink-muted); }

.text-label   {
  font-family:    var(--font-mono);
  font-size:      10px;
  font-weight:    500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color:          rgba(196, 184, 154, 0.5);
}

.text-code    { font-family: var(--font-mono); font-size: 13px; color: var(--color-booth-teal-dark); }
CSS
/* ─── Features Section ───────────────────────────────── */

.booth-card {
  background:  var(--color-booth-white);
  padding:     36px 32px;
  display:     flex;
  flex-direction: column;
  gap:         12px;
  transition:  background 0.15s;
  position:    relative;
}

.booth-card:hover { background: #FEFCF6; }

.booth-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 3px;
  background: transparent;
  transition: background 0.15s;
}

.booth-card:hover::before { background: var(--color-booth-red); }

.card-icon-el {
  width:           44px;
  height:          44px;
  border-radius:   12px;
  background:      var(--color-booth-ivory-alt);
  border:          1px solid var(--color-booth-ivory-deep);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       20px;
  flex-shrink:     0;
}

.card-title {
  font-family:   var(--font-display);
  font-size:     18px;
  color:         var(--color-booth-ink);
  line-height:   1.2;
}

.card-description {
  font-size:   14px;
  color:       var(--color-booth-ink-muted);
  line-height: 1.6;
}
BOOTH // NEXT Components
BOOTH // NEXTUI

Button

Retro diner button with primary, secondary, and ghost variants in three sizes. Cherry red accent, bold uppercase labels. Renders as a Next.js Link when an href is provided.

BOOTH // NEXTUI

Badge

Diner-styled badge with four color variants: red, teal, chrome, and ink. Suited for category labels, tags, and status indicators.

BOOTH // NEXTUI

Text

Polymorphic text primitive with body, caption, label, and code variants. Renders as p, span, or div via the `as` prop.

BOOTH // NEXTUI

Card

Composable card with Card, CardHeader, CardBody, and CardFooter sub-components. Warm ivory surfaces with diner-styled borders.