Styling and Theming
Styling and Theming
The Quantum Advantage Tracker (QAT) uses Tailwind CSS for layout and styling, combined with CSS Variables defined in the OKLCH color space to manage a consistent visual identity across light and dark modes.
Theme Configuration
The project utilizes Tailwind's version 4 theme engine. Custom theme variables are defined in src/app/globals.css and mapped to Tailwind utility classes. This allows you to use standard Tailwind classes (e.g., text-primary, bg-secondary) while maintaining a centralized design system.
Key theme colors include:
- Primary: The brand's signature green (
oklch(0.8097 0.1517 150.4422)), used for main buttons and active states. - Secondary: Used for cards, background accents, and subtle UI elements.
- Hero Gradient: A custom gradient class
bg-hero-gradientused for page headers.
Color System and CSS Variables
Colors are managed via CSS variables in the :root and .dark selectors. To modify the global color palette, update the values in src/app/globals.css.
/* Example: Modifying the primary brand color */
:root {
--primary: oklch(0.8097 0.1517 150.4422);
--primary-foreground: oklch(0.2002 0 0);
}
.dark {
--primary: oklch(0.8097 0.1517 150.4422);
--primary-foreground: oklch(0.2002 0 0);
}
Dark Mode Support
QAT natively supports dark mode using the .dark class strategy. When the dark class is applied to the html or body element, the CSS variables switch to their dark-themed counterparts defined in globals.css.
Utility Functions
To handle dynamic class merging—especially when working with Tailwind classes and component props—the project provides a cn utility in src/lib/utils.ts. This utility combines clsx for conditional logic and tailwind-merge to prevent style conflicts.
Usage Example:
import { cn } from '@/lib/utils';
export function CustomCard({ className, isActive }: { className?: string; isActive: boolean }) {
return (
<div className={cn(
"bg-secondary p-6 rounded-lg border",
isActive && "border-primary",
className
)}>
{/* Content */}
</div>
);
}
Typography
The project uses Inter via next/font/google as its primary typeface. It is configured as a CSS variable (--font-inter-sans) and applied globally to the body in src/app/layout.tsx.
// To apply the font to a specific element:
<div className="font-sans">This uses the Inter font.</div>
Custom Animations
The tracker includes specialized animations for data presentation, such as the infinite marquee for the contributors list. These are defined within the @theme block in the global CSS:
- Marquee: The
animate-marqueeclass provides a seamless horizontal scroll. - Keyframes: Custom keyframes for the marquee translate the element from
0%to-50%for an infinite loop effect.
<ul className="animate-marquee flex w-max">
{/* Marquee items */}
</ul>
Components and Icons
UI components (like Button) are built on a consistent system of variants. Icons are provided via lucide-react or custom SVG wrappers found in src/icons.
To use a standard button with the theme:
import { Button } from '@/components/ui/button';
export function Action() {
return (
<Button variant="default" size="lg">
Click Me
</Button>
);
}