Web app untuk streamer/creator YouTube membuat tema visual untuk widget live chat (OBS Browser Source / Social Stream Ninja) melalui editor visual, tanpa CSS manual. Pengguna atur warna, font, layout, gaya per role, lalu preview real-time sebelum export CSS.
- Framework: Next.js 16 (App Router, Turbopack,
src/directory) - UI: shadcn/ui + Tailwind CSS
- State: Zustand (client-side)
- Validation: Zod (
ThemeConfigschema) - Database (V3): Postgres (Neon) via Drizzle ORM
- Auth (V3): Auth.js (Google OAuth)
- Deployment: Vercel
bun dev # Start dev server
bun build # Production build
bun lint # ESLint
bun typecheck # TypeScript check (tsc --noEmit)Setelah setiap task selesai: jalankan bun build dan bun typecheck sebelum lanjut.
src/
app/
page.tsx # Editor utama
layout.tsx
api/
themes/route.ts # POST (simpan) & GET (list publik)
themes/[id]/route.ts # GET by id
auth/[...nextauth]/ # Auth.js
gallery/page.tsx # Galeri komunitas (V3)
components/
ui/ # shadcn/ui components
editor/
ColorPicker.tsx
RoleColorPanel.tsx
FontSelector.tsx
LayoutControls.tsx
PresetSelector.tsx
PresetGallery.tsx
ExportPanel.tsx
SuperchatMembershipPanel.tsx
SaveThemeButton.tsx
ThemeCard.tsx
preview/
ChatPreviewFrame.tsx
lib/
theme-schema.ts # Zod schema + ThemeConfig type
css-generator/
generateCss.ts # Main generator function
generateCss.test.ts
cssCompatibility.test.ts # OBS CEF 103 guardrails (syntax/var/selector sync)
fontImport.ts # Google Fonts @import builder
templates/
base.ts # Base CSS template (generateBaseCss)
roles.ts # Role-specific CSS
layout.ts # Layout/avatar/spacing CSS
decorations.ts # Gradient row backgrounds per role
superchat.ts # Super Chat CSS
visual-effects.ts # Bubble/outline/shadow/skew CSS
presets/
index.ts # Export preset list
*.json # Preset files
presets.test.ts
preview/
mockChatDom.ts # YouTube DOM fixture (kanonik, dipakai test compat)
export/
downloadCss.ts
copyCss.ts
share/
urlEncoding.ts # Base64 theme encode/decode
store/
useThemeStore.ts # Zustand store
db/
index.ts # Drizzle client
schema.ts # Table definitions
migrations/
- Schema-first: Selalu define/update Zod schema di
lib/theme-schema.tssebelum buat generator atau UI baru. - Template dipisah: CSS template (struktur DOM) dipisah per file di
templates/, hanyagenerateCss.tsyang menggabungkan. - One task = one unit: Task tidak boleh menyentuh lebih dari 1 layer sekaligus kecuali dinyatakan.
- Default values eksplisit: Semua field baru wajib punya default value di schema, agent tidak boleh berimprovisasi.
- No comments: Jangan tambahkan comment di kode kecuali diminta.
- Keyboard accessible: Semua kontrol form harus bisa dioperasikan dengan keyboard.
{
roleColors: {
regular: string, // hex, default '#e0e0e0'
moderator: string, // hex, default '#5e84f1'
member: string, // hex, default '#2ba640'
owner: string, // hex, default '#ffd600'
},
fontFamily: string, // default 'Inter, sans-serif'
avatarSize: number, // px, 24-64, default 32
borderRadius: number, // px, 0-24, default 4
showDecorations: boolean, // default true
}Fungsi generateCss(config: ThemeConfig): string — template statis (struktur DOM tetap) + injeksi CSS variables dari config. Struktur DOM YouTube live chat (yt-live-chat-*) dianggap konstan; selector CSS dipisah di file template agar mudah di-update jika YouTube mengubah DOM.
- Baseline: OBS 28+ (Chromium 103 via CEF). OBS 27 dan lebih lama tidak didukung penuh (
gapdi flex, animasi, confetti). - Generated CSS harus bebas sintaks modern di atas Chromium 103:
oklch/oklab/color-mix/light-dark/lab/lch/hwb/color(),:has(),@layer/@scope/@container/@property,text-wrap. Selalu hitung warna ke hex/rgba saat generate, jangan output fungsi warna modern. - Semua referensi
var(--x)wajib didefinisikan di blok:root(guardrail otomatis dicssCompatibility.test.ts). - Selector elemen
yt-*baru di template CSS wajib ditambahkan juga ke fixturemockChatDom.ts(atau ke allowlist hide-only di test compat). - Update list "Hide Elements" di
templates/base.tsbila YouTube menambah elemen baru (contoh:yt-live-chat-pinned-message-renderer,yt-live-chat-membership-item-renderer,yt-live-chat-deleted-message-renderer).
- Semua input user (nama tema, config JSON) harus divalidasi via Zod sebelum diproses.
- CSS yang dihasilkan harus valid dan kompatibel dengan OBS Browser Source (Chromium Embedded Framework) dan Social Stream Ninja.
- Error validasi harus user-friendly, bukan raw Zod error.
P0-1 → P0-2 → P0-3 → P0-4
→ F1-1 → F1-2 → (F1-3, F1-7 paralel)
→ F1-4 → F1-5 → F1-6
→ F1-8 → F1-9
→ F1-10 → F1-11
→ F1-12, F1-13, F1-14 (paralel setelah F1-9)
→ F1-15 → F1-16
→ F1-17, F1-18 (paralel) → F1-19
→ F1-20 → F1-21 (gate manual sebelum Fase 2)
Penting:
- Jangan kerjakan Fase 2 sebelum F1-21 (Manual QA) dicentang manusia.
- Jangan kerjakan Fase 3 (DB tasks) tanpa
DATABASE_URLvalid. - Dependency ditulis eksplisit — jangan kerjakan task sebelum dependency selesai.