# Atlas Super Club — Bali Premium, cinematic marketing and reservation platform for a fictional Bali super club, built on the Next.js App Router with a motion-first design language. ## Tech Stack | Concern | Library | | ---------------------------- | ---------------------------------------------------- | | Framework | Next.js 16 (App Router, Turbopack, React 19) | | Styling | Tailwind CSS v4 | | Scroll animation | GSAP 3 + `@gsap/react` (`useGSAP`) + ScrollTrigger | | Smooth scroll | Lenis, synced to `gsap.ticker` | | Cursor / micro-interactions | Motion (formerly Framer Motion) | | Validation | Zod v4 (shared client + server schema) | | Email notifications | Resend (optional, config-gated) | | Testing | Vitest + React Testing Library | | Language | TypeScript (strict, `noUncheckedIndexedAccess`) | ## Project Structure ``` atlas-super-club/ ├── src/ │ ├── app/ │ │ ├── api/ │ │ │ ├── guestlist/route.ts │ │ │ └── reservations/route.ts │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── page.tsx │ ├── components/ │ │ ├── layout/ # Navbar, Footer, CustomCursor, SmoothScrollProvider, GuestlistSignupForm │ │ ├── sections/ # Hero, MenuSection/FeaturedOfferings/MenuModal, About, VipPackages, │ │ │ # ImmersiveExperience, Testimonials, Reservations, Gallery │ │ └── ui/ # Container, Reveal (shared GSAP scroll-reveal primitive) │ ├── lib/ # data.ts (content), validation.ts (Zod), email.ts, utils.ts │ └── types/ # Shared domain types ├── tests/ # Vitest unit + integration tests ├── next.config.ts ├── postcss.config.mjs ├── tsconfig.json └── vitest.config.ts ``` ## Prerequisites - Node.js **20.9 or newer** (Node 22 LTS recommended) - npm 10+ ## Getting Started ### Installation ```bash npm install ``` ### Environment Variables ```bash cp .env.example .env.local ``` | Variable | Required | Purpose | | ---------------------------------- | -------------------------- | -------------------------------------------------------------------------------------- | | `NEXT_PUBLIC_SITE_URL` | **Yes** (production) | Base URL for `metadataBase`, canonical tags, Open Graph, sitemap, robots, JSON-LD. | | `RESEND_API_KEY` | No | Enables real email delivery via Resend for reservations/guestlist. | | `RESEND_FROM_EMAIL` | No | Sender address for outgoing notification emails. | | `RESERVATION_NOTIFICATION_EMAIL` | No | Concierge inbox receiving reservation/guestlist notifications. | If `RESEND_API_KEY` and `RESERVATION_NOTIFICATION_EMAIL` are unset, both API routes still validate and log requests server-side and return a successful response — only the email dispatch step is skipped. Supplying real credentials activates delivery with no code changes required. ### Development ```bash npm run dev ``` Visit `http://localhost:3000`. ### Testing ```bash npm run test # single run npm run test:watch # watch mode ``` Covers the Zod reservation schema (valid/invalid payloads, date boundaries, guest limits, error extraction) and the `MenuModal` component (open/close behavior, Escape key, focus handling, body scroll lock). ### Type Checking & Linting ```bash npm run typecheck npm run lint ``` ### Production Build ```bash npm run build npm run start ``` ## Architecture Notes - **Design tokens** (`void`, `gold`, `burnt`, `smoke`, `font-serif`, `font-sans`) are declared once via Tailwind v4's `@theme` block in `src/app/globals.css` and consumed as ordinary utility classes (`bg-void`, `text-gold`, etc.) throughout the codebase. - **`Reveal`** (`src/components/ui/Reveal.tsx`) is the single reusable GSAP ScrollTrigger fade/rise primitive used by every section; only `Hero` (headline stagger + floating card) and `ImmersiveExperience` (scroll-scrubbed parallax) implement bespoke GSAP timelines. All motion respects `prefers-reduced-motion`. - **Lenis** is instantiated once in `SmoothScrollProvider`, wired into `gsap.ticker` so Lenis and ScrollTrigger stay in sync, and exposes a `useSmoothScroll()` hook used by the navbar and in-page CTAs for offset-aware anchor scrolling. - **Custom cursor** is disabled automatically on coarse/touch pointers (`(pointer: coarse)`). - Gallery and Featured Offerings reuse only the exact image/video URLs supplied in the brief (plus the hero background reused once more for the gallery's largest tile) to avoid broken-image risk from unverified third-party URLs. Swap in the venue's own photography before launch. - The reservation and guestlist forms include an invisible honeypot field as a zero-dependency first line of spam defense, in addition to full Zod validation. ## SEO On-page and technical SEO only — no code-layer implementation guarantees search ranking; ranking depends heavily on off-page factors (see **Manual Steps Required**). - **Metadata** (`src/app/layout.tsx`): `metadataBase`, title template, canonical URL, full Open Graph + Twitter Card, `robots` directives, `verification.google` placeholder. - **JSON-LD structured data** (`src/components/seo/NightClubStructuredData.tsx`): `schema.org/NightClub` with address, geo-coordinates, opening hours, price range, `sameAs` social links. Uses placeholder business data — see `src/lib/seo.ts`. - **`app/sitemap.ts` / `app/robots.ts`**: generated automatically at `/sitemap.xml` and `/robots.txt`. - **`app/manifest.ts`**: web app manifest for installability and mobile presentation. - **`app/icon.tsx` / `app/opengraph-image.tsx`**: generated favicon and social share image, built from the same gold/void tokens — no additional static assets. - **Performance**: `preconnect` hints for the Unsplash/DigitalOcean CDNs, `next/font` with `display: swap`, `priority` on the LCP hero image — all contribute to Core Web Vitals. ### Manual Steps Required 1. **Google Search Console** — add the property, verify via the meta tag (replace the placeholder in `verification.google` in `layout.tsx`), then submit `https://yourdomain.com/sitemap.xml`. 2. **Google Business Profile** — for a physical venue, this plus reviews and NAP (name/address/ phone) consistency across directories typically drives more Maps-pack visibility than on-page SEO alone. 3. **Replace placeholder business data** in `src/lib/seo.ts` (address, geo-coordinates, phone) with real details before launch. 4. **Backlinks, content freshness, and reviews** remain the dominant long-term ranking factors and fall outside what any codebase can deliver. ## Security **Implemented** - Security headers in `next.config.ts`: `Content-Security-Policy`, `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, `Permissions-Policy`, `Strict-Transport-Security`. - Static (non-nonce) CSP, chosen to keep the site fully statically generated for performance/SEO, with `script-src`/`style-src` scoped to `'self' 'unsafe-inline'` (Next.js's documented pattern for non-nonce CSP) and `img-src`/`media-src` scoped to exactly the two external CDNs in use. - Shared client + server Zod validation on both API routes; honeypot field on both forms. - In-memory rate limiting (`src/lib/rate-limit.ts`, 5 requests/minute/IP) on `/api/reservations` and `/api/guestlist`. **Not covered — deploy-time responsibility** - The in-memory rate limiter resets per server instance; on serverless/multi-instance hosting it provides partial, not absolute, protection. Swap in Upstash Redis or edge rate limiting for guaranteed limits. - No WAF/DDoS layer — use the hosting provider's (Vercel, Cloudflare, etc.). - Keep dependencies patched: run `npm audit` and `npm outdated` regularly. Next.js 16 has had at least one critical (CVSS 10.0) advisory patched in a later 16.x point release — always install the latest 16.x rather than pinning an old patch version. - Secrets (`RESEND_API_KEY`, etc.) must be set as real environment variables on the host, never committed to source control. ## Known Limitations This project was authored in a sandboxed environment without npm registry access; `npm install`, `npm run build`, and `npm run dev` were not executed to confirm a clean compile. Source files were manually audited against current documentation for Next.js 16, Tailwind v4, GSAP/`@gsap/react`, Lenis, Motion, Zod v4, and Resend — including import/export consistency, prop naming, HTML nesting validity, and TypeScript strict-mode compliance. Run `npm install && npm run typecheck && npm run build` as the first verification step after cloning.