# AGENTS.md

Single-page Indonesian-language portfolio (`<html lang="id">`) built with Next.js 15 App Router, React 19, Tailwind CSS 3, and Framer Motion. No backend/API routes, no test suite, no CI.

## Commands

- `npm run dev` — dev server at http://localhost:3000
- `npm run lint` — `next lint` (deprecated upstream but still the only lint script; currently clean)
- `npx tsc --noEmit` — typecheck (no npm script)
- `npm run build` — static export; output is `out/` (deployed to cPanel `public_html`). `next start` is not available with `output: "export"`.
- There is no test runner. Do not invent test commands.

## Content and structure

- Editable content and its TypeScript types live in `src/data/portfolio.ts`. Edit that file instead of hardcoding copy in components; section headings (`eyebrow`, `title`, `description`) remain hardcoded inside each component.
- `src/app/page.tsx` is the only route. It composes `Background`, `Navbar`, `Hero`, `About`, `Skills`, `Certificates`, `Contact`, `Footer`.
- Section `id`s (`home`, `about`, `skills`, `certificates`, `contact`) must match `navItems`; `Navbar.tsx` uses `IntersectionObserver` on those IDs for active-state highlighting.
- `README.MD` is Indonesian content notes for the Skills / "Perangkat & Teknologi" section, not setup docs. The applied copy is `skillCategories` plus the heading/description in `Skills.tsx`.
- Path alias `@/*` maps to `src/*`.

## Data/type gotchas

- Icon fields are constrained unions: `Social.icon` (`github | linkedin | mail | whatsapp`) and `SkillCategory.icon` (`code | layers | database | network | cloud | wrench`). Adding a value requires updating the union and the matching `iconMap` / `categoryIcons` object in `SocialLinks.tsx` / `Skills.tsx`.
- `focusAreas` is untyped but its icons are mapped by `focusIcons` in `About.tsx` (`code | network | server | mentorship`); update both together.
- `Certificate.type` is `"Sertifikat" | "Ijazah"`. Certificate images are `placehold.co` placeholders; `profile.avatar` and `profile.cvUrl` point at files in `public/`.

## Styling conventions

- Tailwind uses semantic color tokens backed by CSS variables in `src/app/globals.css` (`bg-card`, `text-muted-foreground`, `border-border`, `bg-muted`, etc.). Prefer these over raw slate/indigo values for theme-safe UI.
- Reusable utility classes: `glass`, `text-gradient`, `section-padding`, `section-shell`, `card-hover`; decorative `grid-backdrop` and `noise`.
- Dark mode is class-based (`darkMode: "class"`). The no-flash inline script in `src/app/layout.tsx` reads `localStorage.theme` and defaults to light unless the value is exactly `"dark"`; `ThemeToggle.tsx` writes it. Keep both in sync when changing theme behavior.
- Use the `cn()` helper from `src/lib/utils.ts` for conditional/merged Tailwind classes.

## Gotchas

- `next/image` only allows `images.unsplash.com` and `placehold.co`. Add any new external image host to `images.remotePatterns` in `next.config.mjs`.
- Only files under `public/` are served (e.g. `/fotosaya.jpeg`, `/cv-m-asriadi.pdf`). The root `gambar/` copy of the photo is not publicly served; edit `public/fotosaya.jpeg` for the deployed site.
- Interactive components need `"use client"` (Framer Motion, hooks, browser APIs); layout/page and simple presentational components stay server components.
- `.next/`, `node_modules/`, and `tsconfig.tsbuildinfo` are generated; do not edit. This directory is not a git repository.
