Skip to main content
Crave storefront templates are built with Tailwind CSS and shadcn/ui. You customize the look by editing CSS variables and Tailwind config — no proprietary theming API to learn.

How theming works

Every template ships with a globals.css file that defines CSS custom properties. Tailwind maps these variables to utility classes, and all Crave components use those classes. Change a variable, and every component updates.
@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 240 10% 3.9%;
    --primary: 160 50% 22%;        /* your brand color */
    --primary-foreground: 0 0% 98%;
    --accent: 160 30% 96%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 240 10% 3.9%;
    --foreground: 0 0% 98%;
    --primary: 160 50% 40%;
    --primary-foreground: 0 0% 98%;
  }
}

Change brand colors

Update the --primary variable to match your brand. Use HSL values (hue, saturation, lightness):
:root {
  --primary: 210 100% 50%;          /* blue brand */
  --primary-foreground: 0 0% 100%;  /* white text on primary */
}
All buttons, links, active states, and accent elements update automatically.
Use the shadcn/ui theme generator to preview color combinations and copy the CSS variables.

Customize fonts

Templates use next/font for self-hosted fonts with zero layout shift. Update the font in layout.tsx:
import { Inter } from 'next/font/google';
// or use a local font:
// import localFont from 'next/font/local';

const font = Inter({ subsets: ['latin'] });

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className={font.className}>{children}</body>
    </html>
  );
}
For local font files (.woff, .woff2):
import localFont from 'next/font/local';

const brandFont = localFont({
  src: './fonts/BrandFont-Regular.woff2',
  variable: '--font-brand',
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className={brandFont.variable}>{children}</body>
    </html>
  );
}
Then reference the variable in your Tailwind config:
export default {
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-brand)', 'system-ui', 'sans-serif'],
      },
    },
  },
};

Customize component styles

Crave components use Tailwind utility classes with shadcn/ui’s cn() helper. Override styles by passing className:
<CartPanel className="rounded-none border-0 shadow-2xl" />
<CategoryTabs className="gap-1 bg-zinc-100 p-1 rounded-full" />
For deeper customization, edit the component source directly. All components live in your project’s src/components/ directory — they are not locked in a package.

Border radius

Control the roundness of all components with the --radius variable:
:root {
  --radius: 0.75rem;  /* more rounded */
  /* --radius: 0rem;  /* sharp corners */
}

Dark mode

Templates support dark mode out of the box using Tailwind’s dark: variant. Toggle dark mode by adding the dark class to the <html> element:
// Toggle dark mode
document.documentElement.classList.toggle('dark');
For Next.js apps, use next-themes for automatic system preference detection:
'use client';

import { ThemeProvider } from 'next-themes';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
      {children}
    </ThemeProvider>
  );
}

Restaurant branding

Load the restaurant’s branding dynamically from the API:
const merchant = await storefront.merchant.getBySlug('downtown-pizza');

// Use merchant data for dynamic theming
<img src={merchant.logo} alt={merchant.name} />
<div style={{ backgroundImage: `url(${merchant.cover})` }} />
Each merchant location also exposes restaurantLogo and coverPhoto for location-specific branding.

Next steps