A premium full‑stack interior design showcase application featuring a cinematic hero, animated masonry portfolio, parallax enhanced storytelling sections, and a refined contact funnel — built with a TypeScript React frontend (Vite) and an Express + Drizzle ORM backend.
- Luxury Visual System: Glassy navigation, golden accent gradients, premium typography, subtle glow + sheen micro–interactions.
- Animated Portfolio: Masonry layout with Ken Burns ambience, scroll reveals, hover overlays, category filtering, and reduced‑motion fallbacks.
- Parallax Sections: Reusable
ParallaxSectioncomponent provides depth without overwhelming motion. - Accessible Contact Funnel: Validated form with ARIA live feedback, toast notifications, external FormBackend submission, and animated info cards.
- Theming + Dark Mode: Theme toggle with persisted preference.
- Modern Component Stack: Radix primitives + shadcn‑style UI composition (buttons, dialogs, navigation, form inputs, etc.).
- Typed Domain Layer: Drizzle ORM schema (
shared/schema.ts) with Zod validation helpers. - Single Deployment Surface: API + built client served from one Node process (ideal for Render deployment).
| Layer | Tech |
|---|---|
| UI / SPA | React 18, Vite, TypeScript, Wouter routing |
| Styling | Tailwind CSS, CSS utility animations, custom premium gradients |
| Motion | Framer Motion (scroll + entrance + ambient) |
| Data Layer | Drizzle ORM + Postgres (extensible) |
| Validation | Zod + drizzle-zod |
| Server | Express (single entry: server/index.ts) |
| Build | Vite build for client, esbuild bundle for server |
| Deployment | Render (single web service) |
root
├─ client/ # React + Vite frontend (root set to this in vite.config)
│ ├─ index.html
│ └─ src/
│ ├─ components/ # UI + premium sections
│ ├─ pages/
│ ├─ hooks/
│ ├─ lib/
│ └─ main.tsx # SPA bootstrap
├─ server/
│ ├─ index.ts # Express entry (serves API + static in prod)
│ ├─ routes.ts # (Extendable) API registration
│ └─ vite.ts # Dev integration + static serving
├─ shared/
│ └─ schema.ts # Drizzle schema + Zod types
├─ drizzle.config.ts # Drizzle CLI config
├─ tailwind.config.ts # Tailwind theme + tokens
├─ tsconfig.json # TS config for both client + server
├─ package.json # Scripts / deps
└─ README.md
- Node.js 18+
- (Optional) Postgres database if you extend user data (current routes are placeholder)
npm installnpm run devThis runs server/index.ts with Vite middleware (hot reload for the React app).
npm run checknpm run buildOutputs:
- Server bundle:
dist/index.js - Built client assets:
dist/public/*
npm startServes the prebuilt client + API on PORT (default 5000).
The contact form posts to FormBackend endpoint:
https://www.formbackend.com
Fields submitted: name, email, optional phone, message as multipart/form-data.
You can view / manage submissions via your FormBackend dashboard.
All scroll + reveal animations honor reduced motion preferences. To adjust parallax intensity, edit ParallaxSection props.
Currently server/routes.ts is a scaffold. Add routes like:
app.get('/api/health', (_req, res) => res.json({ ok: true }));Then redeploy. The logging middleware prints compact JSON summaries for /api/* responses.
If you provision a Postgres database:
- Set
DATABASE_URLin your environment. - Define tables in
shared/schema.ts. - Push schema:
npm run db:push(If DATABASE_URL is missing, drizzle.config.ts throws early to prevent silent misconfig.)
Include all files except those ignored by .gitignore (already excludes node_modules, build output, etc.). Make sure you commit:
client/,server/,shared/, config files,package.json,package-lock.json,drizzle.config.ts,tailwind.config.ts,tsconfig.json, assets underattached_assets/.
- Build Command:
npm run build - Start Command:
npm start - Environment: Node 18+ (Render default is fine)
- Add Environment Variables (optional):
PORT(Render supplies automatically)DATABASE_URL(if using Postgres / Drizzle)- Any auth or feature flags you add later
- Provision a Render Postgres instance.
- Copy its connection string into
DATABASE_URL. - Run a one-off deploy or use a job to execute:
npm run db:push.
Static assets are served from dist/public. Leverage long‑term caching by keeping file hashes (Vite handles this automatically).
After deploy completes:
curl -s https://your-service.onrender.com | headAdd a health route for better monitoring:
app.get('/api/health', (_req, res) => res.json({ status: 'ok' }));Do not commit secrets. Use Render Dashboard for all keys. .gitignore already excludes build artifacts.
- Add authentication (passport local already in deps) and protected routes.
- Introduce image optimization / CDN.
- Implement a real portfolio CMS (Headless or simple CRUD with Drizzle).
- Add integration tests with Vitest or Jest + supertest.
- Add skeleton loading states where data will be dynamic.
- Golden accent hex approximations:
#fde63e,#f8d64e,#f1b84b, softened variants for hover states. - Use
backdrop-blur+ layered translucent panels for premium depth. - Maintain accessible contrast — avoid pure gold text on light backgrounds without outline / shadow.
MIT © Interiorlogy
Crafted with focus on polish, performance, and accessibility.