---
name: bukupintar-dev
description: Development tracking for Buku Pintar interactive multimedia learning platform for Kementerian Pendidikan Malaysia. Use this skill when working on bukupintar.html, admin.html, content.json, design.json or any related files.
---

# Buku Pintar — Development Tracker v2.1

## Files
| File | Purpose |
|------|---------|
| bukupintar.html | Main engine |
| admin.html | CMS |
| bukupintar.json | Settings & feature flags |
| design.json | Theme, backgrounds, layouts, character, tutorial |
| content.json | Content with multi-lang fields (_en, _zh, _ta) |
| language.json | UI translations (BM, EN, ZH, TA) |

## v2.1 Fixes & Features
- [x] **FIXED: Font size scaling** — now sets font-size on `<html>` element so ALL rem units scale properly
- [x] **FIXED: Three.js visibility** — darker particle color (#0d9488), bigger size (0.15), higher line opacity (0.2), reduced count (80), #bg-layer2 opacity set to 0.4 light / 0.6 dark
- [x] **Dark/Light toggle on Intro page** — top-right buttons on intro screen (theme + settings)
- [x] **Intro adapts to theme** — light theme = light gradient bg, dark theme = dark gradient bg
- [x] **Topic cards with images** — SVG-generated gradient header with floating circles + emoji icon per topic
- [x] **Topic image config** — design.json `topicImages` per topic ID with gradient, icon, pattern
- [x] **Layout management** — ./layout/<name>/ paths, add/delete/select active in admin
- [x] **Activity/Assessment creator** — generates downloadable HTML template, user places in ./activity/<name>/ or ./assessment/<name>/
- [x] **Proper JSON export** — admin downloads content.json and design.json that bukupintar.html reads directly
- [x] **Dark mode toggle** in topbar (🌙/☀️ button)

## Architecture Notes
- Font scaling: `html.fs-small{font-size:14px}`, `html.fs-medium{16px}`, `html.fs-large{18px}`, `html.fs-xlarge{20px}` — all rem units scale from this
- Three.js bg: opacity controlled via `#bg-layer2{opacity:.4}` with dark theme override to `.6`
- Topic cards: `topicImgSVG()` generates inline SVG with circles + gradient + emoji — no external images needed
- Layouts: stored in `design.json > layouts.items[]` with id, name, path, description, active flag
- Activity/Assessment: admin creates HTML template with postMessage scaffold, user downloads and places in folder

## v2.2 — Video Overlay (Layer 3)
- [x] Video Overlay Layer — per-page configurable video overlay as Layer 3
- [x] Chroma Key — real-time canvas-based: pick color, set tolerance, transparent pixels
- [x] Video Controls — loop, autoplay, muted toggles per page
- [x] Clickthrough — toggle pointer-events so video doesn't block content
- [x] Opacity — slider 0-1
- [x] Responsive Sizing — separate width/height/position for Desktop, Tablet, Mobile
- [x] Admin: Full Layer 3 UI — collapsible video config per page with all controls
- [x] Engine: VideoOverlay object — manages lifecycle, chroma key canvas loop, responsive resize
- [x] Auto-applies on navigation

### Layer 3 Schema
```json
"layer3": {
  "type": "video",
  "src": "./video/character.webm",
  "loop": true, "autoplay": true, "muted": true,
  "opacity": 1, "clickthrough": true,
  "chromaKey": { "enabled": true, "color": "#00ff00", "tolerance": 80 },
  "desktop": { "width": "280px", "height": "auto", "top": "auto", "right": "24px", "bottom": "24px", "left": "auto" },
  "tablet":  { "width": "220px", "height": "auto", ... },
  "mobile":  { "width": "160px", "height": "auto", ... }
}
```

### Chroma Key Notes
- Canvas with willReadFrequently for pixel manipulation
- Each frame: drawImage → getImageData → zero alpha for matching pixels → putImageData
- requestAnimationFrame loop, pauses when video paused
- Tolerance: per-channel abs diff < threshold = transparent
- Recommended: .webm with alpha (no chroma needed) or green-screen .mp4

## v2.3 — Theme-Aware Backgrounds
- [x] Backgrounds now support separate light/dark theme configs
- [x] design.json: `backgrounds[page].light` and `backgrounds[page].dark` — each with layer1/2/3
- [x] bukupintar.html: `getBgForPage(pageKey)` resolves config based on active theme, falls back to light
- [x] `applyBgLayer1(pageKey)` dynamically sets bg-layer1 color/gradient/image per page+theme
- [x] `reapplyBgForTheme()` called on theme toggle — all 3 layers re-apply instantly
- [x] Backwards compatible: legacy flat format (no light/dark) still works
- [x] Admin: ☀️ Cerah / 🌙 Gelap tabs per page in background editor
- [x] Dark theme tab styled with dark bg/text for visual clarity
- [x] All 3 layers (color/gradient/image, Three.js/Vanta, Video+Chroma) configurable independently per theme
