A fully responsive, production-ready digital agency website built with Vite + React + Tailwind CSS, as SmallDrop Inc
- Node.js v16 or higher
- npm v7 or higher
# 1. Unzip and navigate into the project
unzip smalldropinc.zip
cd smalldropinc
# 2. Install dependencies
npm install
# 3. Start the development server
npm run devOpen http://localhost:5173 in your browser.
| Command | Description |
|---|---|
npm run dev |
Start local development server with HMR |
npm run build |
Build for production (outputs to /dist) |
npm run preview |
Preview the production build locally |
smalldropinc/
βββ index.html # HTML entry point (Google Fonts loaded here)
βββ vite.config.js # Vite configuration
βββ tailwind.config.js # Tailwind theme β colors, fonts, animations
βββ postcss.config.js # PostCSS (Tailwind + Autoprefixer)
βββ package.json
βββ src/
βββ main.jsx # React DOM entry point
βββ App.jsx # Root component β hash-based router
βββ index.css # Global styles, Tailwind directives, scroll reveal
βββ components/
βββ Navbar.jsx # Fixed navbar with Services dropdown
βββ Cursor.jsx # Custom cursor (dot + lagged ring)
βββ Hero.jsx # Homepage hero section
βββ Marquee.jsx # Scrolling services ticker
βββ Work.jsx # Homepage portfolio preview grid
βββ Services.jsx # Homepage capabilities section
βββ Clients.jsx # Clients grid + testimonials
βββ Contact.jsx # Homepage CTA section
βββ Footer.jsx # Site-wide footer
βββ AboutUs.jsx # /about page β full about us page
βββ Blog.jsx # /blog page β filterable blog with pagination
βββ LatestWork.jsx # /work page β full portfolio with grid/list view
βββ WebDesign.jsx # /web-design service page
βββ WebDevelopment.jsx # /web-development service page
All routing is handled client-side via URL hash β no external router library required.
| URL Hash | Page | Component |
|---|---|---|
# (default) |
Homepage | Hero + Marquee + Work + Services + Clients + Contact |
#/about |
About Us | AboutUs.jsx |
#/blog |
Blog | Blog.jsx |
#/work |
Latest Work | LatestWork.jsx |
#/web-design |
Web Design Service | WebDesign.jsx |
#/web-development |
Web Development Service | WebDevelopment.jsx |
| Token | Value | Usage |
|---|---|---|
brand-black |
#ffffff |
Page backgrounds (inverted theme) |
brand-white |
#0a0a0a |
Primary text |
brand-accent |
#1a1aff |
Tailwind accent token |
brand-gray |
#f0f0ee |
Section backgrounds |
brand-muted |
#888888 |
Secondary text |
#c3d219 |
Hardcoded | Primary accent β buttons, highlights, cursor, borders |
#0a0a0a |
Hardcoded | Dark sections (Hero, Footer, CTAs) |
Note: The site uses a white background for most content sections with dark (
#0a0a0a) hero sections and footers for contrast. The cursor, active states, and key accents all use#c3d219.
| Role | Font | Usage |
|---|---|---|
| Display | Bebas Neue | Headlines, large numbers, section titles |
| Body | DM Sans | Paragraphs, nav links, descriptions |
| Mono | Space Mono | Labels, tags, code, category badges |
Fonts are loaded via Google Fonts in index.html.
| Class | Effect |
|---|---|
.text-stroke |
Outlined text β #0a0a0a stroke, transparent fill |
.text-stroke-accent |
Outlined text β #1a1aff stroke, transparent fill |
.noise-overlay |
Subtle SVG noise texture via ::after pseudo-element |
.fade-up-section |
Base state for scroll-reveal animation (opacity 0, translateY 40px) |
.fade-up-section.in-view |
Triggered state β fades in and slides up |
A two-part cursor consisting of a solid #c3d219 dot that follows the mouse precisely, and a larger ring that lags behind using requestAnimationFrame for a smooth trailing effect. All default cursors are hidden via * { cursor: none !important }.
Sections use an IntersectionObserver hook (useFadeUp) that adds the .in-view class when an element enters the viewport, triggering a CSS fade-up transition. No external animation library needed.
App.jsx reads window.location.hash to determine the current page and re-renders on hashchange events. Each page change also scrolls to the top.
// Routing logic in App.jsx
function getPage() {
const hash = window.location.hash
if (hash === '#/about') return 'about'
if (hash === '#/blog') return 'blog'
if (hash === '#/work') return 'work'
if (hash === '#/web-design') return 'web-design'
if (hash === '#/web-development') return 'web-development'
return 'home'
}The Services nav item opens a dropdown panel that is left-aligned to the button using left-0 positioning (not centered). It closes on outside click via a mousedown event listener attached to document.
- Live search filtering by title, category, and description
- Category tab filter (11 categories)
- Industry dropdown filter
- Paginated grid β 9 posts per page
- Newsletter subscribe form
- 16 portfolio projects with per-card accent colors
- Grid view (masonry-style with large/small cards) and List view toggle
- Category filter + Industry dropdown + Live search
- 12 projects per page with pagination
| Technology | Version | Purpose |
|---|---|---|
| Vite | ^4.3.9 | Build tool and dev server |
| React | ^18.2.0 | UI framework |
| Tailwind CSS | ^3.3.2 | Utility-first styling |
| PostCSS | ^8.4.24 | CSS processing |
| Autoprefixer | ^10.4.14 | CSS vendor prefixes |
| @vitejs/plugin-react | ^4.0.0 | React Fast Refresh |
No additional UI libraries, icon packages, or animation frameworks β everything is built with vanilla React, Tailwind, and CSS transitions.
The project currently uses CSS gradient placeholders for all project thumbnails and team photos. To replace them with real images:
- Add image files to
src/assets/orpublic/ - Replace the
PostThumbcomponent inBlog.jsxandLatestWork.jsxwith<img>tags - Update leadership avatar divs in
AboutUs.jsxwith<img>tags
npm run buildOutput is generated in the /dist folder. The site is fully static and can be deployed to any static host:
- Vercel β connect your repo, zero config
- Netlify β drag and drop the
/distfolder - GitHub Pages β push
/distcontents togh-pagesbranch - AWS S3 β upload
/distto an S3 bucket with static hosting enabled
Note for SPA routing: Since this project uses hash-based routing (
#/about,#/blogetc.), no server-side redirect configuration is needed. All routing happens entirely in the browser.
The primary accent #c3d219 is used directly in component files. To change it globally, do a find-and-replace across the src/ directory:
# Example: change to a new accent color
grep -rl '#c3d219' src/ | xargs sed -i 's/#c3d219/#YOUR_COLOR/g'Also update the cursor color in Cursor.jsx and the scrollbar thumb in index.css.
- Create
src/components/YourPage.jsx - Add a route in
App.jsx:if (hash === '#/your-page') return 'your-page' // ... {page === 'your-page' && <><YourPage /><Footer /></>}
- Add a nav link in
Navbar.jsx
Service pages follow the same pattern as WebDesign.jsx and WebDevelopment.jsx. Add the new route to the SERVICE_LINKS array in Navbar.jsx with its href and page key to get automatic active-state highlighting in the Services dropdown.
- Built with β€οΈ using Vite, React, and Tailwind CSS
- Subhro Chatterjee 2026