Supasheet.

Theming

Customize the look and feel of Supasheet

Overview

Supasheet uses Tailwind CSS 4 with the @tailwindcss/vite plugin and CSS variables for theming, making it easy to customise colours, typography, and overall appearance. All theme configuration lives in src/styles.css.

Color System

CSS Variables

Supasheet uses OKLCH color space for better perceptual uniformity and color manipulation. Colors are defined in src/styles.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

To customize the theme, modify the CSS variables in src/styles.css:

/* 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 */
}

Custom brand colors:

: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);
  --brand-secondary: oklch(0.7 0.22 280);
  --brand-accent: oklch(0.75 0.2 150);
}

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>

Tailwind CSS v4 Configuration

Supasheet uses Tailwind CSS v4 with the @theme inline directive in src/styles.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 */
}

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);
}

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

On this page