Skip to main content

Overview

SAAC Frontend uses Tailwind CSS v4 integrated with Vite for styling. The project also includes traditional CSS files for component-specific styles, giving you flexibility in your styling approach.

Tailwind CSS v4 Setup

Vite Configuration

Tailwind is configured via the Vite plugin:
vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
})
Tailwind CSS v4 uses the Vite plugin (@tailwindcss/vite) instead of PostCSS configuration. This provides faster builds and better integration with Vite’s development server.

Installation

Tailwind v4 is included in the dependencies:
package.json
{
  "dependencies": {
    "@tailwindcss/vite": "^4.1.13",
    "tailwindcss": "^4.1.13"
  }
}

Global Styles

The index.css file contains global styles applied to the entire application:
src/index.css
:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}

Global Styles Features

CSS Variables

Uses :root for global design tokens and theming

Dark Mode Support

Automatic dark/light mode via prefers-color-scheme

Typography

System font stack for optimal performance

Accessibility

Font smoothing and focus indicators included

Component-Specific Styles

The App.css demonstrates component-scoped styling:
src/App.css
#root {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
  filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: no-preference) {
  a:nth-of-type(2) .logo {
    animation: logo-spin infinite 20s linear;
  }
}

.card {
  padding: 2em;
}

.read-the-docs {
  color: #888;
}

CSS Features Used

Keyframe animations with accessibility considerations:
@keyframes logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Respects user motion preferences */
@media (prefers-reduced-motion: no-preference) {
  a:nth-of-type(2) .logo {
    animation: logo-spin infinite 20s linear;
  }
}
Dynamic visual effects on hover:
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
Optimize for animations:
.logo {
  will-change: filter;
  transition: filter 300ms;
}

Using Tailwind CSS

Utility Classes

With Tailwind v4, you can use utility classes directly in your components:
function Card() {
  return (
    <div className="max-w-sm mx-auto p-6 bg-white rounded-lg shadow-lg">
      <h2 className="text-2xl font-bold mb-4 text-gray-800">Card Title</h2>
      <p className="text-gray-600 leading-relaxed">
        Card content goes here
      </p>
      <button className="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition">
        Click Me
      </button>
    </div>
  )
}

Responsive Design

<div className="w-full md:w-1/2 lg:w-1/3">
  {/* Full width on mobile, half on tablet, third on desktop */}
</div>

<h1 className="text-2xl md:text-4xl lg:text-6xl">
  {/* Responsive text sizes */}
</h1>

Dark Mode with Tailwind

function ThemedComponent() {
  return (
    <div className="bg-white dark:bg-gray-900">
      <h1 className="text-gray-900 dark:text-white">
        Automatically themed content
      </h1>
      <p className="text-gray-600 dark:text-gray-300">
        This text adapts to the color scheme preference
      </p>
    </div>
  )
}

Styling Approaches

1

Tailwind Utility Classes

Best for: Rapid prototyping, consistent spacing, responsive design
function Button({ children }) {
  return (
    <button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
      {children}
    </button>
  )
}
2

CSS Modules

Best for: Complex component styles, animations, custom designs
import './Button.css'

function Button({ children }) {
  return (
    <button className="custom-button">
      {children}
    </button>
  )
}
3

Hybrid Approach

Combine both for maximum flexibility:
import './Card.css'

function Card({ title, children }) {
  return (
    <div className="card-container p-6 rounded-lg shadow-md">
      <h2 className="text-2xl font-bold mb-4">{title}</h2>
      {children}
    </div>
  )
}

Customization

Extending Tailwind

In Tailwind v4, customization can be done via CSS variables or configuration:
src/index.css
@import "tailwindcss";

@theme {
  --color-primary: #646cff;
  --color-secondary: #61dafb;
  --font-heading: 'Inter', system-ui, sans-serif;
}
Then use in components:
<div className="bg-primary text-white">
  Custom themed content
</div>

Custom Utilities

Add custom utility classes:
src/index.css
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
  
  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }
}

Best Practices

Consistency

Use Tailwind utilities for spacing, colors, and typography to maintain consistency

Component Extraction

Extract repeated Tailwind patterns into reusable components

Performance

Tailwind v4 automatically purges unused styles in production builds

Readability

Use multi-line className for complex styling to improve readability

Component Extraction Example

// ❌ Repeated utility classes
function App() {
  return (
    <>
      <button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
        Submit
      </button>
      <button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
        Cancel
      </button>
    </>
  )
}

// ✅ Extracted component
function Button({ children }) {
  return (
    <button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
      {children}
    </button>
  )
}

function App() {
  return (
    <>
      <Button>Submit</Button>
      <Button>Cancel</Button>
    </>
  )
}
The combination of Tailwind CSS v4 for utility-first styling and traditional CSS for custom designs provides maximum flexibility while maintaining fast development speed.

Build docs developers (and LLMs) love