159 lines
7.2 KiB
Markdown
159 lines
7.2 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Project Overview
|
||
|
||
This is the official website for 밍글 스튜디오 (Mingle Studio), a motion capture studio located in Incheon, South Korea. The website is a multi-page static site built with vanilla HTML, CSS, and JavaScript, showcasing motion capture services, studio galleries, and client portfolios.
|
||
|
||
**Tech Stack:** Pure HTML5, CSS3 (with CSS Variables), Vanilla JavaScript (ES6+), no framework dependencies
|
||
|
||
## Architecture & Structure
|
||
|
||
### Page Architecture
|
||
The site follows a modular component-based structure:
|
||
|
||
- **Main Pages**: `index.html`, `about.html`, `services.html`, `portfolio.html`, `gallery.html`, `contact.html`, `qna.html`, `404.html`
|
||
- **Shared Components**: `components/header.html`, `components/footer.html`
|
||
- **Page-specific Assets**: Each page has dedicated CSS (`css/[page].css`) and JavaScript (`js/[page].js`) files
|
||
- **Common Assets**: `css/common.css` and `js/common.js` provide shared functionality
|
||
|
||
### Component Loading System
|
||
The site uses a dynamic component loading system implemented in `js/common.js`:
|
||
- Header and footer are loaded via `fetch()` API from `components/` directory
|
||
- **Fallback System**: Pages should include a static backup footer in HTML that gets hidden when dynamic loading succeeds (check `backupFooter` logic in `loadComponents()`)
|
||
- Components are initialized after DOM load with proper error handling
|
||
- Loading sequence: `showPageLoading()` → `loadComponents()` → `initLazyLoading()` → `hidePageLoading()`
|
||
|
||
### CSS Architecture
|
||
- **CSS Variables**: Defined in `:root` of `common.css` with motion capture/VTuber orange theme
|
||
- **Modular Approach**: Common styles in `common.css`, page-specific styles in separate files
|
||
- **Responsive Design**: Mobile-first approach with breakpoints at 768px and 1200px
|
||
- **Color Scheme**: Primary orange (`#ff8800`) with gradient variations for modern tech aesthetic
|
||
|
||
## Development Commands
|
||
|
||
### Server Options
|
||
|
||
**Node.js (권장):**
|
||
```bash
|
||
npm run dev # http://localhost:8000
|
||
npm start # 같은 기능
|
||
npm run serve # 같은 기능
|
||
npm test # 도움말 + 서버 시작
|
||
```
|
||
|
||
**Python (Alternative):**
|
||
```bash
|
||
python server.py # Custom server with auto-open on port 8001
|
||
python -m http.server 8000 # Basic Python server on port 8000
|
||
```
|
||
|
||
**Note:** The custom Python server (`server.py`) uses port 8001 and includes automatic port detection, browser opening, and clean URL support (`.html` extension optional).
|
||
|
||
### Development Features
|
||
- **Auto Browser Opening**: Python server automatically opens http://localhost:8001 (or available port)
|
||
- **Clean URLs**: `.html` extension optional for access (e.g., `/about` works as `/about.html`)
|
||
- **Dev Optimizations**: Cache disabled, CORS headers added
|
||
- **Port Auto-Detection**: Python server finds available ports from 8001-8020 if default is occupied
|
||
- **Error Handling**: Port conflicts and basic error scenarios handled gracefully
|
||
|
||
### Available URLs
|
||
When using npm scripts (port 8000):
|
||
- Homepage: http://localhost:8000/
|
||
- About: http://localhost:8000/about
|
||
- Services: http://localhost:8000/services
|
||
- Portfolio: http://localhost:8000/portfolio
|
||
- Gallery: http://localhost:8000/gallery
|
||
- Contact: http://localhost:8000/contact
|
||
- Q&A: http://localhost:8000/qna
|
||
|
||
When using `python server.py` (port 8001 or auto-detected):
|
||
- The server will display available URLs with the detected port
|
||
|
||
## Key Technical Details
|
||
|
||
### JavaScript Module System
|
||
- **Common Utilities** (`js/common.js`): Exports functions via `window.commonUtils` object for use in page-specific scripts
|
||
- Navigation handling with hamburger menu
|
||
- Notification system with 4 types (success, error, warning, info)
|
||
- Lazy loading for YouTube iframes and images using IntersectionObserver
|
||
- Loading state management (page-level and component-level)
|
||
- Utility functions: `debounce`, `throttle`, `isValidEmail`
|
||
- **Popup System** (`js/popup.js`): Cookie-based "don't show today" functionality for main page popups
|
||
|
||
### SEO Optimization
|
||
- Structured data (JSON-LD) with LocalBusiness schema for search engines
|
||
- Comprehensive meta tags including Open Graph, Twitter Cards, and Korean platform-specific tags
|
||
- Sitemap.xml without lastmod dates to prevent unwanted date display in search results
|
||
- Favicon system: Both ICO (`mingle-logo.ico`) and WebP (`mingle-logo.webp`) formats
|
||
|
||
### Image Management
|
||
- Studio images stored in `Studio_Image/` directory using WebP format for optimization
|
||
- Gallery system dynamically references these images with descriptive alt text
|
||
- Logo assets: `mingle-logo.webp` (primary) and `mingle-logo.ico` (favicon)
|
||
|
||
### Form Handling & Interactivity
|
||
- Contact form with real-time validation in `js/contact.js`
|
||
- Lazy loading implementation for performance optimization
|
||
- Scroll animations and intersection observers for modern UX
|
||
|
||
## Content Management
|
||
|
||
### Adding Gallery Images
|
||
1. Add new WebP images to `Studio_Image/` directory
|
||
2. Update `gallery.html` with new gallery items following the existing pattern:
|
||
```html
|
||
<div class="gallery-item">
|
||
<img src="Studio_Image/[filename].webp" alt="descriptive text" class="gallery-img" loading="lazy">
|
||
<div class="gallery-caption">Caption Text</div>
|
||
</div>
|
||
```
|
||
|
||
### Adding Portfolio Videos
|
||
- YouTube videos: Update `portfolio.html` with iframe embed using `data-src` for lazy loading
|
||
- SOOP/streaming VODs: Direct iframe source for broadcast examples
|
||
|
||
### Navigation Updates
|
||
When adding new pages, update `components/header.html` navigation links and ensure corresponding CSS/JS files follow the naming convention (`css/[page].css`, `js/[page].js`).
|
||
|
||
## Important Notes
|
||
|
||
### File Structure Conventions
|
||
- Each page has three files: `[page].html`, `css/[page].css`, `js/[page].js`
|
||
- Backup files may exist (e.g., `index_backup.html`, `index_new.html`) - these are not actively used
|
||
- All pages must include placeholders for dynamic components:
|
||
- `<div id="header-placeholder"></div>` for header
|
||
- `<div id="footer-placeholder"></div>` for footer
|
||
- Page-specific CSS and JS are loaded after common files for proper override capability
|
||
|
||
### Styling System
|
||
Access the orange motion capture theme via CSS variables defined in `common.css`:
|
||
```css
|
||
--primary-color: #ff8800;
|
||
--gradient-main: linear-gradient(135deg, #ff8800 0%, #ff6600 100%);
|
||
--navbar-height: 70px;
|
||
```
|
||
|
||
### Common Utilities Access
|
||
Page-specific scripts can access common functions via `window.commonUtils`:
|
||
```javascript
|
||
// Show notification
|
||
window.commonUtils.showNotification('Message', 'success');
|
||
|
||
// Validate email
|
||
window.commonUtils.isValidEmail('test@example.com');
|
||
|
||
// Use debounce/throttle
|
||
const debouncedFn = window.commonUtils.debounce(myFn, 300);
|
||
```
|
||
|
||
## Business Context
|
||
|
||
This website represents a motion capture studio business with:
|
||
- **Primary Service**: OptiTrack-based motion capture studio rental (22만원/hour)
|
||
- **Target Market**: VTubers, game developers, content creators
|
||
- **Location**: Incheon Techno Valley, unique positioning as Incheon's only motion capture facility
|
||
- **Technical Specs**: 28 OptiTrack cameras, 8×7m capture space
|
||
|
||
Understanding this context helps with content updates, SEO optimization, and feature development that aligns with the studio's business objectives. |