# BLACK HEART DANCE HOUSE — Project Context

## About
Landing page for "BLACK HEART DANCE HOUSE" — a pole dance school in Minsk, Belarus.
Instagram: @blackheartdancehouse
Content language: Russian

## Tech Stack
- **Next.js 16** (App Router, TypeScript, Turbopack)
- **Tailwind CSS v4** (dark mode only, gold/black theme)
- **lucide-react** for icons
- **better-sqlite3** for SQLite database
- **Fonts**: Inter (body) + Oswald (headings) via `next/font`
- **Hosting**: Vercel (planned)

## Code Style
- Function declarations for components (not arrow functions)
- PascalCase for component files, camelCase for utils
- `@/` path alias for imports
- `next/image` with `unoptimized` for PNGs that need transparency preserved
- Header nav uses `lg:` breakpoint (1024px) for desktop/mobile switch (9 nav links + CTA need the space)

## Project Structure
```
src/
├── app/
│   ├── layout.tsx          # Root layout, fonts, metadata
│   ├── page.tsx            # Landing: Hero → About → Classes → Team → [OpenDay] → Schedule → Pricing → MasterClasses → News → FAQ → Contact
│   ├── globals.css         # Tailwind imports
│   ├── styles/
│   │   ├── theme.css       # Theme variables, semantic classes
│   │   └── animations.css  # Keyframes, scroll reveal, modal animations
│   ├── admin/
│   │   ├── page.tsx        # Dashboard with 13 section cards
│   │   ├── login/          # Password auth
│   │   ├── layout.tsx      # Sidebar nav shell (14 items)
│   │   ├── _components/    # SectionEditor, FormField, ArrayEditor, NotifyToggle
│   │   ├── meta/           # SEO editor
│   │   ├── hero/           # Hero editor
│   │   ├── about/          # About editor
│   │   ├── team/           # Team list + [id] editor
│   │   ├── classes/        # Classes editor with icon picker
│   │   ├── master-classes/ # MC editor with registrations + notification toggles
│   │   ├── open-day/       # Open Day event editor (settings + grid + bookings)
│   │   ├── schedule/       # Schedule editor
│   │   ├── bookings/       # Group booking management with notification toggles
│   │   ├── pricing/        # Pricing editor
│   │   ├── faq/            # FAQ editor
│   │   ├── news/           # News editor
│   │   └── contact/        # Contact editor
│   └── api/
│       ├── auth/login/     # POST login
│       ├── logout/         # POST logout
│       ├── admin/
│       │   ├── sections/[key]/ # GET/PUT section data
│       │   ├── team/           # CRUD team members
│       │   ├── team/[id]/      # GET/PUT/DELETE single member
│       │   ├── team/reorder/   # PUT reorder
│       │   ├── upload/         # POST file upload (whitelisted folders)
│       │   ├── mc-registrations/ # CRUD registrations + notification toggle
│       │   ├── group-bookings/ # CRUD group bookings + notification toggle
│       │   ├── open-day/       # CRUD events
│       │   ├── open-day/classes/ # CRUD event classes
│       │   ├── open-day/bookings/ # CRUD event bookings + notification toggle
│       │   └── validate-instagram/ # GET check username
│       ├── master-class-register/ # POST public MC signup
│       ├── group-booking/    # POST public group booking
│       └── open-day-register/ # POST public Open Day booking
├── components/
│   ├── layout/
│   │   ├── Header.tsx      # Sticky nav, mobile menu, booking modal ("use client")
│   │   └── Footer.tsx
│   ├── sections/
│   │   ├── Hero.tsx        # Hero with animated logo, floating hearts
│   │   ├── About.tsx       # About with stats (trainers, classes, locations)
│   │   ├── Team.tsx        # Carousel + profile view
│   │   ├── Classes.tsx     # Showcase layout with icon selector
│   │   ├── MasterClasses.tsx # Cards with signup modal
│   │   ├── OpenDay.tsx      # Open Day schedule grid + booking (conditional)
│   │   ├── Schedule.tsx    # Day/group views with filters
│   │   ├── Pricing.tsx     # Tabs: prices, rental, rules
│   │   ├── News.tsx        # Featured + compact articles
│   │   ├── FAQ.tsx         # Accordion with show more
│   │   └── Contact.tsx     # Info + Yandex Maps iframe
│   └── ui/
│       ├── Button.tsx
│       ├── SectionHeading.tsx
│       ├── BookingModal.tsx     # Booking form → Instagram DM + DB save
│       ├── MasterClassSignupModal.tsx # MC registration form → API
│       ├── OpenDaySignupModal.tsx # Open Day class booking → API
│       ├── NewsModal.tsx        # News detail popup
│       ├── Reveal.tsx           # Intersection Observer scroll reveal
│       ├── BackToTop.tsx
│       └── ...
├── data/
│   └── content.ts          # Fallback Russian text (DB takes priority)
├── lib/
│   ├── constants.ts        # BRAND constants, NAV_LINKS
│   ├── config.ts           # UI_CONFIG (thresholds, counts)
│   ├── db.ts               # SQLite DB, 6 migrations, CRUD for all tables
│   ├── auth.ts             # Token signing (Node.js)
│   ├── auth-edge.ts        # Token verification (Edge/Web Crypto)
│   ├── content.ts          # getContent() — DB with fallback
│   └── openDay.ts          # getActiveOpenDay() — server-side Open Day loader
├── proxy.ts                # Middleware: auth guard for /admin/*
└── types/
    ├── index.ts
    ├── content.ts           # SiteContent, TeamMember, ClassItem, MasterClassItem, etc.
    └── navigation.ts
```

