Supasheet.

Theming

Customize the look and feel of Supasheet

Overview

Supasheet uses Tailwind CSS 4 and CSS variables for theming, making it easy to customize colors, typography, and overall appearance.

Theme Configuration

Environment Variables

NEXT_PUBLIC_DEFAULT_THEME_MODE=system  # light | dark | system
NEXT_PUBLIC_THEME_COLOR=#3b82f6       # Light mode primary color
NEXT_PUBLIC_THEME_COLOR_DARK=#2563eb  # Dark mode primary color

Color System

CSS Variables

Supasheet uses OKLCH color space for better perceptual uniformity and color manipulation. Colors are defined in /styles/globals.css:

:root {
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --chart-1: var(--color-blue-300);
  --chart-2: var(--color-blue-500);
  --chart-3: var(--color-blue-600);
  --chart-4: var(--color-blue-700);
  --chart-5: var(--color-blue-800);
  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0.145 0 0);
  --sidebar-primary: oklch(0.205 0 0);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.97 0 0);
  --sidebar-accent-foreground: oklch(0.205 0 0);
  --sidebar-border: oklch(0.922 0 0);
  --sidebar-ring: oklch(0.708 0 0);
  --surface: oklch(0.98 0 0);
  --surface-foreground: var(--foreground);
  --code: var(--surface);
  --code-foreground: var(--surface-foreground);
  --code-highlight: oklch(0.96 0 0);
  --code-number: oklch(0.56 0 0);
  --selection: oklch(0.145 0 0);
  --selection-foreground: oklch(1 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.269 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.371 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
  --chart-1: var(--color-blue-300);
  --chart-2: var(--color-blue-500);
  --chart-3: var(--color-blue-600);
  --chart-4: var(--color-blue-700);
  --chart-5: var(--color-blue-800);
  --sidebar: oklch(0.205 0 0);
  --sidebar-foreground: oklch(0.985 0 0);
  --sidebar-primary: oklch(0.488 0.243 264.376);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.269 0 0);
  --sidebar-accent-foreground: oklch(0.985 0 0);
  --sidebar-border: oklch(1 0 0 / 10%);
  --sidebar-ring: oklch(0.439 0 0);
  --surface: oklch(0.2 0 0);
  --surface-foreground: oklch(0.708 0 0);
  --code: var(--surface);
  --code-foreground: var(--surface-foreground);
  --code-highlight: oklch(0.27 0 0);
  --code-number: oklch(0.72 0 0);
  --selection: oklch(0.922 0 0);
  --selection-foreground: oklch(0.205 0 0);
}

Understanding OKLCH

OKLCH provides better perceptual uniformity compared to HSL:

  • L (Lightness): 0 (black) to 1 (white)
  • C (Chroma): Color intensity, typically 0 to 0.4
  • H (Hue): Angle in degrees (0-360)
/* Examples */
oklch(0.5 0.2 240)    /* Medium blue */
oklch(0.8 0.15 120)   /* Light green */
oklch(0.3 0.1 0)      /* Dark gray */

Color Categories

Supasheet includes several color categories:

Base Colors

  • background, foreground - Main page colors
  • card, card-foreground - Card component colors
  • popover, popover-foreground - Popover/dropdown colors

Interactive Colors

  • primary, primary-foreground - Primary actions and CTAs
  • secondary, secondary-foreground - Secondary actions
  • accent, accent-foreground - Highlighted elements
  • destructive - Destructive actions (delete, remove)

UI Elements

  • border - Border colors
  • input - Input field borders
  • ring - Focus ring colors
  • muted, muted-foreground - Muted/disabled states

Sidebar Colors

  • sidebar, sidebar-foreground - Sidebar background
  • sidebar-primary, sidebar-primary-foreground - Sidebar primary actions
  • sidebar-accent, sidebar-accent-foreground - Sidebar highlights
  • sidebar-border, sidebar-ring - Sidebar borders and focus

Code & Surface Colors

  • surface, surface-foreground - Secondary surface colors
  • code, code-foreground - Code block background
  • code-highlight - Code line highlights
  • code-number - Line numbers
  • selection, selection-foreground - Text selection

Chart Colors

  • chart-1 through chart-5 - Data visualization colors

Customizing Colors

/* Custom brand colors using OKLCH */
:root {
  --brand-primary: oklch(0.55 0.25 240);    /* Vibrant blue */
  --brand-secondary: oklch(0.6 0.22 280);   /* Purple */
  --brand-accent: oklch(0.65 0.2 150);      /* Green */
}

