Young Tbilisi Navigator - Claude Code Instructions
Instructions for working with the Young Tbilisi Navigator repository - a static web application for finding youth activities, clubs, and communities in Tbilisi for teenagers (13-18 years old).
Project Overview
This is a static web application with no build process. It features:
Interactive filtering by type, distance, tags, and languagesYandex Maps integration with clusteringGeolocation with multi-fallback strategyLocalStorage-based favorites managementDark/light themes with optional "rebel mode" stylingTech Stack
**Frontend**: Vanilla JavaScript, HTML5, CSS3 (no frameworks or dependencies)**Maps**: Yandex Maps API with clustering**Data**: JSON-based structure in `data/items.json`**Hosting**: Static file server (Python/Node.js)**Storage**: LocalStorage for preferences and favoritesDevelopment Workflow
Starting Development
Always use the Makefile for development tasks:
```bash
make dev # Start server and open browser
make serve # Simple server in terminal
make open # Open browser to app
make status # Check if server is running
make stop # Stop background server
make clean # Clean up PID/log files
```
**Important**: Never open `index.html` directly via `file://` protocol - CORS restrictions require a static server.
Environment Variables
`PORT`: Server port (default: 8088)`HOST`: Server host (default: localhost)Architecture
File Structure
`index.html`: Main page structure, metadata, Yandex Maps API script`app.js`: All application logic (single-file architecture)`style.css`: Complete styling with CSS custom properties`data/items.json`: Activity/location data`Makefile`: Development server commandsJavaScript Architecture
**Global State**:
`ITEMS`: Main data array loaded from JSON`map`, `clusterer`: Yandex Maps objects`userPos`: User geolocation coordinatesTheme and rebel mode stored in localStorage**Core Functions**:
`loadItems()`: Fetches and filters data (age >= 13)`render()`: Main UI rendering with debounced search`setupMap()`: Initializes Yandex Maps with clustering`applyFilters()`: Filters by type, distance, tags, languages`refreshPins()`: Updates map markers based on filters**Performance Features**:
Distance caching via `distanceCache` MapDebounced user inputs (150ms)Throttled map updates (120ms)Progressive card animation delaysData Schema
Items in `data/items.json` follow this structure:
```json
{
"id": "unique_identifier",
"title": "Display name",
"type": "online|offline",
"categories": ["tag1", "tag2"],
"age": {"min": 13, "max": 18},
"address": "Physical address or 'Онлайн-формат'",
"coords": {"lat": 41.715, "lng": 44.79},
"languages": ["ru", "en", "ge"],
"links": {"site": "url", "instagram": "url"},
"blurb": "Short description"
}
```
`coords` can be `null` for online-only activitiesAge range is inclusiveLanguages use ISO codesTheming System
Three-layer theming via CSS custom properties:
1. **Base theme**: Dark (default) or Light mode
2. **Rebel mode**: Alternative styling with gradients and grain effects
3. **Color tokens**: `--bg`, `--card`, `--text`, `--accent`, etc.
All theme values stored in localStorage and applied via data attributes on `<body>`.
Common Development Tasks
Adding New Activities
1. Edit `data/items.json` with proper schema
2. Get coordinates from Yandex Maps for the `coords` field
3. Ensure all required fields are present
4. Restart server to see changes (no build step needed)
Working with Maps
Yandex Maps API key is in `index.html` script tagMap initialization uses robust retry/polling via `initMapWhenReady()`Clustering automatically handles marker densityCustom balloon templates defined in `setupMap()`Geolocation Implementation
Multi-fallback strategy:
1. HTML5 Geolocation API (primary)
2. Yandex Geolocation API (fallback)
3. IP-based geolocation (last resort)
Distance calculation uses Haversine formula. HTTPS required for accurate geolocation (localhost is exempt).
Modifying UI/Styling
All styles in single `style.css` fileUse existing CSS custom properties for consistencyRespect theme variables for dark/light/rebel modesCard animations use progressive delaysKey Constraints
**No build process**: All code runs directly in browser**No dependencies**: Beyond CDN resources (Yandex Maps)**Static hosting only**: No server-side logic**LocalStorage only**: No backend database**Vanilla JavaScript**: No frameworks or transpilationTesting Checklist
When making changes, verify:
[ ] Server starts with `make dev`[ ] Map loads and displays markers[ ] Filtering works (type, distance, tags, language)[ ] Search with Cyrillic and Latin characters[ ] Geolocation fallback chain[ ] Favorites persist across sessions[ ] Theme switching (dark/light/rebel)[ ] Responsive layout on mobile[ ] All external links workImportant Notes
Target audience is teenagers 13-18 years oldInterface is primarily in RussianYandex Maps API is required (Google Maps not used)Distance filtering requires user geolocationOffline activities require valid coordinatesNo user authentication or backend services