Skip to main content
The project organizes all UI code using the Atomic Design methodology. Every component lives in one of five layers, each building on the one below it.

The five layers

Atoms

Smallest reusable primitives: buttons, inputs, labels, the loading screen, and the typewriter effect.

Molecules

Simple composites that combine atoms: guru cards, countdown timers, phone inputs, and date pickers.

Organisms

Complex sections that compose molecules and atoms: navigation, forms, galleries, video players, and the shader background.

Templates

Page-level layouts. Currently minimal — add skeletons and page shells here as the project grows.

UI (shadcn/ui)

Third-party primitives in components/ui/. Maintained separately so updates from upstream are straightforward.

Directory structure

components/
├── atoms/          # Primitives
├── molecules/      # Simple composites
├── organisms/      # Complex sections
├── templates/      # Page layouts
├── ui/             # shadcn/ui + custom registries
├── audio-player.tsx
└── README.md

Import conventions

Always import from the layer’s index file, not directly from the component file. This keeps imports clean and makes it easy to refactor internal file names without touching consumers.
1

Import atoms

import { LoadingScreen, Typewriter, ScrollToTop, ThemeProvider } from '@/components/atoms'
2

Import molecules

import { GuruCard, LazyDatePicker, LazyPhoneInput, ProgressCounter } from '@/components/molecules'
3

Import organisms

import { Navigation, SevaSubmissionForm, VideoSection, ShaderBackground } from '@/components/organisms'
The @/components path alias is configured in tsconfig.json. Never use relative imports like ../../components/atoms — always use the @/ prefix.

Path aliases

AliasResolves to
@/components/components
@/lib/lib
@/hooks/hooks
@/contexts/contexts
@/utils/utils

shadcn/ui configuration

The project uses shadcn/ui New York style with RSC enabled. Components live in components/ui/shadcn-io/ and are imported from there. Do not modify these files directly — instead extend or wrap them in the appropriate atomic layer. To add a new shadcn/ui component:
npx shadcn@latest add <component-name>

Custom component registries

Three additional registries are configured alongside shadcn/ui:
Animated and interactive UI components. Used for visual effects and motion-rich elements. Install via:
npx magicui-cli@latest add <component-name>
Unique, design-heavy components. Used for special visual sections. Install via:
npx shadcn@latest add <component-name> --registry https://ui.aceternity.com/registry
Premium animated components. The landing page uses Skiper53 from this registry for the hero image carousel on desktop.
import { Skiper53 } from '@/components/ui/skiper-ui/skiper53'

Adding a new component

1

Identify the correct layer

Ask: does this component stand alone with no children components? → atom. Does it compose two or more atoms? → molecule. Does it represent a full page section? → organism.
2

Create the file

Use kebab-case file names. Client components must include the "use client" directive at the top.
"use client"

interface MyComponentProps {
  label: string
  className?: string
}

export default function MyComponent({ label, className = "" }: MyComponentProps) {
  return <div className={className}>{label}</div>
}
3

Export from the layer index

Open the index.ts for the layer and add a named export:
export { default as MyComponent } from './my-component'
4

Import and use

import { MyComponent } from '@/components/atoms'
Keep organisms focused on a single page section. If a component is reused across multiple pages or contains its own isolated state, it belongs in organisms even if it’s visually simple.

Build docs developers (and LLMs) love