Denis Stritar

AGENTS.md

Vendor-neutral rules for any AI coding agent working in this repo (Claude Code, Cursor, Codex, Copilot, Amp, Continue, Aider, etc.). Claude-specific and Copilot-specific pointer files redirect here — keep this as the single source of truth (the always-loaded hub). Task-specific playbooks live in .claude/skills/ and load on demand — see Skills below.

Project

Personal portfolio site for Denis Stritar (Berlin-based product designer). A rich, interactive experience: a time-of-day WebGL hero over a four-mood design system.

Routes

The site is a single page. The case-study route system (/work/<slug>, MDX, content-collections) was removed; don’t reintroduce it without asking. Case studies instead render in-page behind #work/<id> hashes — see Case-study article layer below. Still one route.

Path Source Purpose
/ app/page.tsx The whole site: header + tagline over the WebGL hero
/sitemap.xml app/sitemap.ts One entry
/404 app/not-found.tsx Custom branded 404
/robots.txt, /llms.txt, /humans.txt, /site.webmanifest public/ Static

Trailing slashes are enabled in next.config.ts for reliable GitHub Pages routing.

components/site/header.tsx — Figma nodes 81:303 / 79:253. A 48px row on the content column: 24px logo left, three 48×48 Button variant="ghost" size="icon" right (LinkedIn, theme toggle, cloud mode — node 81:287). --page-inset (16 / 24 / 32px) is still the distance from the top.

Case-study article layer

components/article/ — Figma node 97:313. Clicking a work tile morphs the rail into a small left-hand stack (full-screen sheet below 769px) and opens that tile’s case study in an opaque --panel surface. The cloud-mode architecture, applied again:

Design system & theming

Tokens are defined once in app/globals.css and documented in docs/tokens.md. The Figma “Portfolio” library mirrors them.

WebGL hero

Lives entirely in components/webgl/, mounted via HeroMount with dynamic(..., { ssr: false }) from a client wrapper (calling that from a Server Component errors in Next 16). Nothing 3D runs at build time.

Assets

Binary assets (3D models, HDR maps, favicons, resume) live in public/ and are served from the domain root (no basePath). Text faces are self-hosted by next/font at build time, not from public/. HDR maps light the scene only. public/assets/hdr/night.hdr is oversized (~4.3 MB) — compress to match the others (~140 KB) before launch.

Icons. public/icon.svg is the source of truth for the brand mark on disk — hand-authored, transparent, and it flips #2f2f2f#f7f5f4 via an embedded prefers-color-scheme rule (a favicon renders outside the document, so currentColor can’t work). Its geometry must stay in sync with LogoMark in components/icons/index.tsx. Everything else — favicon.ico (16/32/48), apple-touch-icon.png, icon-192.png, icon-512.png, icon-maskable-512.png — is generated by npm run icons (scripts/generate-icons.mjs) and committed; it is deliberately not wired into build. Rasters can’t adapt, so they ship the light treatment, opaque where the platform demands it. Icons are declared in lib/seo.ts + public/site.webmanifest — don’t also add app/icon.* file-convention files, as the two mechanisms would compete.

SEO invariants

Site-wide metadata: lib/seo.ts via app/layout.tsx.

Skills (progressive disclosure)

Load the matching playbook in .claude/skills/ before the task:

Don’t

Verify before reporting done

npm run typecheck
npm run build

Report exact output if either fails. The build fetches Outfit/Roboto Mono from Google Fonts via next/font — it needs network (CI has it; local builds need connectivity). out/ must contain index.html, 404.html, CNAME, llms.txt, humans.txt, robots.txt, sitemap.xml, .nojekyll, _next/, and assets/. Preview with npm run preview and smoke-test the WebGL, the header entrance, and the theme toggle in a browser.

Deploy

GitHub Actions: .github/workflows/deploy.yml. Push to master → Node 24 → npm run build → uploads ./out to the github-pages environment.