Design System
Component library and design tokens. Click component names to copy import paths.
Accordion
Collapsible FAQ-style component with smooth expand/collapse animations. Uses Radix UI primitives. Each item has a subtle hover highlight in dark mode. Wrap in CursorGlow for interactive glow effects.
Accordion
Action Link Cards
Clickable cards for contact actions, navigation links, and CTAs. Primary variant has emerald background with white sparkles. Secondary variant uses card background with emerald icon accent.
Primary vs Secondary
With/Without Description
External Links
Use external prop for links that open in new tabs (adds target="_blank" rel="noopener noreferrer").
Usage
Import: import { ActionLinkCard } from "@/components/ui/action-link-card"
Primary: Use for the main CTA (e.g., "Schedule a call"). Has white sparkles.
Secondary: Use for alternative actions. No sparkles, emerald icon accent.
External: Set external=true for links opening in new tabs.
Animated Icons (Lucide Animated)
Hover over icons to trigger animations. Use refs to control: iconRef.current?.startAnimation()
SVG Stroke Overlap Fix
Stroke-based SVG icons can show overlapping artifacts when using alpha transparency in colors. We've fixed this by using solid colors for --muted-foreground in globals.css.
Avoid for icons
className="text-foreground/50"Alpha in color causes stroke overlap
Safe to use
className="text-muted-foreground"Uses solid color (oklch 0.556)
Animation Components
Marquee
Ripple
Backgrounds
The unified background system used across landing pages. Combines gradients, animated grids, and decorative patterns.
Landing Background
LandingBackground
The primary wrapper component for all landing pages. Includes a subtle blue gradient and the interactive CursorGrid overlay.
<SiteHeader />
<main>...</main>
<Footer />
</LandingBackground>
Cursor Grid (Interactive)
CursorGrid
The animated dot grid component with cursor-following spotlight, pulsing lines, and random blinking dots.
CursorGrid Features
300px radius glow follows mouse
Emerald lines travel along grid paths
Random dots flash emerald every ~800ms
40px spacing, visible near cursor
Blinking Dots Animation
Animation Phases:
- Flash (150ms) - Dot expands with emerald color
- Settle (300ms) - Bounces down to hold size
- Hold (800ms) - Stays emerald at 1.3x scale
- Deflate (600ms) - Fades back to grey
Behavior:
- 3-8 random dots triggered every ~800ms
- Each dot has random intensity (0.3-1.0)
- Sparse rendering - only active dots update
- Throttled to ~30fps for performance
Decorative Patterns
Static background patterns for cards, sections, or decorative use. Not used on landing pages (use LandingBackground instead).
DotPattern
GridPattern
Usage Guidelines
BlurFade
BlurFade
Wraps content with fade-in + blur animation. Used on the landing page for staggered entrance animations. Scroll down in this preview area to trigger the animation.
First Element (delay: 0.1s)
Fades in with blur effect
Second Element (delay: 0.2s)
Staggered entrance animation
Third Element (delay: 0.3s)
Creates a cascading effect
Cards & Cursor Glow
Centralized card system for consistent styling across the application. Defined in lib/cards.ts. Shadow behavior: sm (default) → md (hover). Dark mode includes subtle emerald glow. Wrap cards in <CursorGlow> for interactive cursor-following glow effects. Use sparkle prop with SparkleProvider to enable twinkling sparkles.
Unified Card Color System
Each card variant has a single accent color that defines its border, shadow, CursorGlow, and sparkle colors. Use getCard(variant) to get all colors and classes at once. CARD_CTA is the only variant with white sparkles.
Interactive
Emerald sparkles
color: emeraldFeatured
Emerald sparkles
color: emeraldCTA
White sparkles only
color: white (exception)Crossed Corners
Emerald sparkles
color: emeraldWarning
Yellow sparkles
color: yellowDestructive
Red sparkles
color: redCard Color Reference
| Variant | Color | Sparkle |
|---|---|---|
| interactive, featured, crossed-corners | emerald | rgba(16, 185, 129, 0.9) |
| cta | white | white (only exception) |
| warning | yellow | rgba(234, 179, 8, 0.9) |
| destructive | red | rgba(239, 68, 68, 0.9) |
Cursor Glow Colors
The GLOW_COLORS constant provides a preset palette. Pass any HSL value for custom colors.
Emerald
GLOW_COLORS.emeraldRed
GLOW_COLORS.redOrange
GLOW_COLORS.orangeCyan
GLOW_COLORS.cyanPurple
GLOW_COLORS.purplePink
GLOW_COLORS.pinkAmber
GLOW_COLORS.amberRose
GLOW_COLORS.roseBlue
GLOW_COLORS.blueCursorGlow Props
colorCSS color value or GLOW_COLORS.*. Default: emeraldsizeGlow radius in pixels. Default: 500opacityBackground glow opacity (0-1). Default: 0.06proximityDistanceDistance to start glowing. Default: 100pxdisabledDisable the glow effect completely. Default: falsedisabledInLightModeDisable glow in light mode only (dark mode still glows). Default: trueUsage Guidelines
Shadow Behavior
Cards use sm shadow by default, intensify to md on hover. Dark mode adds subtle emerald glow.
Glass vs Solid
Use glass cards on landing pages. Use solid cards in dashboard/admin contexts.
Matching Glow Colors
Match CursorGlow color to card's gradient background for cohesive feel.
Hover Opacity
Glass cards become more opaque on hover: white in light mode, brighter grey in dark mode.
Cards: import { CARD_INTERACTIVE_SOLID } from "@/lib/cards"
Glow: import { CursorGlow, GLOW_COLORS } from "@/components/ui/cursor-glow"
Colors
Uses OKLCH color space for perceptual uniformity. Defined in globals.css with light/dark mode variants. Many colors use alpha values (e.g., oklch(0 0 0 / 90%)).
Core
Background
bg-backgroundForeground
text-foregroundCard
bg-cardBorder
border-borderBrand & Actions
Brand
bg-brandPrimary
bg-primarySecondary
bg-secondaryDestructive
bg-destructiveUI States
Muted
bg-mutedAccent
bg-accentPopover
bg-popoverRing
ring-ringChart Colors
Chart 1
--chart-1Chart 2
--chart-2Chart 3
--chart-3Chart 4
--chart-4Chart 5
--chart-5Emerald Scale (Accent)
Primary accent color used for CTAs, links, and highlights.
Data Display
Card
Card content goes here.
Table
| Name | Status | Amount |
|---|---|---|
| Project A | Active | $250 |
| Project B | Pending | $150 |
Dropdowns & Popovers
Glassmorphic dropdowns with backdrop-blur-xl and solid dark background in dark mode.
DropdownMenu
Select
Popover Style
Dark mode popover:
--popover: oklch(0.15 0 0 / 95%)+ backdrop-blur-xl
Favicon
App favicon with JG logo on black background. Generated via app/icon.tsx and app/apple-icon.tsx.
Colors: Background #000000, Logo #34d399 (emerald-400)
Form Controls
Input
Textarea
Label
Switch
Checkbox
Slider
Badge
StatusBadge
Layout Components
BentoGrid + BentoCard
Card 1
Description text
Card 2
Another card
3D Grid Logo - Rotating (Hero Version)
Rotating version with wireframe cube edges and grid texture on logo letters. Features crossfade effect to always show JG correctly (never reversed). Used as background with opacity-20 dark:opacity-15.
Static Logo (Header Version)
Flat CSS/SVG logo for headers - square border with JG inside. Lightweight (no 3D/Canvas). Size sm = 32x32px (h-8 w-8) is used in the dashboard header.
Archived: 3D Glassy Logo
Archived
Previous glass/transmission material version with rounded corners. Replaced by grid-style logo. Component preserved in components/logo-3d-glassy.tsx.
Static Version
Rotating Version
Color Configuration
Colors defined in lib/logo-colors.ts. Click swatches to copy values.
Light Mode
Fill (Glass Cube)
Base
rgba(255, 255, 255, 0.1)Cube base color
Attenuation
rgba(167, 243, 208, 0.3)Light attenuation through glass
Logo (JG Letters)
Color
rgba(4, 120, 87, 1)Main logo color
Emissive
rgba(0, 0, 0, 0)Glow (intensity: 0)
Dark Mode
Fill (Glass Cube)
Base
rgba(16, 185, 129, 0.15)Cube base color
Attenuation
rgba(52, 211, 153, 0.4)Light attenuation through glass
Logo (JG Letters)
Color
rgba(110, 231, 183, 1)Main logo color
Emissive
rgba(52, 211, 153, 1)Glow (intensity: 1.2)
Media Components
BeforeAfterSlider
Editor Controls
Images cover the container (may crop)
Preview
Hover to control slider. Click/tap to go fullscreen.
Modals & Dialogs
Overlay components for user interactions, confirmations, and forms.
Dialog
AlertDialog
Drawer
OpenGraph Images
Dynamic OG images generated with Next.js ImageResponse. Each landing page has its own OG image.
ActiveProduct Engineer Landing Page
Inactive Landing Pages(Book a Project, Pricing)
Test Your OG Images
Each platform caches images differently. Use these validators to debug and refresh cached previews.
Guidelines
- Size: 1200x630px (1.91:1 aspect ratio) - optimal for all platforms
- Safe zone: Keep text/logos away from edges (Facebook crops differently than Twitter)
- Brand: Dark background with emerald accent, include JG logo
- Cache: Social platforms cache aggressively - use validators above to force refresh
- Facebook tip: Click "Scrape Again" in the debugger to refresh cached images
Section Header
Reusable section header component for landing pages. Supports two icon styles:cube (rotating 3D outline) and app (solid background). Five color variants available: emerald, red, yellow, blue, and muted.
Icon Styles
Cube Style (default)
Rotating Cube
3D rotating outline cube with icon centered inside
App Style
App Icon
Solid background with ring border
Color Variants (Cube Style)
Rotating Cube Icon Sizes
SectionHeader
Example Section
This is a subtitle that describes the section content
Shadows
Centralized shadow system for consistent elevation and glow effects. Defined in globals.css as CSS custom properties and exported from lib/shadows.ts for programmatic use.
Elevation
Used for floating/elevated UI elements like cards, headers, popovers. Darker in dark mode.
Small
--shadow-elevation-smCards, containers
Medium
--shadow-elevation-mdHeaders, toggles, project cards
Large
--shadow-elevation-lgModals, dialogs, hover states
Glow Effects
Used for CTAs and accent elements. Creates a colored glow effect around the element.
Emerald Glow
--shadow-glow-emeraldPrimary CTAs (Contact, Live Site)
Emerald Glow (Hover)
--shadow-glow-emerald-hoverHover state for primary CTAs
Usage Examples
Glass Container (Header/Toggle)
shadow-[0_8px_32px_rgba(0,0,0,0.12)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)]Project Card (Default)
shadow-[var(--shadow-elevation-md)]Project Card (Hover)
shadow-[var(--shadow-elevation-lg)]Primary CTA Button
shadow-[var(--shadow-glow-emerald)] hover:shadow-[var(--shadow-glow-emerald-hover)]Import: import { shadowClasses } from "@/lib/shadows"
Component Sources
Base components built on Radix UI primitives. Button, Dialog, Select, Accordion, etc.
Animated components. Marquee, Ripple, BlurFade, BentoGrid, AnimatedGradientText, etc.
Icon library with 1000+ icons. Some wrapped with animation via custom components.
CursorGrid, BeforeAfterSlider, Logo3D, ExperienceTimeline, LandingButton, etc.
Typography
Font stack using Geist Sans and Geist Mono from Vercel. Defined in app/layout.tsx.
Geist Sans
font-sansPrimary typeface for all UI text.
The quick brown fox
The quick brown fox jumps over
The quick brown fox jumps over the lazy dog
ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
Geist Mono
font-monoMonospace for code, data, and technical content.
The quick brown fox
The quick brown fox jumps over
The quick brown fox jumps over the lazy dog
ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
Type Scale & Hierarchy
text-5xlPage Titletext-4xlSection Headertext-2xlCard Titletext-xlSubsection Titletext-lgLead Paragraphtext-baseBody text - default size for paragraphs and UI elementstext-smSecondary text, captions, and metadatatext-xsLabels, badges, and fine printFont Weights
Use tracking-tight (-0.025em) for large headlines. Default tracking for body text.
Hero Section
Animated text components for the hero headline. Cycles through rotating words with smooth transitions. Inspired by Aceternity UI.
Rotating Words
Words cycle in this order (defined in home-client.tsx):
- new — Fresh start, new beginnings
- fast — Speed & performance
- beautiful — Visual design & aesthetics
- modern — Current tech & trends
- custom — Tailored solutions
Interval: 2500ms between transitions
ContainerTextFlip (Current)
Need a new website?
FlipWords (Previous)
Need a new website?
ContainerTextFlip Props
| Prop | Type | Default | Description |
|---|---|---|---|
words | string[] | ["better", ...] | Array of words to cycle through |
interval | number | 3000 | Time in ms between transitions |
className | string | - | CSS classes for the container |
textClassName | string | - | CSS classes for the text |
animationDuration | number | 700 | Animation duration in ms |
Code Example
<h1 className="text-4xl font-bold">
Need a{" "}
<ContainerTextFlip
words={["new", "fast", "beautiful", "modern", "custom"]}
interval={2500}
textClassName="font-bold"
/>
{" "}website?
</h1>Image Upload
A polished image upload component with drag-and-drop, file picker, and URL input modes. Features preview with remove button, loading states, and error handling.
ImageUpload (Empty)
Drop an image here, or click to browse
PNG, JPG, GIF up to 5MB
Supports PNG, JPG, GIF up to 5MB
ImageUpload (With Image)
Hover to reveal remove button
ImageUpload Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | null | - | Current image URL |
onChange | (url: string | null) => void | - | Called when image changes |
uploadEndpoint | string | /api/upload | API endpoint for file uploads |
storagePath | string | images | Folder path in storage bucket |
aspectRatio | string | 16/10 | Preview aspect ratio |
maxSize | number | 5MB | Max file size in bytes |
allowUrl | boolean | true | Show URL input tab |
label | string | - | Label text above upload area |
Typography Components
AnimatedGradientText
Usage Notes
- All UI components are in
components/ui/ - Custom page components are in
components/ - Colors use OKLCH format in
globals.css - Use semantic tokens:
bg-background,text-foreground,border-border - Accent color is green:
hsl(145, 80%, 45%)ortext-emerald-500 - Glow effects via
CursorGlowcomponent - Number animations via
@number-flow/react - Icon transparency: Use
opacity-50nottext-foreground/50to avoid stroke overlap