.dark {
  --brand-primary: oklch(0.65 0.25 240);    /* Lighter blue for dark mode */
  --brand-secondary: oklch(0.7 0.22 280);   /* Lighter purple */
  --brand-accent: oklch(0.75 0.2 150);      /* Lighter green */
}

Using Theme Colors

In Tailwind Classes

<div className="bg-primary text-primary-foreground">
  Primary background
</div>

<div className="bg-secondary text-secondary-foreground">
  Secondary background
</div>

<button className="bg-destructive text-destructive-foreground">
  Delete
</button>

<aside className="bg-sidebar text-sidebar-foreground">
  Sidebar content
</aside>

<div className="bg-surface text-surface-foreground">
  Secondary surface
</div>

<pre className="bg-code text-code-foreground">
  Code block
</pre>

Custom Color Utilities

Supasheet's color system is integrated into Tailwind through the @theme inline block:

// Using standard theme colors
<div className="bg-background text-foreground">
  Page content
</div>

// Using sidebar colors
<nav className="bg-sidebar border-sidebar-border">
  Navigation
</nav>

// Using surface colors
<div className="bg-surface text-surface-foreground">
  Card or panel
</div>

// Using custom OKLCH colors directly
<div className="bg-[oklch(0.55_0.25_240)]">
  Custom color
</div>

Customizing Your Theme

To customize the theme, modify the CSS variables in styles/globals.css. You can adjust colors by changing the OKLCH values:

/* Example: Customizing primary color */
:root {
  --primary: oklch(0.5 0.2 240);  /* Custom blue */
}

.dark {
  --primary: oklch(0.65 0.2 240); /* Lighter for dark mode */
}

Tailwind CSS 4 Configuration

Supasheet uses Tailwind CSS 4 with the new @theme inline directive:

/* styles/globals.css */
@import "tailwindcss";

@theme inline {
  --breakpoint-3xl: 1600px;
  --breakpoint-4xl: 2000px;
  --font-sans: var(--font-sans);
  --font-mono: var(--font-mono);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  /* ... other color mappings */
}

This allows you to use theme colors directly in Tailwind classes:

<div className="bg-background text-foreground rounded-lg">
  Content with theme colors and radius
</div>

Custom Variants

Supasheet includes custom Tailwind variants:

@custom-variant dark (&:is(.dark *));
@custom-variant fixed (&:is(.layout-fixed *));

Use them in your components:

<div className="bg-white dark:bg-gray-900">
  Responsive to dark mode
</div>

<div className="relative fixed:absolute">
  Changes based on layout type
</div>

Best Practices

1. Use OKLCH for Better Color Manipulation

/* Good ✅ - OKLCH provides better perceptual uniformity */
:root {
  --brand-color: oklch(0.55 0.2 240);
  --brand-hover: oklch(0.45 0.2 240);  /* Darker, same hue */
  --brand-light: oklch(0.75 0.15 240); /* Lighter, reduced chroma */
}

/* Less ideal - RGB/Hex harder to adjust perceptually */
:root {
  --brand-color: #3b82f6;
  --brand-hover: #2563eb;
}

2. Consistent Naming Convention

/* Good ✅ - Semantic naming with foreground pairs */
--primary
--primary-foreground
--secondary
--secondary-foreground
--sidebar
--sidebar-foreground

/* Bad ❌ - Color-based naming */
--blue
--text-on-blue
--light-gray
--dark-text

3. Theme Scoping with Data Attributes

/* Good ✅ - Scoped to data attribute */
[data-theme='custom'] {
  --primary: oklch(0.5 0.2 240);
}

/* Bad ❌ - Class-based global override */
.custom-theme {
  background: blue;
}

4. Maintain Accessibility

/* Good ✅ - Sufficient contrast between background and foreground */
:root {
  --background: oklch(1 0 0);        /* White */
  --foreground: oklch(0.145 0 0);    /* Very dark gray */
}

/* Bad ❌ - Insufficient contrast */
:root {
  --background: oklch(0.8 0 0);      /* Light gray */
  --foreground: oklch(0.6 0 0);      /* Medium gray */
}

5. Use Alpha Channel for Transparency

/* Good ✅ - OKLCH with alpha */
:root {
  --overlay: oklch(0 0 0 / 50%);
  --border: oklch(1 0 0 / 10%);
}

.dark {
  --border: oklch(1 0 0 / 15%);
}

Next Steps