## Brand / Styling
- **Accent**: gold (`#c9a96e` / `hsl(37, 42%, 61%)`)
- **Background**: `#050505` – `#0a0a0a` (dark only)
- **Surface**: `#171717` dark cards
- Logo: transparent PNG heart with gold glow, uses `unoptimized`

## Content Data
- Primary source: SQLite database (`db/blackheart.db`)
- Fallback: `src/data/content.ts` (auto-seeds DB on first access)
- Admin panel edits go to DB, site reads from DB via `getContent()`
- 12 team members with photos, Instagram links, bios, victories, education
- 6 class types (Exotic Pole Dance, Pole Dance, Body Plastic, etc.)
- Master classes with date/time slots and public registration
- 2 addresses in Minsk, Yandex Maps embed with markers
- Contact: phone, Instagram (no email)

## Admin Panel
- Password-based auth with HMAC-SHA256 signed JWT (24h TTL)
- Cookie: `bh-admin-token` (httpOnly, secure in prod)
- Auto-save with 800ms debounce on all section editors
- Team members: drag-reorder, photo upload, rich bio (experience, victories, education)
- Master classes: slots, registration viewer with notification tracking (confirm + reminder), trainer/style autocomplete
- Group bookings: saved to DB from BookingModal, admin page at `/admin/bookings` with notification toggles
- Open Day: event settings (date, pricing, discount rules, min bookings), schedule grid (halls × time slots), per-class booking with auto-cancel threshold, public section after Hero
- Shared `NotifyToggle` component (`src/app/admin/_components/NotifyToggle.tsx`) used across MC registrations, group bookings, and Open Day bookings
- File upload: whitelisted folders (`team`, `master-classes`, `news`, `classes`), max 5MB, image types only

## Security Notes
- **CSRF protection**: Double-submit cookie pattern. Login sets `bh-csrf-token` cookie (JS-readable). All admin fetch calls use `adminFetch()` from `src/lib/csrf.ts` which sends the token as `X-CSRF-Token` header. Middleware (`proxy.ts`) validates header matches cookie on POST/PUT/DELETE to `/api/admin/*`. **Always use `adminFetch()` instead of `fetch()` for admin API calls.**
- File upload validates: MIME type, file extension, whitelisted folder (no path traversal)
- API routes validate: input types, string lengths, numeric IDs
- Public MC registration: length-limited but **no rate limiting yet** (add before production)

## Upcoming Features
- **Rate limiting** on public endpoints (`/api/master-class-register`, `/api/group-booking`, `/api/open-day-register`)
- **DB backup mechanism** — automated/manual backup of `db/blackheart.db` with rotation

## AST Index
- **Always use the AST index** at `memory/ast-index.md` when searching for components, props, hooks, types, or styles
- Contains: component tree, all exports, props, hooks, client/server status, CSS classes, keyframes
- Update the index when adding/removing/renaming files or exports

## Database Migrations
- **Never drop/recreate the database** — admin data (photos, edits, registrations) lives there
- Schema changes go through versioned migrations in `src/lib/db.ts` (`migrations` array)
- Add a new entry with the next version number; never modify existing migrations
- Migrations run automatically on server start via `runMigrations()` and are tracked in the `_migrations` table
- Use `CREATE TABLE IF NOT EXISTS` and column-existence checks (`PRAGMA table_info`) for safety

## Turbopack / Dev Server Troubleshooting
If the dev server hangs on "Compiling..." or shows a white page:
1. Kill all node processes: `taskkill /F /IM node.exe`
2. Remove stale lock: `rm -f .next/dev/lock`
3. Clear cache: `rm -rf .next node_modules/.cache`
4. Restart: `npm run dev`
- This often happens after shutting down the PC without stopping the server first
- Always stop the dev server (Ctrl+C) before shutting down

## Git
- Remote: Gitea at `git.dolgolyov-family.by`
- User: diana.dolgolyova
- Branch: main
