Library

React · Next.js

Add Sitka to an existing Next.js project. Components are copied directly into your codebase — no npm package, no version lock-in.

Prerequisites

Your project needs these peer dependencies. Install any that are missing:

bash
npm install clsx tailwind-merge framer-motion lucide-react @fontsource/inter

React

19+

Next.js

16+

Tailwind CSS

4+

TypeScript

5+

1

Add CSS variables

Copy the token variables block into your global stylesheet (or a new sitka.css that you import in layout.tsx).

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

/* ── Sitka tokens — dark (default) ───────────────── */
:root {
  --background:      9   9  12;
  --surface:        13  13  17;
  --surface-raised: 22  22  28;
  --surface-hover:  32  32  40;

  --accent:         0 192 232;
  --accent-hover:   0 160 200;
  --accent-subtle:  0  38  46;
  --accent-muted:   0  72  86;

  --text-primary:   242 242 246;
  --text-secondary: 155 155 170;
  --text-tertiary:  100 100 115;

  --border:          38  38  48;
  --border-subtle:   26  26  33;

  --radius-sm:  4px;
  --radius:     6px;
  --radius-md:  10px;
  --radius-lg:  16px;
}

/* ── Sitka tokens — light ─────────────────────────── */
[data-theme="light"] {
  --background:      250 250 250;
  --surface:         255 255 255;
  --surface-raised:  246 246 248;
  --surface-hover:   240 240 244;

  --accent:          0 192 232;
  --accent-subtle:   224 247 252;
  --accent-muted:    179 237 249;

  --text-primary:    40  40  40;
  --text-secondary:  116 116 116;
  --text-tertiary:   167 167 172;

  --border:          224 224 231;
  --border-subtle:   240 240 244;
}

/* ── Glass surface ────────────────────────────────── */
.glass {
  background-color: rgb(var(--surface) / 0.92);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgb(var(--border));
}
2

Extend Tailwind config

Merge the Sitka theme extension into your existing tailwind.config.ts:

tailwind.config.ts
ts
import type { Config } from "tailwindcss";

const config: Config = {
  content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
  theme: {
    extend: {
      fontFamily: {
        sans: ["var(--font-inter)", "Inter", "system-ui", "sans-serif"],
        mono: ["var(--font-mono)", "JetBrains Mono", "monospace"],
      },
      colors: {
        sitka: {
          cyan: "#00C0E8",
          50: "#f0faf4",  100: "#dcf5e7", 200: "#b9eace",
          300: "#84d4a8", 400: "#4dba82", 500: "#34a865",
          600: "#289452", 700: "#1f7341", 800: "#165733",
          900: "#0f3d24", 950: "#071f12",
        },
      },
      boxShadow: {
        glass: "0 0 0 1px rgba(255,255,255,0.08), 0 8px 32px rgba(0,0,0,0.12)",
        glow:  "0 0 0 1px rgba(0,192,232,0.3), 0 0 20px rgba(0,192,232,0.15)",
        soft:  "0 1px 3px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.06)",
      },
      transitionTimingFunction: {
        spring: "cubic-bezier(0.16, 1, 0.3, 1)",
      },
    },
  },
};

export default config;
3

Add the cn helper

All components use this tiny utility to merge Tailwind classes:

lib/cn.ts
ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

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

Copy components

Each component is a self-contained file in src/components/ui/. Copy whichever ones you need into your project's component directory and import them:

app/page.tsx
tsx
import { Button } from "@/components/ui/Button";
import { Badge }  from "@/components/ui/Badge";
import { Input }  from "@/components/ui/Input";

export default function Page() {
  return (
    <div className="flex flex-col gap-4 p-8">
      <Badge variant="success">Active</Badge>
      <Input placeholder="Search…" />
      <Button variant="primary" size="lg">
        Get Started
      </Button>
    </div>
  );
}
5

Load Inter font

Sitka uses Inter as its primary typeface. Load it via next/font in your root layout:

app/layout.tsx
tsx
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({
  subsets: ["latin"],
  variable: "--font-inter",
  display: "swap",
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={inter.variable}>
      <body>{children}</body>
    </html>
  );
}

Dark / Light mode

Sitka is dark-first. Toggle light mode by setting data-theme="light" on <html>:

ts
// anywhere in your client code
document.documentElement.setAttribute("data-theme", "light");
// reset to dark
document.documentElement.removeAttribute("data-theme");

Next steps

  • Browse the Component docs for props and copy-paste examples.
  • Download the full token JSON for automated generation pipelines.
  • Check the Motion guide for Framer Motion spring presets.