Overview
Plugin Agency uses a custom CSS design system with CSS variables, a dark tech aesthetic, and mobile-first responsive design. All styles are written in vanilla CSS without preprocessors or CSS-in-JS.
CSS Architecture
The styling is organized across two main files:
src/index.css - Design system, global styles, components
src/App.css - Minimal (cleared for component-based styling)
File Structure
src/
├── index.css # Main stylesheet (1850+ lines)
├── App.css # Cleared (component styles in index.css)
└── assets/
└── fonts/ # Custom fonts (Garet family)
Design System Tokens
The project uses CSS custom properties (variables) for consistent theming.
Color Tokens
:root {
/* Background layers */
--bg : #05050a ;
--bg-2 : #0a0a14 ;
--bg-3 : #0f0f1e ;
/* Surface colors */
--surface : rgba ( 255 , 255 , 255 , 0.04 );
--surface-2 : rgba ( 255 , 255 , 255 , 0.07 );
/* Borders */
--border : rgba ( 255 , 255 , 255 , 0.08 );
--border-glow : rgba ( 0 , 212 , 255 , 0.35 );
/* Brand colors */
--cyan : #00d4ff ;
--cyan-dim : rgba ( 0 , 212 , 255 , 0.15 );
--violet : #7c3aed ;
--violet-dim : rgba ( 124 , 58 , 237 , 0.15 );
--green : #10b981 ;
--red : #ef4444 ;
/* Text colors */
--text : #e2e8f0 ;
--text-2 : #94a3b8 ;
--text-3 : #64748b ;
--white : #ffffff ;
}
Usage Example:
.card {
background : var ( --surface );
border : 1 px solid var ( --border );
color : var ( --text );
}
.card:hover {
border-color : var ( --border-glow );
box-shadow : var ( --glow-cyan );
}
Typography Tokens
:root {
/* Font families */
--font-sans : 'Garet' , system-ui , sans-serif ;
--font-mono : 'JetBrains Mono' , 'Courier New' , monospace ;
}
Custom Fonts:
@import url ( 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap' );
@font-face {
font-family : 'Garet' ;
src : url ( './assets/fonts/Garet-Book.woff2' ) format ( 'woff2' ),
url ( './assets/fonts/Garet-Book.woff' ) format ( 'woff' ),
url ( './assets/fonts/Garet-Book.ttf' ) format ( 'truetype' );
font-weight : 400 ;
font-style : normal ;
font-display : swap ;
}
@font-face {
font-family : 'Garet' ;
src : url ( './assets/fonts/Garet-Heavy.woff2' ) format ( 'woff2' ),
url ( './assets/fonts/Garet-Heavy.woff' ) format ( 'woff' ),
url ( './assets/fonts/Garet-Heavy.ttf' ) format ( 'truetype' );
font-weight : 700 ;
font-style : normal ;
font-display : swap ;
}
Using font-display: swap ensures text remains visible during font loading, improving perceived performance.
Spacing & Layout Tokens
:root {
--radius : 12 px ;
--radius-lg : 20 px ;
--max-width : 1200 px ;
}
Glow Effects
:root {
--glow-cyan : 0 0 30 px rgba ( 0 , 212 , 255 , 0.25 ), 0 0 60 px rgba ( 0 , 212 , 255 , 0.1 );
--glow-violet : 0 0 30 px rgba ( 124 , 58 , 237 , 0.25 ), 0 0 60 px rgba ( 124 , 58 , 237 , 0.1 );
}
Component Patterns
Glass Morphism Cards
.glass {
background : var ( --surface );
border : 1 px solid var ( --border );
backdrop-filter : blur ( 16 px );
-webkit-backdrop-filter : blur ( 16 px );
border-radius : var ( --radius );
}
.glass:hover {
border-color : var ( --border-glow );
box-shadow : var ( --glow-cyan );
}
Usage:
< div className = "glass" >
< h3 > Glass Card </ h3 >
< p > Semi-transparent card with backdrop blur </ p >
</ div >
.btn {
display : inline-flex ;
align-items : center ;
justify-content : center ;
gap : 0.5 rem ;
padding : 0.75 rem 1.75 rem ;
border-radius : 50 px ;
font-weight : 600 ;
font-family : var ( --font-sans );
font-size : 0.95 rem ;
transition : all 0.25 s ease ;
cursor : pointer ;
}
.btn-primary {
background : linear-gradient ( 135 deg , var ( --cyan ), #0099cc );
color : #000 ;
box-shadow : 0 0 20 px rgba ( 0 , 212 , 255 , 0.3 );
}
.btn-primary:hover {
transform : translateY ( -2 px );
box-shadow : 0 0 35 px rgba ( 0 , 212 , 255 , 0.5 );
}
.btn-outline {
border : 1.5 px solid var ( --border );
color : var ( --text );
background : var ( --surface );
}
.btn-outline:hover {
border-color : var ( --cyan );
color : var ( --cyan );
transform : translateY ( -2 px );
box-shadow : 0 0 20 px rgba ( 0 , 212 , 255 , 0.15 );
}
Gradient Text
.section-title span {
background : linear-gradient ( 135 deg , var ( --cyan ), var ( --violet ));
-webkit-background-clip : text ;
background-clip : text ;
-webkit-text-fill-color : transparent ;
}
Usage:
< h2 className = "section-title" >
Our < span > Services </ span >
</ h2 >
Animations
Grid Background Animation
.grid-bg {
position : absolute ;
inset : 0 ;
background-image :
linear-gradient ( rgba ( 0 , 212 , 255 , 0.04 ) 1 px , transparent 1 px ),
linear-gradient ( 90 deg , rgba ( 0 , 212 , 255 , 0.04 ) 1 px , transparent 1 px );
background-size : 60 px 60 px ;
animation : gridPan 20 s linear infinite ;
pointer-events : none ;
}
@keyframes gridPan {
0% {
background-position : 0 0 ;
}
100% {
background-position : 60 px 60 px ;
}
}
Pulse Animation
.hero-badge-dot {
width : 6 px ;
height : 6 px ;
border-radius : 50 % ;
background : var ( --cyan );
animation : pulse 2 s ease-in-out infinite ;
}
@keyframes pulse {
0% , 100% {
opacity : 1 ;
box-shadow : 0 0 0 0 rgba ( 0 , 212 , 255 , 0.4 );
}
50% {
opacity : 0.7 ;
box-shadow : 0 0 0 5 px rgba ( 0 , 212 , 255 , 0 );
}
}
Fade In Up
@keyframes fadeInUp {
from {
opacity : 0 ;
transform : translateY ( 20 px );
}
to {
opacity : 1 ;
transform : translateY ( 0 );
}
}
.fade-in-up {
animation : fadeInUp 0.6 s ease forwards ;
}
Responsive Design
Mobile-First Approach
The design is built mobile-first, with breakpoints for larger screens:
/* Mobile styles (base) */
section {
padding : 4 rem 0 ;
}
/* Tablet and up */
@media ( min-width : 768 px ) {
section {
padding : 6 rem 0 ;
}
}
Breakpoints
/* Tablet: 768px */
@media ( max-width : 768 px ) {
.container {
padding : 0 1.25 rem ;
}
.packs-grid {
grid-template-columns : 1 fr ;
}
.two-column-layout {
grid-template-columns : 1 fr ;
gap : 2.5 rem ;
}
}
/* Mobile: 480px */
@media ( max-width : 480 px ) {
.team-grid-ds {
grid-template-columns : 1 fr ;
}
.hero-buttons {
flex-direction : column ;
}
.section-title {
font-size : 1.75 rem ;
}
}
Fluid Typography
/* Scales between 2rem and 3rem based on viewport */
.section-title {
font-size : clamp ( 2 rem , 4 vw , 3 rem );
}
/* Hero title scales between 2.5rem and 5rem */
.hero h1 {
font-size : clamp ( 2.5 rem , 6 vw , 5 rem );
}
/* Subtitle scales between 1rem and 1.2rem */
.hero-subtitle {
font-size : clamp ( 1 rem , 2 vw , 1.2 rem );
}
Using clamp() ensures typography scales smoothly across all screen sizes without hard breakpoints.
The mobile navigation uses a hamburger menu with smooth transitions:
HTML Structure
< button className = "hamburger" onClick = { toggleMenu } >
< span ></ span >
< span ></ span >
< span ></ span >
</ button >
CSS
.hamburger {
display : none ; /* Hidden on desktop */
flex-direction : column ;
justify-content : space-between ;
width : 28 px ;
height : 20 px ;
background : transparent ;
cursor : pointer ;
z-index : 1001 ;
}
.hamburger span {
display : block ;
width : 100 % ;
height : 2 px ;
background : var ( --text-2 );
border-radius : 2 px ;
transition : all 0.3 s ease ;
}
/* Animated X when active */
.hamburger.active span :nth-child ( 1 ) {
transform : translateY ( 9 px ) rotate ( 45 deg );
}
.hamburger.active span :nth-child ( 2 ) {
opacity : 0 ;
}
.hamburger.active span :nth-child ( 3 ) {
transform : translateY ( -9 px ) rotate ( -45 deg );
}
/* Mobile menu */
@media ( max-width : 768 px ) {
.hamburger {
display : flex ;
}
.nav-links {
position : fixed ;
top : 0 ;
right : -100 % ; /* Hidden off-screen */
height : 100 vh ;
width : 75 % ;
max-width : 300 px ;
background : rgba ( 5 , 5 , 10 , 0.97 );
backdrop-filter : blur ( 20 px );
flex-direction : column ;
justify-content : center ;
transition : right 0.3 s ease ;
border-left : 1 px solid var ( --border );
z-index : 999 ;
}
.nav-links.active {
right : 0 ; /* Slide in */
}
}
JavaScript (React)
const [ menuOpen , setMenuOpen ] = useState ( false )
const toggleMenu = () => setMenuOpen ( ! menuOpen )
return (
<>
< button
className = { `hamburger ${ menuOpen ? 'active' : '' } ` }
onClick = { toggleMenu }
>
< span ></ span >
< span ></ span >
< span ></ span >
</ button >
< nav className = { `nav-links ${ menuOpen ? 'active' : '' } ` } >
{ /* Nav items */ }
</ nav >
</>
)
Layout Utilities
Container
.container {
max-width : var ( --max-width ); /* 1200px */
margin : 0 auto ;
padding : 0 2 rem ;
}
@media ( max-width : 768 px ) {
.container {
padding : 0 1.25 rem ;
}
}
Section Spacing
section {
padding : 6 rem 0 ;
}
@media ( max-width : 768 px ) {
section {
padding : 4 rem 0 ;
}
}
Grid Layouts
/* Auto-fit grid with minimum 280px columns */
.services-grid {
display : grid ;
grid-template-columns : repeat ( auto-fit , minmax ( 280 px , 1 fr ));
gap : 1.25 rem ;
}
/* Fixed 3-column grid */
.packs-grid {
display : grid ;
grid-template-columns : repeat ( 3 , 1 fr );
gap : 1.5 rem ;
}
/* Two-column layout */
.two-column-layout {
display : grid ;
grid-template-columns : 1 fr 1 fr ;
gap : 4 rem ;
}
Advanced Effects
Glow Orbs
.orb {
position : absolute ;
border-radius : 50 % ;
filter : blur ( 80 px );
pointer-events : none ;
}
.orb-cyan {
background : rgba ( 0 , 212 , 255 , 0.15 );
}
.orb-violet {
background : rgba ( 124 , 58 , 237 , 0.15 );
}
Usage:
< div className = "hero-bg" >
< div className = "orb orb-cyan" style = { { width: '400px' , height: '400px' , top: '10%' , left: '5%' } } />
< div className = "orb orb-violet" style = { { width: '500px' , height: '500px' , bottom: '20%' , right: '10%' } } />
</ div >
.tb-track {
display : flex ;
gap : 1.5 rem ;
width : max-content ;
animation : tb-scroll-forward 35 s linear infinite ;
}
.tb-track-wrapper:hover .tb-track {
animation-play-state : paused ;
}
@keyframes tb-scroll-forward {
from { transform : translateX ( 0 ); }
to { transform : translateX ( -50 % ); }
}
Best Practices
Use CSS Variables Always use design tokens instead of hardcoded values for consistency and easy theming.
Mobile-First Write base styles for mobile, then add @media queries for larger screens.
Performance Use transform and opacity for animations (GPU-accelerated). Avoid animating width, height, or margin.
Accessibility Ensure sufficient color contrast (WCAG AA minimum). Use semantic HTML and ARIA labels.
Next Steps
Configuration Learn about Vite and ESLint configuration
Components Explore React component architecture