---
name: dinkbit-frontend-developer
description: Use whenever building or modifying frontend UI — components, pages, layouts, or full applications — where pixel-accurate fidelity to a design, polished interactions/animations, responsive and adaptive behavior across desktop/mobile, and performance all matter. Trigger on requests to build components, implement a design/mockup/Figma/XD file, add animations or micro-interactions, fix responsive/mobile layout issues, build landing pages or dashboards, or optimize frontend performance — even if the user doesn't say "frontend" or "UI" explicitly. Covers look, feel and fidelity; for public pages load ship-ready-frontend too (crawlability, head/meta, robots, sitemap, checks).
---

# Frontend Developer

Execution standards distilled from analysis of 7 production repos (5 Astro, 2 Laravel/Blade — same studio, several scaffold generations). Every convention here was observed working in shipped code; the systematic gaps found in those repos (invisible focus states, missing reduced-motion handling, and the ones a 2026-10 review of two client previews surfaced: reveals that hide content without JS, disabled zoom, overflow hidden on body, sub-16px inputs) are corrected, not copied; see Non-negotiables. Nothing in this skill is invented "best practice" — where the repos had no pattern, this skill stays silent.

## The bar

A deliverable is done when it: (1) matches the design source at every checked viewport, not just at breakpoints; (2) has designed hover/focus/active states and motion with intentional timing on everything interactive; (3) adapts interaction models across desktop/mobile, not just reflows; (4) ships zero CLS, lazy weight, and a calm reduced-motion path; (5) passes the numbered checklist. "Looks close" fails; "renders correctly but animates generically" fails.

## Workflow

### 1. Ingest before you build

- Identify the design source (Figma/XD export, screenshot, prod URL) and the target stack. Never guess the stack — read the project's existing config (package.json, tailwind config/CSS, component folder) first.
- **Extract tokens first**, components second → read [references/design-tokens.md](references/design-tokens.md). Output of this step: a `@theme` block (or v3 config) with `misc-/brand-/state-` color namespaces, font roles, and the breakpoint scale — plus the five structural primitives (Section, Box, H, Button, Fields) if the project lacks them.
- Decide the scaling model *now* (fixed-rem vs fluid scaled-artboard) → criteria in [references/responsive-adaptive.md](references/responsive-adaptive.md). Retrofitting fluid scaling later is a rewrite.

### 2. Compose

- Pages are pure composition: parametrized section components stacked with content from data/i18n and spacing tuned via utility overrides. Sections compose the primitives. Sub-parts nest inside their section's folder.
- Organization: `sections/` (page-level blocks, PascalCase folder each) vs `components/` (reusable primitives). Client JS co-located next to its component.
- State-as-attribute: JS toggles attributes (`css-sticky`, `css-error`, `data-fade-show`); CSS owns all visual response.

### 3. Add motion deliberately

→ read [references/animation-interaction.md](references/animation-interaction.md) before writing any animation code.
Defaults: 0.2s micro-interactions; 0.6–1s entrances; IntersectionObserver reveals whose hidden state applies only under `html.js` (set by an inline `<head>` script before paint), never on the hero/LCP; GSAP+Lenis only for scroll-storytelling; reduced-motion coverage is mandatory, not optional polish. Every hover has a designed destination.

### 4. Make it responsive AND adaptive

→ read [references/responsive-adaptive.md](references/responsive-adaptive.md).
New projects: Tailwind v4 default breakpoints (sm 640 · md 768 · lg 1024 · xl 1280 · 2xl 1536) plus 320/375 base; existing projects keep their configured scale (the studio scale 375/600/768/1024/1200/1366/1440 with max-width `_` twins); swap components when the interaction model changes per device; drop decorative layers on mobile; art-direct hero imagery per orientation.

### 5. Keep it fast

→ read [references/performance.md](references/performance.md).
Zero-JS baseline with an escalation ladder (vanilla → Alpine → framework island); images with explicit dimensions + 2×-DPR responsive sizes; ≤2 self-hosted font families; heavy libs scoped to the components using them.

### 6. Keep it accessible

→ read [references/accessibility.md](references/accessibility.md).
`:focus-visible` rings (never suppress outlines), landmarks + honest heading levels, labeled icon-controls, three-phase async feedback, AA contrast in every theme.

### 7. Before calling anything done

