# CLAUDE.md - CheapIndex Project Context

## Project Structure
```
project/
├── index.php       (main script, all settings at top)
├── index.md        (content / data)
└── assets/         (CSS, JS, images, local pico.min.css)
```

## Settings Reference
| Variable | Default | Purpose |
|----------|---------|---------|
| `$set_title` | `'Made with CheapIndex'` | Page `<title>` and OG title |
| `$set_description` | — | Meta description |
| `$site_author` | — | Meta author |
| `$site_language` | `'en'` | HTML lang attribute |
| `$favicon_url` | — | Favicon URL |
| `$show_profile_header` | `false` | Show GitHub profile card at top |
| `$github_username` | — | GitHub username for profile card |
| `$set_realname` | — | Display name in profile card |
| `$dateFormat` | `'d M Y'` | Footer timestamp format |
| `$set_font` | `'Poppins'` | Google/Bunny font name |
| `$set_backgroundcolor` | `'#e6f2ff'` | Light mode background |
| `$set_dark_backgroundcolor` | `'#2d2d2d'` | Dark mode background |
| `$print_contact_footer` | — | Contact line in footer |
| `$set_social_media_preview` | — | OG/Twitter preview image URL |
| `$enable_line_numbers` | `false` | Line numbers in code blocks |
| `$umami_website_id` | — | Umami analytics ID (leave `''` to disable) |
| `$local_dev_mode` | `false` | `true` = local CSS, `false` = CDN |
| `$local_pico_css` | `'assets/pico.min.css'` | Local CSS path (used when `$local_dev_mode = true`) |
| `$color_note_bg` | `'#fed056'` | NOTE alert background color |
| `$color_warn_bg` | `'#fff3e0'` | WARN alert background color |
| `$show_theme_toggle` | `true` | Show light/dark toggle button |
| `$default_theme` | `'light'` | Default theme: `'light'` or `'dark'` |
| `$markdownFile` | `'index.md'` | Content file path |

## Markdown Syntax Features
| Syntax | Output |
|--------|--------|
| `# H1–H6` | `<h1 id="slug">...</h1>` (auto anchor ID) |
| `[NOTE]...[/NOTE]` | `<div class="alert note">` |
| `[WARN]...[/WARN]` | `<div class="alert warn">` |
| `:::center...:::` | `<div class="center-block">` (any content) |
| `:::carousel...:::` | Image carousel/slider |
| `![alt](url){.center}` | Centered image |
| `[text](url){.btn-green}` | Green button link |
| `[text](url){.btn-green .center}` | Centered green button |
| `### ![](icon.svg) Heading` | Heading with inline icon |
| `1. 2. 3.` | Ordered list (preserves start number via `<ol start="N">`) |
| `` `code` `` | `<code>` (HTML-escaped) |
| `` ```code``` `` | `<pre><code>` (placeholder-protected) |
| `\| table \|` | `<table>` |
| `---` / `***` | `<hr>` |

## Critical Rules
- **NEVER remove or reorder the placeholder system** — code blocks, inline code, and alerts are replaced with numbered tokens (`___PROTECTED_CODE_N___`) before inline parsing and restored after. Order matters.
- `htmlspecialchars()` is used for inline `` `code` `` only, never for block code
- CSS uses custom properties: `:root` for light, `[data-theme="dark"]` for dark
- Dark mode: `data-theme` attribute on `<body>` + `localStorage`; default set via `$default_theme`
- Font applied via `--font-system` CSS variable — `h1–h6` need explicit `font-family` rule to override PicoCSS defaults
- Routing is multi-page capable via `$_SERVER['SCRIPT_NAME']` + `$_SERVER['REQUEST_URI']`

## CSS Structure
```css
:root {
  --font-system: "{font}", sans-serif;
  --color-bg: #e6f2ff;
}
[data-theme="dark"] {
  --color-bg: #2d2d2d;
}
h1, h2, h3, h4, h5, h6 { font-family: var(--font-system); }
```

## External Dependencies
- PicoCSS v2: `cdn.jsdelivr.net/npm/@picocss/pico@2`
- Fonts: Bunny Fonts (`fonts.bunny.net`) — privacy-friendly Google Fonts alternative
- Icons: inline SVG only (no FontAwesome)
- Analytics: Umami (optional, self-hosted)

## Security
- Never commit `.env` files
- Use `htmlspecialchars()` on all user inputs
- Use PDO prepared statements for any SQL
- Add CSRF tokens to forms where applicable

## Dev Commands
```bash
# PHP syntax check
php -l index.php

# Local server
php -S localhost:8000

# Test routing
curl localhost:8000/contact

# Debug
grep -n "ERROR\|FIXME" *.php
```

## Troubleshooting
| Problem | Solution |
|---------|----------|
| Routing fails | Check `$_SERVER['SCRIPT_NAME']` |
| CSS not loading | Check `$local_dev_mode` and `$local_pico_css` path |
| Code block corruption | Check placeholder order in parser |
| Dark mode broken | Check `localStorage` and `data-theme` on `<body>` |
| Font not applying to headings | Add explicit `font-family` rule for `h1–h6` |
| Ordered list starts at 1 | Parser uses `<ol start="N">` — check `$olOpen` logic |

## Commit Guidelines
- Prefixes: `feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `test:`, `chore:`
- Keep commits small and atomic
- Update CHANGELOG.md if applicable
