Styling and Theming
Relevant source files
The following files were used as context for generating this wiki page:The styling and theming architecture of the Greenline client application is built upon a modern stack leveraging Tailwind CSS for utility-first styling, CSS Custom Properties (variables) for theming, and shadcn/ui for a set of pre-built, customizable components. This combination allows for rapid development, consistent UI, and a flexible theming system that supports both light and dark modes, with system preference detection.
The core of the system is managed through tailwind.config.ts for style definitions and globals.css for theme variable declarations. The next-themes library, integrated via the ThemeProvider component, orchestrates the theme switching by toggling a class on the <html> element, which in turn applies the corresponding set of CSS variables.
Core Technologies
The project utilizes several key libraries for its styling and UI layer.
| Library | Purpose | Source |
|---|---|---|
tailwindcss | A utility-first CSS framework for building custom designs. | [client/package.json:34](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L34) |
next-themes | Manages theme switching (light/dark/system) in Next.js applications. | [client/package.json:18](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L18) |
tailwindcss-animate | A Tailwind CSS plugin for adding enter/exit animations. | [client/package.json:23](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L23), [client/tailwind.config.ts:90](https://github.com/asixham/greenline/blob/HEAD/client/tailwind.config.ts#L90) |
tailwind-scrollbar | A Tailwind CSS plugin for styling scrollbars. | [client/package.json:33](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L33), [client/tailwind.config.ts:90](https://github.com/asixham/greenline/blob/HEAD/client/tailwind.config.ts#L90) |
clsx / tailwind-merge | Utilities for constructing conditional class names. | [client/package.json:14, 22](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L14) |
@radix-ui/* | A collection of unstyled, accessible UI primitives. | [client/package.json:11-17](https://github.com/asixham/greenline/blob/HEAD/client/package.json#L11-L17) |
Sources: client/package.json:11-34, client/tailwind.config.ts:90
Configuration
Tailwind CSS Configuration
The main configuration for Tailwind CSS is located in client/tailwind.config.ts. It defines content paths, dark mode strategy, and theme extensions.
- Content Paths: Specifies the files that Tailwind will scan for utility classes.
// client/tailwind.config.ts:5-9 content: [ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", ], - Dark Mode: The strategy is set to
class, meaning dark mode is activated by adding a.darkclass to an ancestor element (typically<html>).// client/tailwind.config.ts:4 darkMode: ["class"], - Theme Extensions: The
theme.extendobject adds custom values to the default Tailwind theme.
Custom Colors
The application defines a semantic color palette using HSL variables, which are mapped to CSS variables in globals.css.
| Name | HSL Value | Description |
|---|---|---|
background | hsl(var(--background)) | The main background color of the app. |
foreground | hsl(var(--foreground)) | The main text color. |
card | hsl(var(--card)) | The background color for card components. |
primary | hsl(var(--primary)) | Primary interactive element color. |
secondary | hsl(var(--secondary)) | Secondary interactive element color. |
muted | hsl(var(--muted)) | Muted text and element color. |
accent | hsl(var(--accent)) | Color for accents and highlights. |
destructive | hsl(var(--destructive)) | Color for destructive actions (e.g., errors). |
border | hsl(var(--border)) | Default border color. |
input | hsl(var(--input)) | Default input field border color. |
ring | hsl(var(--ring)) | Color for focus rings. |
chart.* | hsl(var(--chart-N)) | A set of 5 colors for use in charts. |
Sources: client/tailwind.config.ts:12-51
Custom Animations & Keyframes
Custom animations are defined for components like accordions and decorative elements.
| Animation Name | Keyframes Definition | Description |
|---|---|---|
accordion-down | from { height: 0 } to { height: var(...) } | Animates an accordion opening. |
accordion-up | from { height: var(...) } to { height: 0 } | Animates an accordion closing. |
spin-slow | spin 8s linear infinite | A slower version of the default spin animation. |
marquee | marquee 25s linear infinite | A horizontal scrolling animation. |
rain | from { transform: translateY(-100%) } to { ... } | A vertical falling animation. |
Sources: client/tailwind.config.ts:60-88
shadcn/ui Configuration
The project uses shadcn/ui, and its configuration is stored in client/components.json. This file dictates how shadcn/ui components are generated and where they are placed.
| Property | Value | Description |
|---|---|---|
style | new-york | The visual style preset for the components. |
rsc | true | Indicates that components should be generated as React Server Components. |
tailwind.config | tailwind.config.ts | Path to the Tailwind configuration file. |
tailwind.css | src/app/globals.css | Path to the global CSS file where variables are defined. |
tailwind.baseColor | zinc | The base color palette used for generating theme variables. |
tailwind.cssVariables | true | Enables the use of CSS variables for theming. |
aliases.components | @/components | Path alias for component files. |
aliases.ui | @/components/ui | Path alias for the generated UI primitive components. |
Sources: client/components.json:2-19
Theming System
The theming system is driven by CSS variables defined in globals.css and controlled by the ThemeProvider component.
Theme Application Flow
This diagram shows how a theme is applied from configuration to the rendered component.
CSS Variables
globals.css contains two main blocks of CSS variables: one for the light theme (:root) and one for the dark theme (.dark). These variables control colors for background, text, cards, borders, and more.
Light Theme (:root)
/* client/src/app/globals.css:28-56 */
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
/* ... other variables */
--radius: 0.5rem
}
Dark Theme (.dark)
The dark theme overrides the default variables when the .dark class is present on the <html> element. The default background is black.
/* client/src/app/globals.css:58-86 */
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
/* ... other variables */
}
The base background color is set to black (#000000) at the root level, and the .dark class modifies it to a dark gray.
Sources: client/src/app/globals.css:8, 60
ThemeProvider
The ThemeProvider from next-themes is wrapped around the application's children in the root layout. It handles the logic for switching themes.
// client/src/app/layout.tsx:39-47
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
attribute="class": Tellsnext-themesto change themes by modifying a class on the<html>tag.defaultTheme="system": Sets the default theme to match the user's operating system preference.enableSystem: Enables automatic theme switching based on system preferences.
Sources: client/src/app/layout.tsx:39-47
Global Styles and Fonts
Global Styles
The globals.css file also imports Tailwind's base, components, and utilities layers. It sets the default background and text-foreground on the <body> element, ensuring the theme is applied globally.
/* client/src/app/globals.css:1-4 */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* client/src/app/globals.css:91-93 */
body {
@apply bg-background text-foreground;
}
A special hover effect is also defined globally for SVG icons, changing their fill color to the brand's primary green (#D4FF00).
/* client/src/app/globals.css:96-98 */
.svg-icon:hover path {
fill: #D4FF00;
}
Sources: client/src/app/globals.css:1-4, 91-98
Font Configuration
The application uses the Open_Sans font from Google Fonts, configured in client/src/app/layout.tsx using next/font/google. The resulting class name is applied to the <body> tag along with antialiased for smoother font rendering.
// client/src/app/layout.tsx:22, 37
const openSans = Open_Sans({ subsets: ['latin'] })
// ...
<body
className={`${openSans.className} antialiased`}
>
Sources: client/src/app/layout.tsx:22, 37
Component Styling
Components are styled using a combination of shadcn/ui base components and Tailwind CSS utility classes.
Base UI Components
Base components like Card are created using React.forwardRef and cn (a utility that merges Tailwind classes). These components encapsulate the base styles. For example, the Card component applies rounded-xl, border, bg-card, and text-card-foreground.
// client/src/components/ui/card.tsx:6-14
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className
)}
{...props}
/>
))
Sources: client/src/components/ui/card.tsx:6-14
Application of Styles
Higher-level components then use these base components and apply further utility classes for layout, color, and state variations. For instance, the HeroSection component uses utility classes for gradients, custom colors like text-[#D4FF00], and responsive design.
// client/src/components/Hero/index.tsx:145-148
<span className="bg-clip-text text-transparent bg-gradient-to-r from-[#D4FF00] to-green-400">
Intelligence Platform
</span>
This demonstrates how specific, one-off styles are created directly within components using Tailwind's extensive utility set, while the base theme is maintained through the shadcn/ui components and CSS variables.