→ run [references/execution-checklist.md](references/execution-checklist.md) — 47 numbered, testable items; ⛔ items are hard blockers. Verify visually at every breakpoint and diff against the design source. If the ai-site-review skill is installed, its `scripts/render_check.mjs` sweeps the breakpoints (overflow, inputs <16px, axe, screenshots) in one command.

## Reference files (read on demand, not upfront)

| File | Read when |
|---|---|
| [references/design-tokens.md](references/design-tokens.md) | Starting any project/feature; deriving tokens from a design file; building the primitive set |
| [references/animation-interaction.md](references/animation-interaction.md) | Adding any motion, hover mechanics, scroll behavior, sticky chrome, carousels/tickers/toasts |
| [references/responsive-adaptive.md](references/responsive-adaptive.md) | Choosing the scaling model; layout shifts across devices; nav patterns; verification matrix |
| [references/performance.md](references/performance.md) | Project setup; adding images/fonts/libraries; before shipping a page |
| [references/accessibility.md](references/accessibility.md) | Building interactive components/forms; the pre-done audit |
| [references/execution-checklist.md](references/execution-checklist.md) | Always, before declaring any deliverable complete |

## Variant selection (don't force a stack)

| If the project… | Then |
|---|---|
| Uses Tailwind v4 | CSS-first `@theme` tokens (works in any framework — Blade uses `@source` globs) |
| Uses Tailwind v3 | Same token names in `tailwind.config.js` `theme`; `theme()` in component CSS |
| Uses another styling system | Keep the namespaces as CSS custom properties; the token architecture is CSS, not Tailwind |
| Is a content/product surface | Fixed-rem scaling (default) |
| Is an art-directed campaign/illustration site | Fluid scaled-artboard system (vw-calibrated spacing/type) |
| Needs simple toggles/accordions | Alpine.js (or vanilla) — not a framework island |
| Needs stateful search/filters/wizards | Framework island (React/Vue/Svelte per project), still inside a static shell |
| Needs scroll-storytelling | GSAP ScrollTrigger + Lenis, scrubbed, with reduced-motion branch |
| Only needs reveals/marquees | CSS keyframes + IntersectionObserver — no animation library |
| Already has component/primitive conventions | Follow them; map these patterns onto its names rather than importing this catalog wholesale |

## Non-negotiables (corrections to the source material)

1. Never ship `*:focus { outline: none }` — style `:focus-visible` instead.
2. Never ship motion without a `prefers-reduced-motion` path.
3. Never `transition: all` — enumerate properties.
4. Never animate layout properties — transforms/opacity only.
5. Never interpolate class names (`gap-${n}`).
6. Never leave commented-out code, placeholder images, or `console.*` in the deliverable.
7. Never hide content in a way that needs JS to undo: reveal hidden states live under `html.js` (`<script>document.documentElement.classList.add('js')</script>` first thing in `<head>`), so no-JS readers, crawlers and link previews still see everything. Never fade in the hero/LCP text or image.
8. Never disable zoom: viewport is exactly `width=device-width, initial-scale=1` (no `user-scalable=no`, no `maximum-scale`).
9. Never `overflow-x: hidden` on `html`/`body` to hide horizontal scroll. Find the element that overflows and fix it; clip decorative overflow on its own wrapper with `overflow: clip`.
10. Form controls are at least 16px (`text-base`) on mobile, or iOS zooms in on focus.
11. A decorative background video is never the LCP: preload the poster `<img>`, start the video on first interaction or after ~10 s, and pause controls stay reachable.
12. Third parties (GTM, captcha, booking/chat embeds) load on first use, not in `<head>`: GTM after `load` + idle.
13. No text under 12px (check `font:` shorthands as well as `font-size`). Raising a 9–11px label to the floor can break the box it was sized for (a caption that spills out of a 112px card, a QR label wider than its 52px square): recheck every fixed-size box whose text you resized, and on small screens visually hide redundant labels (keep them for screen readers) rather than shrink them back.
14. Content parity across breakpoints: every content block visible on desktop is visible on mobile. Layouts may reflow, collapse into accordions or move into a menu; they never drop content. The classic bug is a 3-column grid that becomes 2 columns with `:nth-child(3){display:none}` and silently hides a third of the speakers/products/team. Dissolve the column wrappers instead (`display:contents`, `order` for sequence). `ai-site-review/scripts/render_check.mjs` fails a width that is missing blocks the widest width shows.
15. WebGL/canvas effects and intro loaders never hold the page: effects start after `load` + idle, loaders unlock scroll when their exit starts (details in animation-interaction.md).
