Skip to content

Repository files navigation

Kalapriti Designs

Website for Kalapriti Designs, an architectural and design consultancy.

React 19 + Vite, deployed to GitHub Pages at kalapritidesigns.com.


Naming

Brand and repository are both kalapriti: they were reconciled on 17 Sep 2026 when the repo was renamed from kalapreeti.

Brand, repository and deploy path are still different things, and conflating them broke production twice before the rename. The rules stand:

  • vite.config.js → base is the only place the deploy path is written.
  • Every asset URL is built with asset() from src/data/site.js, which reads import.meta.env.BASE_URL. Never hardcode the prefix in a component.
  • Every brand string comes from BRAND in src/data/site.js.

The site is served from the custom domain kalapritidesigns.com (set by public/CNAME), so base is /. It is read from VITE_BASE, so a one-off preview build for stackified.github.io/kalapriti/ can be produced with VITE_BASE=/kalapriti/ without editing the config. The absolute URLs in index.html, public/sitemap.xml and public/robots.txt point at kalapritidesigns.com.


Setup

npm install
npm run dev      # http://localhost:5173/
npm run build
npm run lint
npm run deploy   # builds, then publishes dist/ to the gh-pages branch

CI (.github/workflows/deploy.yml) runs lint, build and a build-output check on every push and pull request to dev and main. Only pushes to main publish dist/ to the gh-pages branch, which GitHub Pages serves at kalapritidesigns.com.

Structure

src/
  data/          all copy, services, process steps, contact details
  components/    Nav, Footer, Layout, Reveal, PageHeader, Picture, Cursor,
                 Atmosphere, FloatingActions
  lib/           motion.js (GSAP + ScrollTrigger entry point)
  pages/         Home, Projects, Services, Process, Resources, About, Contact, NotFound
  index.css      design tokens (colour, type, spacing)
  App.css        component styles
public/
  CNAME          custom domain (kalapritidesigns.com)
  assets/        images and logo files
  robots.txt, sitemap.xml

404.html (the GitHub Pages SPA fallback) is not in public/: it is generated into dist/ by vite.config.js at build time. See the note below.

Content lives in src/data/, not in components. To change a service, a process step or the phone number, edit the data file.

Routing on GitHub Pages

Pages has no SPA rewrite, so a deep link like /services would 404. 404.html, written into dist/ by a build plugin in vite.config.js (which derives pathSegmentsToKeep from the base), encodes the path into a query string and redirects to the index, where a snippet in index.html restores the URL before React mounts. Both halves must stay in step. Remove them if the site moves to a host with proper rewrites (Netlify, Vercel).

Design: "the drawing set"

The site reads as an architect's drawing set: a light beige sheet, a faint drafting grid with a heavier line every eighth cell, dusky olive as ink, and hairline rules and dimension lines as chrome. The per-page sheet codes were removed at the client's request (see src/components/PageHeader.jsx). Colour is the palette agreed with the client: white and beige grounds, a desaturated dusky olive green, and burgundy as the accent (tokens in src/index.css); type is EB Garamond for display over DM Sans.

Motion is owned by GSAP + ScrollTrigger (src/lib/motion.js is the single entry point). Lenis provides smooth scroll, synced to ScrollTrigger in Layout.jsx. The hero is one orchestrated timeline; the Process page is the showpiece: a sticky ghost numeral counts 01→06 and the rail fills as you scroll. Everything degrades to a fully readable static page under prefers-reduced-motion, and the hero has a safety timer so it can never stay clipped if a tab loads unfocused (rAF suspended).

Desktop-only extras (the drafting crosshair cursor and magnetic CTAs) run only with a fine pointer and stand down under reduced motion. The cursor, Lenis smooth scroll and the grain overlay sit behind FEATURES in src/data/site.js. Flip a flag to disable one.

Images

<Picture name="…" /> (src/components/Picture.jsx) emits AVIF → WebP → PNG with srcset, and always sets width/height from the manifest so layout shift is zero. Variants are generated by:

npm run images

(scripts/images.py, needs Pillow). To add a real project photo: drop it in public/assets, add a PLAN entry, run the script, reference it by name. The hero is preloaded from index.html so the LCP image starts with the HTML.

Known placeholders

Thing State
Projects Placeholder, flagged in UI via PROJECTS_ARE_PLACEHOLDER; hidden from menus (hidden: true in NAV)
Resources Prototype for client review (RESOURCES_ARE_PROTOTYPE); hidden from menus
Contact form Sends via WhatsApp; swap MODE in src/pages/Contact.jsx once an inbox exists
OG image Reuses hero.png; needs a 1200×630 card
Logo wordmark logo-mark.svg contains a live <text> element set in High Tower Text. That font is not embedded, so the "riti" glyphs fall back to a default serif on most machines. Ask the client for a version with the text converted to outlines.

Tech note

Vite 8.3.0 with @vitejs/plugin-react 6.1.1 · React 19 · wouter for routing (7 static routes; react-router was 25% of the bundle for no gain) · GSAP 3.15 + ScrollTrigger · Lenis 1.3. npm audit reports 0 vulnerabilities.

ESLint note: the config has no jsx-uses-vars, so a capitalised parameter used only as a JSX tag reads as unused. Bind it to a const instead (see Reveal.jsx).

License

Proprietary. Copyright (c) 2026 Kalapriti Designs. All rights reserved. Designed and developed by Stackified. See LICENSE.

About

Official architectural portfolio and studio website for Kalapreeti. Modern minimalist design with sophisticated interactive elements.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages