Skip to Content
StatixFlow Next Docs
Styling & Theming

Styling & Theming

No tailwind.config.*

The template uses Tailwind CSS v4, configured entirely in CSS — there is no tailwind.config.js/.ts file. Everything starts from app/globals.css:

app/globals.css
@import "tailwindcss"; @plugin "@tailwindcss/typography";

Design tokens

Brand/semantic colors are defined as CSS custom properties under :root, then re-exposed to Tailwind’s utility classes via an @theme inline block:

app/globals.css
:root { --background: var(--color-slate-50); --foreground: oklch(0.1445 0.0148 121.37); --primary: var(--color-neutral-900); --primary-foreground: var(--color-white); --secondary: var(--color-blue-800); --secondary-foreground: var(--color-blue-50); --status-success: oklch(0.93 0.07 180.27); --status-success-foreground: var(--color-teal-600); /* ...status-info, status-warning, status-destructive follow the same pattern */ --muted: var(--color-gray-200); --muted-foreground: oklch(0.53 0.03 251.66); --accent: var(--color-violet-100); --accent-foreground: var(--color-violet-700); --border: oklch(0.9097 0 0); } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); /* ...and so on for every token above */ }

That @theme inline block is what makes bg-primary, text-secondary-foreground, bg-status-success, etc. available as ordinary Tailwind utility classes.

To reskin the template’s brand colors, edit the :root custom properties — not the @theme inline block, and not individual component files. Changing --primary and --secondary propagates everywhere those tokens are used. Prefer extending/reusing these tokens over introducing raw color values (bg-[#123456]) in components.

There’s a separate @theme block (not inline) for typography:

@theme { --font-sans: var(--font-instrument-sans), sans-serif; }

--font-instrument-sans is set by next/font/google’s Instrument_Sans loader in app/layout.tsx — swap the font there if you need a different typeface, then update this token to match.

cn() — merging conditional classNames

lib/cn.ts wraps clsx + tailwind-merge:

lib/cn.ts
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }

This is the standard way to combine static classes with conditional ones anywhere in the codebase — clsx handles the conditional logic, twMerge resolves conflicting Tailwind classes (e.g. a later bg-primary correctly overriding an earlier bg-white) so you don’t get both applied. Use it instead of template-literal string concatenation whenever a component’s className depends on props or state.

<div className={cn("rounded-full px-4 py-2", isActive && "bg-primary text-primary-foreground")} />

Other CSS conventions worth knowing

  • @layer utilities in globals.css holds one-off utility classes used by specific components (striped backgrounds, marquee/ping keyframes) — check there before adding a new bespoke utility class of your own.
  • @layer components holds small overrides for third-party CSS (Swiper pagination bullets) and a couple of structural fixes (GSAP SplitText descender clipping).
  • Swiper’s CSS is imported directly in globals.css (swiper/css, swiper/css/pagination, swiper/css/mousewheel) since swiper is used for carousels/sliders.
Last updated on