Theming & Styling
Relevant source files
The following files were used as context for generating this wiki page:
The Subito project employs a centralized styling architecture based on Tailwind CSS v4, shadcn/ui, and next-themes. The styling system is managed primarily within the @subito/ui workspace, which exports global CSS variables and shared UI components to the rest of the monorepo. This ensures a consistent visual identity across applications like the dashboard.
The system supports light and dark modes through CSS variables defined using OKLCH color spaces. It includes a custom theme provider that handles theme switching via system preferences and a dedicated keyboard hotkey ('d').
Core Architecture
The styling architecture is built upon a foundation of utility-first CSS and a robust variable-based theming system.
CSS Variable System
The project uses a theme-first approach where design tokens are defined as CSS variables within @layer base. These variables are mapped to Tailwind theme keys using the @theme directive.
The diagram above illustrates how raw CSS variables are mapped to Tailwind theme tokens for use in components.
Sources: packages/ui/src/styles/globals.css:1-125, packages/ui/components.json:7-12
Component Styling Logic
Components utilize class-variance-authority (CVA) to manage variants and tailwind-merge (via a cn utility) to handle conditional class merging. This allows for complex component states (like active, disabled, or vertical orientations) to be styled predictably.
Sources: packages/ui/src/components/tabs.tsx:21-36, packages/ui/package.json:15-18
Theme Management
Theme state is managed through the ThemeProvider component, which wraps the application and provides access to the current theme context.
Theme Provider Configuration
The ThemeProvider is a wrapper around NextThemesProvider from the next-themes library. It is configured to use the class attribute for theme switching, allowing the .dark class to be toggled on the html or body element.
| Property | Value | Description |
|---|---|---|
attribute | "class" | Toggles the theme by adding/removing the 'dark' class. |
defaultTheme | "system" | Defaults to the user's operating system preference. |
enableSystem | true | Observes system-level dark mode changes. |
disableTransitionOnChange | true | Prevents CSS transitions during theme swaps. |
Sources: apps/dashboard/components/theme-provider.tsx:7-22
Theme Hotkey Feature
A unique feature of the Subito dashboard is the ThemeHotkey component. It listens for a global keydown event and toggles the theme between 'light' and 'dark' when the 'd' key is pressed, provided the user is not currently interacting with an input field.
The sequence diagram shows the logic gate preventing theme toggling while typing.
Styling Variables & Tokens
The project defines a comprehensive set of tokens in globals.css using the OKLCH color model, which provides better perceptual uniformity compared to RGB/HSL.
Color Tokens (Partial List)
| Token | Light Mode (Default) | Dark Mode (.dark) |
|---|---|---|
--background | oklch(1 0 0) | oklch(0.145 0 0) |
--foreground | oklch(0.145 0 0) | oklch(0.985 0 0) |
--primary | oklch(0.205 0 0) | oklch(0.922 0 0) |
--destructive | oklch(0.577 0.245 27.325) | oklch(0.704 0.191 22.216) |
--border | oklch(0.922 0 0) | oklch(1 0 0 / 10%) |
Sources: packages/ui/src/styles/globals.css:55-120
Border Radius System
Radius values are calculated as multiples of a base --radius variable (set to 0.625rem).
- sm:
calc(var(--radius) * 0.6) - md:
calc(var(--radius) * 0.8) - lg:
var(--radius) - xl:
calc(var(--radius) * 1.4)
Sources: packages/ui/src/styles/globals.css:42-48
Implementation in Applications
The dashboard application integrates the styling system by importing the global CSS and wrapping the root layout in the ThemeProvider.
Root Layout Integration
In apps/dashboard/app/layout.tsx, the styling is applied by:
- Importing
@subito/ui/globals.css. - Configuring fonts via
next/font/google(Inter for sans-serif, Geist Mono for monospace). - Applying
antialiasedand font variables to thehtmlelement.
Sources: apps/dashboard/app/layout.tsx:1-34
Component Usage Example: Tabs
The Tabs component illustrates how Tailwind v4 features like the @group directive and data-attributes (e.g., data-active, data-orientation) are used for styling.
// Example of variant styling using CVA and data-attributes
const tabsListVariants = cva(
"inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground",
{
variants: {
variant: {
default: "bg-muted",
line: "gap-1 bg-transparent",
},
},
}
)
Sources: packages/ui/src/components/tabs.tsx:21-36
Summary
Theming and styling in Subito is a centralized, type-safe system that leverages the latest capabilities of Tailwind CSS v4 and shadcn/ui. By defining tokens in a shared package and utilizing a robust theme provider with hotkey support, the project maintains a consistent and developer-friendly styling environment across the entire monorepo.