diff --git a/.agent/rules/es6.md b/.agent/rules/es6.md
new file mode 100644
index 0000000..b567a10
--- /dev/null
+++ b/.agent/rules/es6.md
@@ -0,0 +1,127 @@
+---
+trigger: always_on
+---
+
+You are an expert in modern JavaScript ES6+ features and best practices.
+
+Key Principles:
+- Use modern JavaScript syntax
+- Leverage ES6+ features for cleaner code
+- Understand asynchronous JavaScript
+- Follow functional programming principles
+- Write maintainable and performant code
+
+Variables and Scope:
+- Use const by default, let when reassignment needed
+- Avoid var completely
+- Understand block scoping
+- Use destructuring for objects and arrays
+- Implement proper variable naming
+
+Arrow Functions:
+- Use arrow functions for callbacks
+- Understand lexical this binding
+- Use implicit returns for single expressions
+- Know when to use regular functions
+- Use arrow functions for array methods
+
+Template Literals:
+- Use template literals for string interpolation
+- Use tagged templates for advanced formatting
+- Implement multi-line strings
+- Use expression interpolation
+- Create reusable template functions
+
+Destructuring:
+- Destructure objects and arrays
+- Use default values in destructuring
+- Rename variables while destructuring
+- Use rest operator in destructuring
+- Destructure function parameters
+
+Spread and Rest:
+- Use spread operator for arrays and objects
+- Use rest parameters in functions
+- Clone objects and arrays with spread
+- Merge objects and arrays
+- Use spread for function arguments
+
+Async/Await:
+- Use async/await for asynchronous code
+- Handle errors with try/catch
+- Use Promise.all for parallel operations
+- Use Promise.race for timeout patterns
+- Implement proper error handling
+- Avoid callback hell
+
+Modules:
+- Use ES6 import/export syntax
+- Implement named and default exports
+- Use dynamic imports for code splitting
+- Organize code into modules
+- Use barrel exports for cleaner imports
+
+Classes:
+- Use class syntax for OOP
+- Implement constructors properly
+- Use getters and setters
+- Implement static methods
+- Use private fields (#field)
+- Extend classes with inheritance
+
+Array Methods:
+- Use map, filter, reduce for transformations
+- Use find, findIndex for searching
+- Use some, every for validation
+- Use forEach for iteration (prefer map/filter)
+- Chain array methods for complex operations
+- Use flatMap for flattening and mapping
+
+Object Methods:
+- Use Object.keys, Object.values, Object.entries
+- Use Object.assign for merging
+- Use Object.freeze for immutability
+- Use Object.create for prototypal inheritance
+- Use computed property names
+- Use shorthand property syntax
+
+Optional Chaining:
+- Use ?. for safe property access
+- Use ?. for optional method calls
+- Use ?. for array element access
+- Combine with nullish coalescing
+- Avoid excessive chaining
+
+Nullish Coalescing:
+- Use ?? for default values
+- Understand difference from ||
+- Use with optional chaining
+- Implement proper fallbacks
+- Use for configuration objects
+
+Promises:
+- Create and consume Promises
+- Chain Promises properly
+- Use Promise.all for parallel execution
+- Use Promise.allSettled for all results
+- Implement proper error handling
+- Use Promise.race for timeouts
+
+Iterators and Generators:
+- Understand iterable protocol
+- Use generators for lazy evaluation
+- Implement custom iterators
+- Use yield for generator functions
+- Use for...of for iteration
+
+Best Practices:
+- Use strict mode
+- Avoid global variables
+- Use meaningful variable names
+- Implement pure functions
+- Avoid mutating data
+- Use const for immutability
+- Handle errors properly
+- Use ESLint for code quality
+- Write unit tests
+- Document complex logic
\ No newline at end of file
diff --git a/.agent/rules/styling-consistency.md b/.agent/rules/styling-consistency.md
new file mode 100644
index 0000000..9290f64
--- /dev/null
+++ b/.agent/rules/styling-consistency.md
@@ -0,0 +1,5 @@
+---
+trigger: always_on
+---
+
+Use Tailwind utility classes only. Avoid custom CSS files or inline styles unless for dynamic values.
\ No newline at end of file
diff --git a/.agent/rules/typescript.md b/.agent/rules/typescript.md
new file mode 100644
index 0000000..c67650e
--- /dev/null
+++ b/.agent/rules/typescript.md
@@ -0,0 +1,29 @@
+---
+trigger: always_on
+---
+
+You are an expert in TypeScript configuration and type safety.
+
+Key Principles:
+- Enable 'strict': true in tsconfig.json
+- Avoid 'any' type at all costs
+- Use 'unknown' for uncertain types
+- Handle null and undefined explicitly
+
+Strict Mode Features:
+- noImplicitAny: Forces typing of all variables
+- strictNullChecks: Prevents accessing properties of null/undefined
+- strictFunctionTypes: Enforces sound function parameter bivariance
+- strictPropertyInitialization: Ensures class properties are initialized
+
+Type Safety Best Practices:
+- Use type guards (typeof, instanceof, custom guards) to narrow types
+- Use discriminated unions for state management
+- Use 'readonly' for immutable data structures
+- Use 'as const' for literal types
+- Prefer Interfaces for public APIs, Types for unions/intersections
+
+Error Handling:
+- Don't throw strings; throw Error objects
+- Use Result types or Option types for functional error handling
+- Handle all cases in switch statements (exhaustiveness checking)
\ No newline at end of file
diff --git a/.agent/skills/brainstorming/SKILL.md b/.agent/skills/brainstorming/SKILL.md
new file mode 100644
index 0000000..a21f162
--- /dev/null
+++ b/.agent/skills/brainstorming/SKILL.md
@@ -0,0 +1,230 @@
+---
+name: brainstorming
+description: >
+ Use this skill before any creative or constructive work
+ (features, components, architecture, behavior changes, or functionality).
+ This skill transforms vague ideas into validated designs through
+ disciplined, incremental reasoning and collaboration.
+---
+
+# Brainstorming Ideas Into Designs
+
+## Purpose
+
+Turn raw ideas into **clear, validated designs and specifications**
+through structured dialogue **before any implementation begins**.
+
+This skill exists to prevent:
+- premature implementation
+- hidden assumptions
+- misaligned solutions
+- fragile systems
+
+You are **not allowed** to implement, code, or modify behavior while this skill is active.
+
+---
+
+## Operating Mode
+
+You are operating as a **design facilitator and senior reviewer**, not a builder.
+
+- No creative implementation
+- No speculative features
+- No silent assumptions
+- No skipping ahead
+
+Your job is to **slow the process down just enough to get it right**.
+
+---
+
+## The Process
+
+### 1️⃣ Understand the Current Context (Mandatory First Step)
+
+Before asking any questions:
+
+- Review the current project state (if available):
+ - files
+ - documentation
+ - plans
+ - prior decisions
+- Identify what already exists vs. what is proposed
+- Note constraints that appear implicit but unconfirmed
+
+**Do not design yet.**
+
+---
+
+### 2️⃣ Understanding the Idea (One Question at a Time)
+
+Your goal here is **shared clarity**, not speed.
+
+**Rules:**
+
+- Ask **one question per message**
+- Prefer **multiple-choice questions** when possible
+- Use open-ended questions only when necessary
+- If a topic needs depth, split it into multiple questions
+
+Focus on understanding:
+
+- purpose
+- target users
+- constraints
+- success criteria
+- explicit non-goals
+
+---
+
+### 3️⃣ Non-Functional Requirements (Mandatory)
+
+You MUST explicitly clarify or propose assumptions for:
+
+- Performance expectations
+- Scale (users, data, traffic)
+- Security or privacy constraints
+- Reliability / availability needs
+- Maintenance and ownership expectations
+
+If the user is unsure:
+
+- Propose reasonable defaults
+- Clearly mark them as **assumptions**
+
+---
+
+### 4️⃣ Understanding Lock (Hard Gate)
+
+Before proposing **any design**, you MUST pause and do the following:
+
+#### Understanding Summary
+Provide a concise summary (5–7 bullets) covering:
+- What is being built
+- Why it exists
+- Who it is for
+- Key constraints
+- Explicit non-goals
+
+#### Assumptions
+List all assumptions explicitly.
+
+#### Open Questions
+List unresolved questions, if any.
+
+Then ask:
+
+> “Does this accurately reflect your intent?
+> Please confirm or correct anything before we move to design.”
+
+**Do NOT proceed until explicit confirmation is given.**
+
+---
+
+### 5️⃣ Explore Design Approaches
+
+Once understanding is confirmed:
+
+- Propose **2–3 viable approaches**
+- Lead with your **recommended option**
+- Explain trade-offs clearly:
+ - complexity
+ - extensibility
+ - risk
+ - maintenance
+- Avoid premature optimization (**YAGNI ruthlessly**)
+
+This is still **not** final design.
+
+---
+
+### 6️⃣ Present the Design (Incrementally)
+
+When presenting the design:
+
+- Break it into sections of **200–300 words max**
+- After each section, ask:
+
+ > “Does this look right so far?”
+
+Cover, as relevant:
+
+- Architecture
+- Components
+- Data flow
+- Error handling
+- Edge cases
+- Testing strategy
+
+---
+
+### 7️⃣ Decision Log (Mandatory)
+
+Maintain a running **Decision Log** throughout the design discussion.
+
+For each decision:
+- What was decided
+- Alternatives considered
+- Why this option was chosen
+
+This log should be preserved for documentation.
+
+---
+
+## After the Design
+
+### 📄 Documentation
+
+Once the design is validated:
+
+- Write the final design to a durable, shared format (e.g. Markdown)
+- Include:
+ - Understanding summary
+ - Assumptions
+ - Decision log
+ - Final design
+
+Persist the document according to the project’s standard workflow.
+
+---
+
+### 🛠️ Implementation Handoff (Optional)
+
+Only after documentation is complete, ask:
+
+> “Ready to set up for implementation?”
+
+If yes:
+- Create an explicit implementation plan
+- Isolate work if the workflow supports it
+- Proceed incrementally
+
+---
+
+## Exit Criteria (Hard Stop Conditions)
+
+You may exit brainstorming mode **only when all of the following are true**:
+
+- Understanding Lock has been confirmed
+- At least one design approach is explicitly accepted
+- Major assumptions are documented
+- Key risks are acknowledged
+- Decision Log is complete
+
+If any criterion is unmet:
+- Continue refinement
+- **Do NOT proceed to implementation**
+
+---
+
+## Key Principles (Non-Negotiable)
+
+- One question at a time
+- Assumptions must be explicit
+- Explore alternatives
+- Validate incrementally
+- Prefer clarity over cleverness
+- Be willing to go back and clarify
+- **YAGNI ruthlessly**
+
+---
+If the design is high-impact, high-risk, or requires elevated confidence, you MUST hand off the finalized design and Decision Log to the `multi-agent-brainstorming` skill before implementation.
diff --git a/.agent/skills/frontend-developer/SKILL.md b/.agent/skills/frontend-developer/SKILL.md
new file mode 100644
index 0000000..6be6725
--- /dev/null
+++ b/.agent/skills/frontend-developer/SKILL.md
@@ -0,0 +1,141 @@
+---
+name: frontend-dev-guidelines
+description: Opinionated frontend development standards for modern Astro + React + TypeScript applications. Covers Islands Architecture, Static Site Generation (SSG), Tailwind CSS, SEO optimization, i18n, and strict TypeScript practices.
+---
+
+
+# Frontend Development Guidelines
+
+**(Astro · Islands Architecture · Tailwind CSS · TypeScript · SEO-First)**
+
+You are a **senior frontend engineer** operating under strict architectural and performance standards.
+
+Your goal is to build **lightning-fast, SEO-optimized, and maintainable applications** using:
+
+* **Astro** for the core framework (MPA / SSG)
+* **React** for interactive "Islands" only
+* **Astro Routing** (`src/pages/`) and Layouts
+* **Tailwind CSS + shadcn/ui** for styling
+* **Mobile-first** responsive design
+* **Strict i18n** (Internationalization)
+* **SEO Best Practices** (Metadata, Sitemaps, Schema.org)
+
+This skill defines **how frontend code must be written**, not merely how it *can* be written.
+
+---
+
+## 1. Core Architectural Doctrine (Non-Negotiable)
+
+### 1. Astro-First & Islands Architecture
+* Use **Astro components (`.astro`)** by default for all static UI, layouts, and page structures.
+* Use **React components (`.tsx`)** ONLY for interactive elements that require client-side state (hooks).
+* Hydrate React components using `client:load`, `client:visible`, or `client:idle` only when necessary.
+* Avoid shipping unnecessary JavaScript to the client.
+
+### 2. File-Based Routing & Layouts
+* Routes live in `src/pages/` using `.astro` or `.md/.mdx` files.
+* Use **Layouts** (`src/layouts/`) to wrap pages and manage common structure (HTML boilerplate, Analytics, Navigation).
+* Common components live in `src/components/`.
+
+### 3. Tailwind CSS + shadcn/ui
+* Use pure Tailwind CSS utility classes.
+* shadcn/ui components (`src/components/ui/`) are the source of truth for all complex primitives.
+* Always include `client:load` or similar directives for interactive shadcn components (e.g., Modals, Dropdowns).
+
+### 4. Search Engine Optimization (SEO)
+* Every page must have a `` or `` component with:
+ - Unique `
` and ``.
+ - Open Graph (OG) tags and Twitter cards.
+ - Canonical URLs.
+* Maintain a `sitemap-index.xml` and `robots.txt`.
+
+### 5. Internationalization (i18n)
+* Use Astro's built-in i18n support or a dedicated integration.
+* All routes should follow a locale pattern (e.g., `/en/about`, `/es/acercas-de`).
+* Never hardcode strings; use translation keys.
+
+### 6. Mobile-First Responsiveness
+* All UI must be designed and implemented mobile-first.
+* Use base Tailwind classes for mobile, and breakpoint prefixes (`md:`, `lg:`) for larger screens.
+
+---
+
+## 2. When to Use This Skill
+
+Use **frontend-dev-guidelines** when:
+
+* Creating pages or layouts in Astro.
+* Building interactive React components for the site.
+* Implementing i18n or SEO features.
+* Styling with Tailwind CSS.
+* Optimizing assets or performance.
+
+---
+
+## 3. Quick Start Checklists
+
+### New Page Checklist
+
+* [ ] Create `src/pages/[lang]/index.astro`.
+* [ ] Use a Layout component.
+* [ ] Pass unique SEO metadata (title, description).
+* [ ] Ensure all text uses translation helpers.
+* [ ] Add interactive elements as React Islands where needed.
+
+---
+
+## 4. Component Standards
+
+### Astro Component (Static)
+
+```astro
+---
+// src/components/Header.astro
+interface Props {
+ title: string;
+}
+const { title } = Astro.props;
+---
+
+
{title}
+
+```
+
+### React Island (Interactive)
+
+```tsx
+// src/components/Counter.tsx
+import { useState } from 'react';
+
+export const Counter = () => {
+ const [count, setCount] = useState(0);
+ return ;
+};
+
+// Usage in .astro:
+//
+```
+
+---
+
+## 5. Performance Defaults
+
+* Use **Astro Image** component for optimized assets.
+* Prefer static generation (SSG) for all marketing pages.
+* Minimize the use of `client:load` to reduce Time to Interactive (TTI).
+
+---
+
+## 6. Anti-Patterns (Immediate Rejection)
+
+❌ Using React for a purely static component.
+❌ Hardcoding strings (ignoring i18n).
+❌ Missing meta tags or titles on pages.
+❌ Over-hydrating: Using `client:load` for things below the fold.
+
+---
+
+## 7. Skill Status
+
+**Status:** Stable, Astro-native
+**Intended Use:** Astro + React Applications prioritizing Performance and SEO.
diff --git a/.agent/skills/frontend-developer/resources/common-patterns.md b/.agent/skills/frontend-developer/resources/common-patterns.md
new file mode 100644
index 0000000..3df60a4
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/common-patterns.md
@@ -0,0 +1,182 @@
+# Common Patterns
+
+This document details required patterns for frequent frontend challenges in a Next.js (App Router) + Tailwind CSS architecture.
+
+---
+
+## 1. The Server/Client Boundary
+
+The most important pattern in Next.js is understanding where the server ends and the client begins. By default, everything is a Server Component unless marked with `"use client"`.
+
+### Composing Server and Client Components
+
+When you need interactivity (a Client Component) but also want to render a Server Component inside it, pass the Server Component as `children`. This prevents the Server Component from being implicitly converted to a Client Component.
+
+```tsx
+// src/components/ui/InteractiveWrapper.tsx
+'use client';
+
+import { useState } from 'react';
+import { clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function InteractiveWrapper({ children }: { children: React.ReactNode }) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ return (
+
+
+ {isOpen &&
{children}
}
+
+ );
+}
+
+// src/app/page.tsx
+import { InteractiveWrapper } from '@/components/ui/InteractiveWrapper';
+import { ServerSideDataList } from './ServerSideDataList';
+
+export default function Home() {
+ return (
+
+ {/* This component executes on the server and is passed over the network as rendered HTML */}
+
+
+ );
+}
+```
+
+---
+
+## 2. Server Actions for Forms & Mutations
+
+Forms should progressively enhance using Server Actions. Use React's `useActionState` (formerly `useFormState`) and `useFormStatus` to handle pending states and displaying server validation errors on the client.
+
+```tsx
+// src/features/users/actions/updateProfile.ts
+'use server';
+import { db } from '@/lib/db';
+
+export async function updateProfile(prevState: any, formData: FormData) {
+ const name = formData.get('name') as string;
+ if (name.length < 2) {
+ return { error: 'Name must be at least 2 characters.' };
+ }
+
+ await db.users.update({ name });
+ return { success: true };
+}
+
+// src/features/users/components/ProfileForm.tsx
+'use client';
+import { useActionState } from 'react';
+import { useFormStatus } from 'react-dom';
+import { updateProfile } from '../actions/updateProfile';
+
+function SubmitButton() {
+ const { pending } = useFormStatus();
+ return (
+
+ );
+}
+
+export function ProfileForm() {
+ const [state, formAction] = useActionState(updateProfile, null);
+
+ return (
+
+ );
+}
+```
+
+---
+
+## 3. Class Name Merging (Tailwind CSS)
+
+Always use a combination of `clsx` and `tailwind-merge` when building reusable UI components. This ensures conditional classes apply cleanly and Tailwind conflicting utilities (e.g., passing `px-4` to override a default `px-2`) behave predictably.
+
+```tsx
+// src/components/ui/Badge.tsx
+import { clsx, type ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
+
+interface BadgeProps extends React.HTMLAttributes {
+ variant?: 'primary' | 'secondary' | 'error';
+}
+
+export function Badge({ variant = 'primary', className, ...props }: BadgeProps) {
+ return (
+
+ );
+}
+```
+
+---
+
+## 4. State Management
+
+1. **Global Constants:** Export from a constants file.
+2. **URL Search Params:** Use `searchParams` prop in Server Components, or `useSearchParams`/`useRouter` for client state that needs to be deep-linked (e.g., active tab, search query, filters). This is the preferred method for global state in SSR apps.
+3. **Local UI State:** Use `useState` or `useReducer` in Client Components.
+4. **Client-side Global State (e.g., Theme, Cart):** Use `Zustand` with `persist` for localStorage integration, initialized in a Client Component.
+
+```tsx
+// Using URL for state (Client Side Example)
+'use client';
+
+import { useSearchParams, useRouter, usePathname } from 'next/navigation';
+
+export function FilterTabs() {
+ const searchParams = useSearchParams();
+ const router = useRouter();
+ const pathname = usePathname();
+ const activeTab = searchParams.get('tab') || 'all';
+
+ const setTab = (tab: string) => {
+ const params = new URLSearchParams(searchParams.toString());
+ params.set('tab', tab);
+ router.push(`${pathname}?${params.toString()}`); // Triggers server re-render
+ };
+
+ return (
+
+ );
+}
+```
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/complete-examples.md b/.agent/skills/frontend-developer/resources/complete-examples.md
new file mode 100644
index 0000000..9fe63b3
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/complete-examples.md
@@ -0,0 +1,189 @@
+# Complete Example: Product Management Feature
+
+This example demonstrates a complete feature implementation using Next.js App Router, React Server Components, Server Actions, and Tailwind CSS.
+
+---
+
+## 1. Directory Structure
+
+```
+src/
+ app/
+ products/
+ [id]/
+ page.tsx
+ features/
+ products/
+ actions/
+ updateProduct.ts
+ components/
+ ProductEditForm.tsx
+ types/
+ product.ts
+```
+
+---
+
+## 2. Global Type Definition
+
+```tsx
+// src/types/product.ts
+export interface Product {
+ id: string;
+ name: string;
+ price: number;
+ description: string;
+ updatedAt: string;
+}
+```
+
+---
+
+## 3. Server Action (Mutation)
+
+```tsx
+// src/features/products/actions/updateProduct.ts
+'use server';
+
+import { revalidatePath } from 'next/cache';
+import { db } from '@/lib/db';
+import type { ActionState } from '@/types/action-state';
+
+export async function updateProduct(
+ prevState: ActionState | null,
+ formData: FormData
+): Promise {
+ const id = formData.get('id') as string;
+ const name = formData.get('name') as string;
+ const price = Number(formData.get('price'));
+
+ if (!name || name.length < 3) {
+ return { error: 'Name must be at least 3 characters long.' };
+ }
+
+ try {
+ await db.product.update({
+ where: { id },
+ data: { name, price },
+ });
+
+ revalidatePath(`/products/${id}`);
+ return { success: true };
+ } catch (e) {
+ return { error: 'Failed to update product.' };
+ }
+}
+```
+
+---
+
+## 4. Client Component (Interactive Form)
+
+```tsx
+// src/features/products/components/ProductEditForm.tsx
+'use client';
+
+import { useActionState } from 'react';
+import { updateProduct } from '../actions/updateProduct';
+import type { Product } from '~types/product';
+import { cn } from '@/lib/utils';
+
+export function ProductEditForm({ product }: { product: Product }) {
+ const [state, formAction, isPending] = useActionState(updateProduct, null);
+
+ return (
+
+ );
+}
+```
+
+---
+
+## 5. Page Component (Server Side Composition)
+
+```tsx
+// src/app/products/[id]/page.tsx
+import { db } from '@/lib/db';
+import { notFound } from 'next/navigation';
+import { ProductEditForm } from '@/features/products/components/ProductEditForm';
+import type { Product } from '~types/product';
+
+interface PageProps {
+ params: { id: string };
+}
+
+export default async function Page({ params }: PageProps) {
+ // Fetch data directly on server
+ const product: Product | null = await db.product.findUnique({
+ where: { id: params.id }
+ });
+
+ if (!product) {
+ notFound();
+ }
+
+ return (
+
+
+
+
+ Edit Product
+
+
ID: {product.id}
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+```
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/component-patterns.md b/.agent/skills/frontend-developer/resources/component-patterns.md
new file mode 100644
index 0000000..c75e01b
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/component-patterns.md
@@ -0,0 +1,143 @@
+# Component Patterns
+
+This document establishes the structural rules for all React components in the Next.js frontend architecture.
+
+---
+
+## 1. File Structure & Colocation
+
+### Single File Principle
+* Components under 150 lines should keep their types, sub-components, and styling helpers in the same file.
+* Use **shadcn/ui** components located in `@/components/ui/` as your building blocks.
+* If a component grows too large, extract sub-components into sibling files within the same domain directory.
+
+### Types Colocation
+* Feature-specific types live in `@/features/{feature}/types/`.
+* Global types live in `~types/`.
+* Component prop types are defined directly above the component export.
+
+---
+
+## 2. Server Components (Default)
+
+Server Components are the default in Next.js. They run on the server, fetch data directly, and ship zero JavaScript to the client.
+
+### Pattern: Async Server Component
+* Use `async/await` directly in the component signature.
+* Do not use hooks (`useState`, `useEffect`, `useContext`) in Server Components.
+
+```tsx
+import { db } from '@/lib/db';
+import type { Product } from '~types/product';
+import { ProductCard } from './ProductCard';
+
+interface ProductListProps {
+ categoryId: string;
+}
+
+export default async function ProductList({ categoryId }: ProductListProps) {
+ const products: Product[] = await db.products.findMany({ where: { categoryId } });
+
+ return (
+
+ {products.map(product => (
+
+ ))}
+
+ );
+}
+```
+
+---
+
+## 3. Client Components (`"use client"`)
+
+Only use `"use client"` when you need browser APIs, interactivity (event listeners), or React state/effects.
+
+### Pattern: The Interactivity Leaf
+Push `"use client"` down the component tree as far as possible. Instead of making an entire page a Client Component just for one togglable dropdown, isolate the dropdown.
+
+### Component Structure Order (Client Components)
+1. Types / Props
+2. Hooks & State
+3. Derived values (`useMemo`, simple variables)
+4. Handlers
+5. Render return
+
+```tsx
+'use client';
+
+import { useState } from 'react';
+import { clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+interface ExpandableTextProps {
+ children: React.ReactNode;
+ maxLines?: number;
+ className?: string;
+}
+
+export function ExpandableText({ children, maxLines = 3, className }: ExpandableTextProps) {
+ const [expanded, setExpanded] = useState(false);
+
+ return (
+
+
+ {children}
+
+
+
+ );
+}
+```
+
+---
+
+## 4. The `children` Prop (Composition)
+
+Use the `children` prop heavily. This pattern is crucial in App Router to pass unwrappable Server Components into Client Component shells, bypassing serialization errors.
+
+```tsx
+// 🟢 Good: Server Component passes children to Client Shell
+// /app/layout.tsx
+import { ClientSidebarMenu } from '@/components/ClientSidebarMenu';
+import { ServerSideNavLinks } from '@/components/ServerSideNavLinks';
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ {/* Evaluated on server, passed to client shell */}
+
+ );
+}
+```
+
+---
+
+## 5. Prop Types
+
+* Always type props explicitly with an `interface` named `{ComponentName}Props`.
+* Prefer `React.ReactNode` for `children` types.
+* Avoid `React.FC` or `React.FunctionComponent`; define the component as a standard function (it handles generics better and allows `async` types cleanly in Next.js).
+
+```tsx
+// 🟢 Good
+interface ButtonProps extends React.ButtonHTMLAttributes {
+ variant?: 'primary' | 'secondary';
+ isLoading?: boolean;
+}
+
+export function Button({ variant = 'primary', isLoading, children, className, ...props }: ButtonProps) {
+ return ;
+}
+
+// ❌ Bad (React.FC hides implicit typing and conflicts with async Server Components)
+export const Button: React.FC = ({ children }) => {
+ return ;
+};
+```
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/data-fetching.md b/.agent/skills/frontend-developer/resources/data-fetching.md
new file mode 100644
index 0000000..0e6de02
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/data-fetching.md
@@ -0,0 +1,218 @@
+# Data Fetching & Mutations (Next.js)
+
+The frontend architecture relies on **React Server Components (RSC)** for initial data fetching and **Server Actions** for mutations. Client-side fetching is reserved for specific use cases like highly interactive grids, polling, or infinite scrolling.
+
+---
+
+## 1. Fetching Data (Server Components)
+
+By default, fetch data directly in your React Server Components. This approach eliminates client-side network waterfalls and ships less JavaScript to the browser.
+
+### The Standard Pattern
+
+```tsx
+import { db } from '@/lib/db';
+import type { Product } from '~types/product';
+import { notFound } from 'next/navigation';
+
+interface ProductPageProps {
+ params: { id: string };
+}
+
+export default async function ProductPage({ params }: ProductPageProps) {
+ // 1. Fetch data directly on the server
+ const product: Product | null = await db.products.findById(params.id);
+
+ // 2. Handle 404s cleanly
+ if (!product) {
+ notFound();
+ }
+
+ // 3. Render directly with the data
+ return (
+
+
+ {product.name}
+
+
{product.description}
+
+ ${product.price}
+
+
+ );
+}
+```
+
+### Using Next.js Fetch Wrapper (Caching & Revalidation)
+
+If you are fetching from external APIs, use the extended `fetch` provided by Next.js to control caching and revalidation.
+
+```tsx
+export async function getPosts() {
+ const res = await fetch('https://api.example.com/posts', {
+ next: { tags: ['posts'], revalidate: 3600 }, // Cache for 1 hour, or until revalidated by tag
+ });
+
+ if (!res.ok) {
+ throw new Error('Failed to fetch posts');
+ }
+
+ return res.json();
+}
+```
+
+---
+
+## 2. Mutations (Server Actions)
+
+Mutations (creates, updates, deletes) are handled via **Server Actions**. These are asynchronous functions executed on the server that can be called directly from Client Components or passed to forms in Server Components.
+
+### Defining a Server Action
+
+Server actions should usually be defined in a dedicated file (e.g., `src/features/products/actions/createProduct.ts`) to avoid mixing client/server boundaries inappropriately.
+
+```tsx
+// src/features/products/actions/createProduct.ts
+'use server';
+
+import { revalidatePath } from 'next/cache';
+import { redirect } from 'next/navigation';
+import { db } from '@/lib/db';
+
+export async function createProduct(formData: FormData) {
+ // 1. Extract data
+ const name = formData.get('name') as string;
+ const price = Number(formData.get('price'));
+
+ // 2. Validate data
+ if (!name || isNaN(price)) {
+ return { error: 'Invalid product data' };
+ }
+
+ // 3. Perform the mutation
+ await db.products.insert({ name, price });
+
+ // 4. Revalidate cache and redirect
+ revalidatePath('/products');
+ redirect('/products');
+}
+```
+
+### Using a Server Action in a Form (Server Component)
+
+Server Components can pass actions directly to the `action` prop of a form. This works even with JavaScript disabled.
+
+```tsx
+// src/app/products/new/page.tsx
+import { createProduct } from '@/features/products/actions/createProduct';
+
+export default function NewProductPage() {
+ return (
+
+ );
+}
+```
+
+### Using `useActionState` and `useFormStatus` (Client Components)
+
+To provide pending states and inline error messages, you must use Client Components with the `useActionState` and `useFormStatus` hooks.
+
+```tsx
+// src/features/products/components/ProductForm.tsx
+'use client';
+
+import { useActionState } from 'react';
+import { useFormStatus } from 'react-dom';
+import { createProduct } from '../actions/createProduct';
+import { clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+function SubmitButton() {
+ const { pending } = useFormStatus();
+
+ return (
+
+ );
+}
+
+export function ProductForm() {
+ // useActionState connects form state (errors, success messages) to the server action
+ const [state, formAction] = useActionState(createProduct, null);
+
+ return (
+
+ );
+}
+```
+
+---
+
+## 3. Client-Side Fetching (React Query / SWR)
+
+While RSC is the default, client-side fetching is acceptable and necessary for:
+1. Infinite scrolling feeds.
+2. Data that updates frequently and needs polling.
+3. Complex interactive client-side tables/grids.
+
+To do this, you can initialize React Query in a Client Provider and use hooks like `useQuery` or `useInfiniteQuery`. However, always try to hydrate initial data from the Server Component to avoid empty loading spinners on the first paint.
+
+```tsx
+// src/features/dashboard/components/LiveMetrics.tsx
+'use client';
+
+import { useQuery } from '@tanstack/react-query';
+import { fetchMetrics } from '../api/clientApi';
+
+export function LiveMetrics({ initialData }: { initialData: any }) {
+ const { data } = useQuery({
+ queryKey: ['metrics'],
+ queryFn: fetchMetrics,
+ initialData, // Prevents loading state on initial render
+ refetchInterval: 5000, // Poll every 5s
+ });
+
+ return (
+
+ Active Users: {data.activeUsers}
+
+ );
+}
+```
+
+---
+
+## 4. Banned Patterns
+
+❌ **`useEffect` + `fetch` on Mount:** Never use `useEffect` to load the initial dataset for a page. Use Server Components.
+❌ **Route Handlers (`/api/...`) for Internal Data:** If your frontend and backend are in the same Next.js app, do not `fetch('/api/...')` from a Client Component to your own Next.js API routes just to load data. Use Server Actions or Direct DB calls in RSC instead. Route Handlers are meant primarily for external webhook consumers or integrations.
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/file-organization.md b/.agent/skills/frontend-developer/resources/file-organization.md
new file mode 100644
index 0000000..4933497
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/file-organization.md
@@ -0,0 +1,108 @@
+# File Organization (Next.js)
+
+This project follows a **Feature-First** architecture alongside the Next.js **App Router** (`app/` directory). This ensures that domain logic remains modular while leveraging the filesystem-based routing of Next.js.
+
+---
+
+## 1. Directory Overview
+
+```
+src/
+ app/ <-- 1. Routing & Composition Layer
+ features/ <-- 2. Domain Logic Layer
+ components/ <-- 3. Shared Primitive Layer
+ types/ <-- 4. Global Type Definition Layer
+ lib/ <-- 5. Infrastructure & Utilities
+ hooks/ <-- 6. Shared React Hooks
+```
+
+---
+
+## 2. The `app/` Directory (Routing & Composition)
+
+The `app/` directory is responsible ONLY for routing, layouts, and composing features and shared components.
+
+* Keep page files small.
+* Prefer using **Route Groups** `(group-name)` for logical organization without URL impact.
+* Colocate route-specific components only if they are entirely unique to that page.
+
+```
+src/app/
+ (auth)/ <-- Auth route group
+ login/page.tsx
+ register/page.tsx
+ dashboard/
+ layout.tsx
+ page.tsx
+ loading.tsx
+ error.tsx
+```
+
+---
+
+## 3. The `features/` Directory (Domain Logic)
+
+A feature is a self-contained module representing a business domain (e.g., `products`, `orders`, `users`).
+
+**Structure of a feature:**
+```
+src/features/products/
+ actions/ <-- Server Actions (mutations)
+ components/ <-- Feature-specific UI
+ helpers/ <-- Non-React utility functions
+ index.ts <-- Public API for the feature (Optional)
+```
+
+**Crucial Note:** Features should avoid cross-importing from other features' internal subdirectories. If a component is needed by multiple features, promote it to `src/components/`.
+
+---
+
+## 4. The `types/` Directory (Global Types)
+
+All foundational TypeScript interfaces and types live in the root `src/types/` directory.
+
+* **Alias:** Always use `~types/...` to import these.
+* **Naming:** Use PascalCase for filenames and exported types.
+
+```
+src/types/
+ user.ts
+ order.ts
+ api-response.ts
+```
+
+---
+
+## 5. The `components/` Directory (Shared Primitives)
+
+Base UI components (buttons, cards, inputs) that do not belong to a specific feature.
+
+* Use a subfolder structure like `ui/`, `layout/`, or `skeletons/`.
+* These components must be highly reusable and agnostic of domain data.
+
+```
+src/components/
+ ui/
+ Button.tsx
+ Input.tsx
+ Badge.tsx
+```
+
+---
+
+## 6. Import Aliases Summary
+
+| Alias | Path | Level |
+| ------------- | ---------------- | ------------------------ |
+| `@/` | `src/` | Project Root Alias |
+| `~types` | `src/types` | Global Types Alias |
+| `@/components/ui` | `src/components/ui` | shadcn-ui components |
+
+---
+
+## 7. Organization Rules
+
+1. **Flat is better than nested:** Avoid going more than 3 directory levels deep within a feature.
+2. **Feature Isolation:** If you find yourself importing `{ X } from '@/features/a/components/x'` into `@/features/b/components/y'`, consider moving `X` to `@/components/`.
+3. **Public Exports:** Use `index.ts` in features to control what is exposed to the rest of the application.
+4. **Colocation:** Keep `loading.tsx` and `error.tsx` right next to the `page.tsx` they protect.
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/loading-and-error-states.md b/.agent/skills/frontend-developer/resources/loading-and-error-states.md
new file mode 100644
index 0000000..abcbc05
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/loading-and-error-states.md
@@ -0,0 +1,150 @@
+# Loading & Error States (Next.js)
+
+In the App Router architecture, loading and error states are handled by specific file-level boundaries (`loading.tsx` and `error.tsx`). This allows for **Streaming SSR**, where the layout and shell are sent immediately, and slow data-fetching regions fill in later.
+
+---
+
+## 1. Loading States (`loading.tsx`)
+
+A `loading.tsx` file creates a **Suspense Boundary** around the page segment. It is automatically rendered when a route segment is first loaded or when its data is being fetched on the server.
+
+### The Skeleton Pattern
+* Use `loading.tsx` for page-level transitions.
+* Use Tailwind with `animate-pulse` or specific Skeleton components for a premium feel.
+
+```tsx
+// src/app/dashboard/loading.tsx
+export default function DashboardLoading() {
+ return (
+
+
+
+ {[1, 2, 3].map(i => (
+
+ ))}
+
+
+ );
+}
+```
+
+### Granular Loading (Manual Suspense)
+If only a small part of a page is slow (e.g., an activity feed), wrap just that component in ``.
+
+```tsx
+import { Suspense } from 'react';
+import { SlowActivityFeed } from '@/features/dashboard/components/SlowActivityFeed';
+import { FeedSkeleton } from '@/components/skeletons/FeedSkeleton';
+
+export default function DashboardPage() {
+ return (
+
+
Dashboard Overview
+ {/* Rapidly rendered UI */}
+
+ }>
+ {/* Only this part will stream in when ready */}
+
+
+
+ );
+}
+```
+
+---
+
+## 2. Error States (`error.tsx`)
+
+The `error.tsx` file acts as a **React Error Boundary**. It captures errors in the specific segment and its children, preventing a single error from crashing the entire application.
+
+### The Segment Error Boundary
+* Must be a **Client Component**.
+* Receives `error` and a `reset` function as props.
+
+```tsx
+// src/app/dashboard/error.tsx
+'use client';
+
+import { useEffect } from 'react';
+
+export default function DashboardError({
+ error,
+ reset,
+}: {
+ error: Error & { digest?: string };
+ reset: () => void;
+}) {
+ useEffect(() => {
+ // Log error to an observability service (e.g. Sentry)
+ console.error(error);
+ }, [error]);
+
+ return (
+
+
Something went wrong!
+
{error.message}
+
+
+ );
+}
+```
+
+---
+
+## 3. Empty States
+
+Return specific "Empty" UI components when a data set is empty. Never return `null` if the user expects feedback.
+
+```tsx
+export function EmptyOrderList() {
+ return (
+
+ 📦
+
No Orders Found
+
When you place an order, it will appear here.
+
+ );
+}
+```
+
+---
+
+## 4. Mutation Feedback (Toasts)
+
+For mutations (Server Actions), never rely on page-level loaders for small updates. Use a toast/snack system initiated from the Client Component level.
+
+* Use `useActionState` to track success/failure.
+* Use a minimalist toast library or custom Tailwind component.
+
+```tsx
+'use client';
+
+import { createProduct } from '../actions/createProduct';
+import { useActionState, useEffect } from 'react';
+import { toast } from '@/lib/toast'; // Your chosen minimalist toast implementation
+
+export function CreateProductForm() {
+ const [state, formAction] = useActionState(createProduct, null);
+
+ useEffect(() => {
+ if (state?.success) toast.success('Product created successfully');
+ if (state?.error) toast.error(state.error);
+ }, [state]);
+
+ return ;
+}
+```
+
+---
+
+## 5. Summary Rules
+
+1. **Streaming is Mandatory:** Always provide a `loading.tsx` for top-level app routes to prevent blocking the browser during data fetching.
+2. **Graceful Failures:** Every major segment (dashboard, accounts, products) must have an `error.tsx`.
+3. **Skeleton Fidelity:** Skeleton UI should roughly match the layout of the loaded component to prevent layout shifts (CLS).
+4. **Retry Pattern:** Error boundaries must always provide a "Retry" or "Refresh" action.
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/performance.md b/.agent/skills/frontend-developer/resources/performance.md
new file mode 100644
index 0000000..5500488
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/performance.md
@@ -0,0 +1,129 @@
+# Performance Guidelines (Next.js)
+
+Next.js provides powerful performance optimizations out of the box. Our architecture leverages these to ensure high Lighthouse scores and zero Cumulative Layout Shift (CLS).
+
+---
+
+## 1. Image Optimization (`next/image`)
+
+Always use the `Image` component from `next/image`. This automatically handles resizing, optimization (WebP/AVIF), and lazy loading.
+
+### Rules of Engagement
+* Provide `width` and `height` to prevent CLS.
+* For background images or images whose dimensions are unknown, use the `fill` prop combined with a container having `position: relative`.
+* Use the `priority` prop for the Largest Contentful Paint (LCP) image (e.g., Hero image).
+
+```tsx
+import Image from 'next/image';
+
+export function ProductHero({ src, alt }: { src: string; alt: string }) {
+ return (
+
+
+
+ );
+}
+```
+
+---
+
+## 2. Link Optimization (`next/link`)
+
+Always use `Link` from `next/link`.
+
+* **Prefetching:** Next.js automatically prefetches links in the viewport, making navigation feel instantaneous.
+* **Scroll Restoration:** Automatic scroll position restoration.
+
+```tsx
+import Link from 'next/link';
+
+export function Nav() {
+ return Search;
+}
+```
+
+---
+
+## 3. Font Optimization (`next/font`)
+
+Use `next/font/google` or `next/font/local`. This downloads the font at build time and hosts it with your assets, eliminating external network requests and layout shifts.
+
+```tsx
+// src/app/layout.tsx
+import { Inter } from 'next/font/google';
+
+const inter = Inter({ subsets: ['latin'], display: 'swap' });
+
+export default function RootLayout({ children }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+---
+
+## 4. Code Splitting & Dynamic Imports
+
+Next.js automatically splits code at the route level. For client-side components that are heavy or conditionally rendered, use `next/dynamic`.
+
+```tsx
+import dynamic from 'next/dynamic';
+
+const ExpensiveChart = dynamic(() => import('@/components/charts/ExpensiveChart'), {
+ loading: () =>
Loading Chart...
,
+ ssr: false, // Prevents server-side rendering for browser-only libraries
+});
+
+export function Dashboard() {
+ return ;
+}
+```
+
+---
+
+## 5. Caching Strategies
+
+Leverage the Next.js Data Cache.
+
+* **Full Route Caching:** Static routes are cached by default.
+* **Data Cache:** `fetch()` calls are cached across requests by default.
+* **Revalidation:** Use `revalidatePath` or `revalidateTag` in Server Actions to purge specific cached data when it changes.
+
+```tsx
+// Revalidating after a mutation
+'use server';
+import { revalidatePath } from 'next/cache';
+
+export async function addComment() {
+ // ... db logic ...
+ revalidatePath('/posts/[slug]');
+}
+```
+
+---
+
+## 6. Avoiding Hydration Mismatch
+
+Hydration mismatches occur when the server-rendered HTML doesn't match the first client-side render (e.g., using `new Date()` or `Math.random()` directly in a component).
+
+* **Fix:** Use `useEffect` to trigger client-only rendering or use the `suppressHydrationWarning` prop on elements like `time`.
+
+---
+
+## 7. Performance Checklist
+
+* [ ] All images use `next/image`.
+* [ ] All fonts use `next/font`.
+* [ ] No CLS: Containers have defined aspect ratios or heights.
+* [ ] Bundle Size: Avoid importing heavy libraries (like `lodash`) directly; use specific sub-module imports or `next/dynamic`.
+* [ ] Cache tags: Meaningful tags used for data fetching to allow precise revalidation.
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/routing-guide.md b/.agent/skills/frontend-developer/resources/routing-guide.md
new file mode 100644
index 0000000..22c8890
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/routing-guide.md
@@ -0,0 +1,153 @@
+# Routing Guide (Next.js App Router)
+
+This codebase uses the **Next.js App Router** (`app/` directory) exclusively. All routing is folder-based, and components inside the `app/` directory are React Server Components by default.
+
+---
+
+## 1. Directory Structure
+
+The `src/app/` directory defines your routes.
+
+* Each folder represents a route segment.
+* Special files (`page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`) define the UI for that segment.
+* You can use Route Groups `(folderName)` to organize routes without affecting the URL path.
+
+```
+src/
+ app/
+ (marketing)/ <-- Route Group (does not affect URL)
+ page.tsx <-- `/` route
+ layout.tsx <-- Shared layout for marketing pages
+ about/
+ page.tsx <-- `/about` route
+ (app)/
+ layout.tsx <-- Shared layout for app/dashboard
+ dashboard/
+ page.tsx <-- `/dashboard` route
+ loading.tsx <-- Loading UI for dashboard
+ error.tsx <-- Error UI for dashboard
+ categories/
+ [slug]/ <-- Dynamic Segment
+ page.tsx <-- `/categories/electronics` route
+```
+
+---
+
+## 2. Dynamic Segments
+
+Use square brackets `[paramName]` to create dynamic routes.
+
+```tsx
+// src/app/categories/[slug]/page.tsx
+interface CategoryPageProps {
+ params: { slug: string };
+}
+
+export default async function CategoryPage({ params }: CategoryPageProps) {
+ const categoryId = params.slug;
+ // Fetch data based on the categoryId...
+ return
Category: {categoryId}
;
+}
+```
+
+---
+
+## 3. Search Parameters
+
+Next.js provides access to URL search parameters directly in Server Components via the `searchParams` prop.
+
+```tsx
+// src/app/products/page.tsx
+interface ProductsPageProps {
+ searchParams: { q?: string; page?: string };
+}
+
+export default async function ProductsPage({ searchParams }: ProductsPageProps) {
+ const searchQuery = searchParams.q ?? '';
+ const currentPage = Number(searchParams.page) || 1;
+
+ // Fetch products based on searchQuery and currentPage
+ return
Search results for: {searchQuery}
;
+}
+```
+
+**Client-Side Note:** If you need to access search params in a Client Component, use the `useSearchParams()` hook from `next/navigation`.
+
+---
+
+## 4. Navigation
+
+Always use the `Link` component from `next/link` for internal navigation to ensure prefetched routes and smooth client-side transitions.
+
+```tsx
+import Link from 'next/link';
+
+export function Navigation() {
+ return (
+
+ );
+}
+```
+
+For programmatic navigation (e.g., redirecting after a form submission), use the `useRouter()` hook from `next/navigation` in Client Components, or `redirect()` from `next/navigation` in Server Components / Server Actions.
+
+```tsx
+// Client side programmatic navigation
+'use client';
+import { useRouter } from 'next/navigation';
+
+export function LoginRedirect() {
+ const router = useRouter();
+
+ const handleSuccess = () => {
+ router.push('/dashboard');
+ };
+ // ...
+}
+```
+
+```tsx
+// Server side redirect
+'use server';
+import { redirect } from 'next/navigation';
+
+export async function submitForm() {
+ // process form...
+ redirect('/dashboard');
+}
+```
+
+---
+
+## 5. Parallel & Intercepted Routes
+
+For advanced UI patterns (like modals, or side-by-side split screens), rely on Next.js constructs:
+
+* **Parallel Routes (`@folder`)**: Allows you to simultaneously or conditionally render one or more pages in the same layout.
+* **Intercepted Routes (`(..)folder`)**: Allows you to load a route from another part of your application within the current layout (e.g., opening a photo in a modal without losing the context of the feed).
+
+---
+
+## 6. Architecture Boundary: Features vs App
+
+The `src/app/` directory should remain relatively thin. It acts as the composer of your application. Complex domain logic, reusable UI blocks, and API calls should live in `src/features/` or `src/components/`, and be imported into your route files.
+
+```tsx
+// src/app/dashboard/page.tsx
+// 🟢 Good: App router composes feature components
+import { DashboardMetrics } from '@/features/dashboard/components/DashboardMetrics';
+import { RecentActivity } from '@/features/dashboard/components/RecentActivity';
+
+export default function DashboardPage() {
+ return (
+
+
+
+
+ );
+}
+```
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/styling-guide.md b/.agent/skills/frontend-developer/resources/styling-guide.md
new file mode 100644
index 0000000..7470581
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/styling-guide.md
@@ -0,0 +1,119 @@
+# Styling Guide (Tailwind CSS)
+
+This project strictly adheres to **Tailwind CSS** for all styling. UI component libraries like MUI, Bootstrap, or custom CSS-in-JS solutions are forbidden.
+
+---
+
+## 1. The Principle of Utility-First
+
+Always favor utility classes over custom CSS. Utility classes ensure a consistent design language and keep the CSS bundle small.
+
+### 🟢 Do:
+* Use standard Tailwind classes (`px-4`, `flex`, `text-black`, etc.).
+* Use **shadcn/ui** for complex primitives (Inputs, Selects, Dialogs).
+* Use the minimalist black-and-white primary palette unless specified otherwise.
+
+### ❌ Don't:
+* Create `.css` files unless for global resets or complex third-party library overrides.
+* Use the `style={...}` prop for static styles.
+* Use UI library-specific styling props (e.g., MUI's `sx`).
+
+---
+
+## 2. Conditional Styling & Composition
+
+For components that accept external `className` props or have internal conditional logic, use `clsx` and `tailwind-merge`. This pattern is non-negotiable for building reliable reusable components.
+
+```tsx
+import { clsx, type ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+/**
+ * Utility for merging tailwind classes safely.
+ */
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
+
+interface ButtonProps extends React.ButtonHTMLAttributes {
+ variant?: 'primary' | 'secondary';
+}
+
+export function Button({ variant = 'primary', className, ...props }: ButtonProps) {
+ return (
+
+ );
+}
+```
+
+---
+
+## 3. Dark Mode & Theming
+
+The primary design aesthetic is **Premium Minimalist** (Black and White).
+
+* **Light Mode:** White background, black/gray-900 text, gray-200 borders.
+* **Dark Mode:** Black/gray-950 background, white text, gray-800 borders.
+
+Use the `dark:` prefix for all components to ensure they behave correctly in dark modes.
+
+```html
+
+ ...
+
+```
+
+---
+
+## 4. Typography
+
+Use a high-quality modern sans-serif font (Inter, Roboto, or Outfit) via `next/font`.
+
+* **Headings:** `text-2xl` to `text-5xl`, `font-bold` or `font-semibold`, `tracking-tight`.
+* **Body:** `text-base` or `text-sm`, `leading-relaxed`.
+* **Capitals:** For buttons or small UI labels, use `uppercase tracking-widest text-[10px]`.
+
+---
+
+## 5. Layout & Spacing
+
+* **Mobile-First Responsiveness:** Always style starting from the smallest screen. Base classes are for mobile; use `sm:`, `md:`, `lg:` only for larger screen overrides.
+* **Containers:** Use `max-w-7xl mx-auto px-4 md:px-8`.
+* **Grids:** Always prefer `grid` over `flex` for page-level layouts.
+* **Gaps:** Use standard spacing scale (`gap-4`, `gap-8`).
+
+```tsx
+export function ProductGrid() {
+ return (
+
+ {/* Product Items */}
+
+ );
+}
+```
+
+---
+
+## 6. Micro-animations
+
+Leverage Tailwind's transition utilities for a premium feel.
+
+* **Hovers:** Use `hover:opacity-80` or `hover:-translate-y-1`.
+* **Transitions:** Always add `transition-all duration-300`.
+* **Focus States:** Distinct black outlines: `focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2`.
+
+---
+
+## 7. Banned Patterns
+
+❌ **Inline Styles:** Except for dynamic values (e.g., progress bar width).
+❌ **Relative Units (em):** Use Tailwind's default `rem` based scale.
+❌ **Important (`!`):** Avoid using `!important` classes. Fix the specificity or use `tailwind-merge` instead.
+❌ **Third-party UI libraries (Shadcn, Headless UI):** Only use if specifically requested by the user. Default to pure Tailwind.
\ No newline at end of file
diff --git a/.agent/skills/frontend-developer/resources/typescript-standards.md b/.agent/skills/frontend-developer/resources/typescript-standards.md
new file mode 100644
index 0000000..ab22931
--- /dev/null
+++ b/.agent/skills/frontend-developer/resources/typescript-standards.md
@@ -0,0 +1,118 @@
+# TypeScript Standards (Next.js)
+
+Our TypeScript configuration adheres to the strictest possible standards to ensure type safety across the server-client boundary and within the Next.js App Router tree.
+
+---
+
+## 1. Strict Mode
+
+The `tsconfig.json` must have `'strict': true` enabled.
+
+* **No `any`:** Under no circumstances should `any` be used. Use `unknown` if the type is truly uncertain, or `interface` for known structures.
+* **Non-Nullable:** Handle `null` and `undefined` explicitly via optional chaining (`?.`) or nullish coalescing (`??`).
+
+---
+
+## 2. Next.js Specific Types
+
+### Page & Layout Props
+Always type the props for `page.tsx` and `layout.tsx`.
+
+```tsx
+// src/app/products/[id]/page.tsx
+interface ProductPageProps {
+ params: { id: string };
+ searchParams: { [key: string]: string | string[] | undefined };
+}
+
+export default async function ProductPage({ params, searchParams }: ProductPageProps) {
+ // ...
+}
+```
+
+### Server Actions
+State within `useActionState` should be strictly typed.
+
+```tsx
+// src/features/products/types/action-state.ts
+export interface ActionState {
+ success?: boolean;
+ error?: string;
+ data?: any;
+}
+```
+
+---
+
+## 3. Global vs Feature Types
+
+### Global Types (`src/types/`)
+* **Location:** Use `src/types/` for entities used by 3+ features or core system types.
+* **Alias:** Use the `~types/...` alias.
+* **Structure:** One file per entity (e.g., `user.ts`, `auth.ts`).
+
+### Feature Types (`src/features/{f}/types/`)
+* **Location:** Use for types strictly coupled with one domain.
+* **Alias:** Use `@/features/f/types`.
+
+---
+
+## 4. Design Patterns
+
+* **Interfaces vs Types:**
+ * Use **Interfaces** for public APIs, props, and object definitions (they are more performant and extendable).
+ * Use **Types** for unions, intersections, and primitives.
+
+* **Discriminated Unions:**
+ Use for state management to ensure all possible paths are handled.
+
+```tsx
+type LoadingState =
+ | { status: 'idle' }
+ | { status: 'loading' }
+ | { status: 'success'; data: any }
+ | { status: 'error'; message: string };
+```
+
+---
+
+## 5. Banned Patterns
+
+❌ **`as const` for Enums:** Prefer string literal unions over Enums for better readability and performance.
+❌ **`React.FC`:** As noted in the Component Patterns, use standard function declarations.
+❌ **Implicit returns:** Always provide explicit return types for functions, especially those exported from a file.
+❌ **`any` data fetching:** Every fetch or DB call must be cast to a specific interface.
+
+---
+
+## 6. JSDoc Documentation
+
+Publicly exported components and utility functions must have JSDoc blocks for better developer experience and tooling.
+
+```tsx
+/**
+ * Renders a primary call-to-action button.
+ * @param variant - Visual style of the button.
+ * @param isLoading - Whether the button is in a loading state.
+ */
+export function Button({ variant, isLoading, ...props }: ButtonProps) {
+ // ...
+}
+```
+
+---
+
+## 7. Absolute Rule on Nullability
+
+Never use non-null assertions (`!`). If a value could be null, the code must account for that possibility with a guard or a fallback.
+
+```tsx
+// ❌ Bad
+const user = await db.getUser(id);
+console.log(user!.name);
+
+// 🟢 Good
+const user = await db.getUser(id);
+if (!user) return
User not found
;
+console.log(user.name);
+```
\ No newline at end of file
diff --git a/.agent/skills/react-best-practices/AGENTS.md b/.agent/skills/react-best-practices/AGENTS.md
new file mode 100644
index 0000000..898afb3
--- /dev/null
+++ b/.agent/skills/react-best-practices/AGENTS.md
@@ -0,0 +1,2249 @@
+# React Best Practices
+
+**Version 0.1.0**
+Vercel Engineering
+January 2026
+
+> **Note:**
+> This document is mainly for agents and LLMs to follow when maintaining,
+> generating, or refactoring React and Next.js codebases at Vercel. Humans
+> may also find it useful, but guidance here is optimized for automation
+> and consistency by AI-assisted workflows.
+
+---
+
+## Abstract
+
+Comprehensive performance optimization guide for React and Next.js applications, designed for AI agents and LLMs. Contains 40+ rules across 8 categories, prioritized by impact from critical (eliminating waterfalls, reducing bundle size) to incremental (advanced patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
+
+---
+
+## Table of Contents
+
+1. [Eliminating Waterfalls](#1-eliminating-waterfalls) — **CRITICAL**
+ - 1.1 [Defer Await Until Needed](#11-defer-await-until-needed)
+ - 1.2 [Dependency-Based Parallelization](#12-dependency-based-parallelization)
+ - 1.3 [Prevent Waterfall Chains in API Routes](#13-prevent-waterfall-chains-in-api-routes)
+ - 1.4 [Promise.all() for Independent Operations](#14-promiseall-for-independent-operations)
+ - 1.5 [Strategic Suspense Boundaries](#15-strategic-suspense-boundaries)
+2. [Bundle Size Optimization](#2-bundle-size-optimization) — **CRITICAL**
+ - 2.1 [Avoid Barrel File Imports](#21-avoid-barrel-file-imports)
+ - 2.2 [Conditional Module Loading](#22-conditional-module-loading)
+ - 2.3 [Defer Non-Critical Third-Party Libraries](#23-defer-non-critical-third-party-libraries)
+ - 2.4 [Dynamic Imports for Heavy Components](#24-dynamic-imports-for-heavy-components)
+ - 2.5 [Preload Based on User Intent](#25-preload-based-on-user-intent)
+3. [Server-Side Performance](#3-server-side-performance) — **HIGH**
+ - 3.1 [Cross-Request LRU Caching](#31-cross-request-lru-caching)
+ - 3.2 [Minimize Serialization at RSC Boundaries](#32-minimize-serialization-at-rsc-boundaries)
+ - 3.3 [Parallel Data Fetching with Component Composition](#33-parallel-data-fetching-with-component-composition)
+ - 3.4 [Per-Request Deduplication with React.cache()](#34-per-request-deduplication-with-reactcache)
+ - 3.5 [Use after() for Non-Blocking Operations](#35-use-after-for-non-blocking-operations)
+4. [Client-Side Data Fetching](#4-client-side-data-fetching) — **MEDIUM-HIGH**
+ - 4.1 [Deduplicate Global Event Listeners](#41-deduplicate-global-event-listeners)
+ - 4.2 [Use SWR for Automatic Deduplication](#42-use-swr-for-automatic-deduplication)
+5. [Re-render Optimization](#5-re-render-optimization) — **MEDIUM**
+ - 5.1 [Defer State Reads to Usage Point](#51-defer-state-reads-to-usage-point)
+ - 5.2 [Extract to Memoized Components](#52-extract-to-memoized-components)
+ - 5.3 [Narrow Effect Dependencies](#53-narrow-effect-dependencies)
+ - 5.4 [Subscribe to Derived State](#54-subscribe-to-derived-state)
+ - 5.5 [Use Functional setState Updates](#55-use-functional-setstate-updates)
+ - 5.6 [Use Lazy State Initialization](#56-use-lazy-state-initialization)
+ - 5.7 [Use Transitions for Non-Urgent Updates](#57-use-transitions-for-non-urgent-updates)
+6. [Rendering Performance](#6-rendering-performance) — **MEDIUM**
+ - 6.1 [Animate SVG Wrapper Instead of SVG Element](#61-animate-svg-wrapper-instead-of-svg-element)
+ - 6.2 [CSS content-visibility for Long Lists](#62-css-content-visibility-for-long-lists)
+ - 6.3 [Hoist Static JSX Elements](#63-hoist-static-jsx-elements)
+ - 6.4 [Optimize SVG Precision](#64-optimize-svg-precision)
+ - 6.5 [Prevent Hydration Mismatch Without Flickering](#65-prevent-hydration-mismatch-without-flickering)
+ - 6.6 [Use Activity Component for Show/Hide](#66-use-activity-component-for-showhide)
+ - 6.7 [Use Explicit Conditional Rendering](#67-use-explicit-conditional-rendering)
+7. [JavaScript Performance](#7-javascript-performance) — **LOW-MEDIUM**
+ - 7.1 [Batch DOM CSS Changes](#71-batch-dom-css-changes)
+ - 7.2 [Build Index Maps for Repeated Lookups](#72-build-index-maps-for-repeated-lookups)
+ - 7.3 [Cache Property Access in Loops](#73-cache-property-access-in-loops)
+ - 7.4 [Cache Repeated Function Calls](#74-cache-repeated-function-calls)
+ - 7.5 [Cache Storage API Calls](#75-cache-storage-api-calls)
+ - 7.6 [Combine Multiple Array Iterations](#76-combine-multiple-array-iterations)
+ - 7.7 [Early Length Check for Array Comparisons](#77-early-length-check-for-array-comparisons)
+ - 7.8 [Early Return from Functions](#78-early-return-from-functions)
+ - 7.9 [Hoist RegExp Creation](#79-hoist-regexp-creation)
+ - 7.10 [Use Loop for Min/Max Instead of Sort](#710-use-loop-for-minmax-instead-of-sort)
+ - 7.11 [Use Set/Map for O(1) Lookups](#711-use-setmap-for-o1-lookups)
+ - 7.12 [Use toSorted() Instead of sort() for Immutability](#712-use-tosorted-instead-of-sort-for-immutability)
+8. [Advanced Patterns](#8-advanced-patterns) — **LOW**
+ - 8.1 [Store Event Handlers in Refs](#81-store-event-handlers-in-refs)
+ - 8.2 [useLatest for Stable Callback Refs](#82-uselatest-for-stable-callback-refs)
+
+---
+
+## 1. Eliminating Waterfalls
+
+**Impact: CRITICAL**
+
+Waterfalls are the #1 performance killer. Each sequential await adds full network latency. Eliminating them yields the largest gains.
+
+### 1.1 Defer Await Until Needed
+
+**Impact: HIGH (avoids blocking unused code paths)**
+
+Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.
+
+**Incorrect: blocks both branches**
+
+```typescript
+async function handleRequest(userId: string, skipProcessing: boolean) {
+ const userData = await fetchUserData(userId)
+
+ if (skipProcessing) {
+ // Returns immediately but still waited for userData
+ return { skipped: true }
+ }
+
+ // Only this branch uses userData
+ return processUserData(userData)
+}
+```
+
+**Correct: only blocks when needed**
+
+```typescript
+async function handleRequest(userId: string, skipProcessing: boolean) {
+ if (skipProcessing) {
+ // Returns immediately without waiting
+ return { skipped: true }
+ }
+
+ // Fetch only when needed
+ const userData = await fetchUserData(userId)
+ return processUserData(userData)
+}
+```
+
+**Another example: early return optimization**
+
+```typescript
+// Incorrect: always fetches permissions
+async function updateResource(resourceId: string, userId: string) {
+ const permissions = await fetchPermissions(userId)
+ const resource = await getResource(resourceId)
+
+ if (!resource) {
+ return { error: 'Not found' }
+ }
+
+ if (!permissions.canEdit) {
+ return { error: 'Forbidden' }
+ }
+
+ return await updateResourceData(resource, permissions)
+}
+
+// Correct: fetches only when needed
+async function updateResource(resourceId: string, userId: string) {
+ const resource = await getResource(resourceId)
+
+ if (!resource) {
+ return { error: 'Not found' }
+ }
+
+ const permissions = await fetchPermissions(userId)
+
+ if (!permissions.canEdit) {
+ return { error: 'Forbidden' }
+ }
+
+ return await updateResourceData(resource, permissions)
+}
+```
+
+This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.
+
+### 1.2 Dependency-Based Parallelization
+
+**Impact: CRITICAL (2-10× improvement)**
+
+For operations with partial dependencies, use `better-all` to maximize parallelism. It automatically starts each task at the earliest possible moment.
+
+**Incorrect: profile waits for config unnecessarily**
+
+```typescript
+const [user, config] = await Promise.all([
+ fetchUser(),
+ fetchConfig()
+])
+const profile = await fetchProfile(user.id)
+```
+
+**Correct: config and profile run in parallel**
+
+```typescript
+import { all } from 'better-all'
+
+const { user, config, profile } = await all({
+ async user() { return fetchUser() },
+ async config() { return fetchConfig() },
+ async profile() {
+ return fetchProfile((await this.$.user).id)
+ }
+})
+```
+
+Reference: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
+
+### 1.3 Prevent Waterfall Chains in API Routes
+
+**Impact: CRITICAL (2-10× improvement)**
+
+In API routes and Server Actions, start independent operations immediately, even if you don't await them yet.
+
+**Incorrect: config waits for auth, data waits for both**
+
+```typescript
+export async function GET(request: Request) {
+ const session = await auth()
+ const config = await fetchConfig()
+ const data = await fetchData(session.user.id)
+ return Response.json({ data, config })
+}
+```
+
+**Correct: auth and config start immediately**
+
+```typescript
+export async function GET(request: Request) {
+ const sessionPromise = auth()
+ const configPromise = fetchConfig()
+ const session = await sessionPromise
+ const [config, data] = await Promise.all([
+ configPromise,
+ fetchData(session.user.id)
+ ])
+ return Response.json({ data, config })
+}
+```
+
+For operations with more complex dependency chains, use `better-all` to automatically maximize parallelism (see Dependency-Based Parallelization).
+
+### 1.4 Promise.all() for Independent Operations
+
+**Impact: CRITICAL (2-10× improvement)**
+
+When async operations have no interdependencies, execute them concurrently using `Promise.all()`.
+
+**Incorrect: sequential execution, 3 round trips**
+
+```typescript
+const user = await fetchUser()
+const posts = await fetchPosts()
+const comments = await fetchComments()
+```
+
+**Correct: parallel execution, 1 round trip**
+
+```typescript
+const [user, posts, comments] = await Promise.all([
+ fetchUser(),
+ fetchPosts(),
+ fetchComments()
+])
+```
+
+### 1.5 Strategic Suspense Boundaries
+
+**Impact: HIGH (faster initial paint)**
+
+Instead of awaiting data in async components before returning JSX, use Suspense boundaries to show the wrapper UI faster while data loads.
+
+**Incorrect: wrapper blocked by data fetching**
+
+```tsx
+async function Page() {
+ const data = await fetchData() // Blocks entire page
+
+ return (
+
+
Sidebar
+
Header
+
+
+
+
Footer
+
+ )
+}
+```
+
+The entire layout waits for data even though only the middle section needs it.
+
+**Correct: wrapper shows immediately, data streams in**
+
+```tsx
+function Page() {
+ return (
+
+
Sidebar
+
Header
+
+ }>
+
+
+
+
Footer
+
+ )
+}
+
+async function DataDisplay() {
+ const data = await fetchData() // Only blocks this component
+ return
{data.content}
+}
+```
+
+Sidebar, Header, and Footer render immediately. Only DataDisplay waits for data.
+
+**Alternative: share promise across components**
+
+```tsx
+function Page() {
+ // Start fetch immediately, but don't await
+ const dataPromise = fetchData()
+
+ return (
+
+}
+
+function DataSummary({ dataPromise }: { dataPromise: Promise }) {
+ const data = use(dataPromise) // Reuses the same promise
+ return
{data.summary}
+}
+```
+
+Both components share the same promise, so only one fetch occurs. Layout renders immediately while both components wait together.
+
+**When NOT to use this pattern:**
+
+- Critical data needed for layout decisions (affects positioning)
+
+- SEO-critical content above the fold
+
+- Small, fast queries where suspense overhead isn't worth it
+
+- When you want to avoid layout shift (loading → content jump)
+
+**Trade-off:** Faster initial paint vs potential layout shift. Choose based on your UX priorities.
+
+---
+
+## 2. Bundle Size Optimization
+
+**Impact: CRITICAL**
+
+Reducing initial bundle size improves Time to Interactive and Largest Contentful Paint.
+
+### 2.1 Avoid Barrel File Imports
+
+**Impact: CRITICAL (200-800ms import cost, slow builds)**
+
+Import directly from source files instead of barrel files to avoid loading thousands of unused modules. **Barrel files** are entry points that re-export multiple modules (e.g., `index.js` that does `export * from './module'`).
+
+Popular icon and component libraries can have **up to 10,000 re-exports** in their entry file. For many React packages, **it takes 200-800ms just to import them**, affecting both development speed and production cold starts.
+
+**Why tree-shaking doesn't help:** When a library is marked as external (not bundled), the bundler can't optimize it. If you bundle it to enable tree-shaking, builds become substantially slower analyzing the entire module graph.
+
+**Incorrect: imports entire library**
+
+```tsx
+import { Check, X, Menu } from 'lucide-react'
+// Loads 1,583 modules, takes ~2.8s extra in dev
+// Runtime cost: 200-800ms on every cold start
+
+import { Button, TextField } from '@mui/material'
+// Loads 2,225 modules, takes ~4.2s extra in dev
+```
+
+**Correct: imports only what you need**
+
+```tsx
+import Check from 'lucide-react/dist/esm/icons/check'
+import X from 'lucide-react/dist/esm/icons/x'
+import Menu from 'lucide-react/dist/esm/icons/menu'
+// Loads only 3 modules (~2KB vs ~1MB)
+
+import Button from '@mui/material/Button'
+import TextField from '@mui/material/TextField'
+// Loads only what you use
+```
+
+**Alternative: Next.js 13.5+**
+
+```js
+// next.config.js - use optimizePackageImports
+module.exports = {
+ experimental: {
+ optimizePackageImports: ['lucide-react', '@mui/material']
+ }
+}
+
+// Then you can keep the ergonomic barrel imports:
+import { Check, X, Menu } from 'lucide-react'
+// Automatically transformed to direct imports at build time
+```
+
+Direct imports provide 15-70% faster dev boot, 28% faster builds, 40% faster cold starts, and significantly faster HMR.
+
+Libraries commonly affected: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `@radix-ui/react-*`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`.
+
+Reference: [https://vercel.com/blog/how-we-optimized-package-imports-in-next-js](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)
+
+### 2.2 Conditional Module Loading
+
+**Impact: HIGH (loads large data only when needed)**
+
+Load large data or modules only when a feature is activated.
+
+**Example: lazy-load animation frames**
+
+```tsx
+function AnimationPlayer({ enabled }: { enabled: boolean }) {
+ const [frames, setFrames] = useState(null)
+
+ useEffect(() => {
+ if (enabled && !frames && typeof window !== 'undefined') {
+ import('./animation-frames.js')
+ .then(mod => setFrames(mod.frames))
+ .catch(() => setEnabled(false))
+ }
+ }, [enabled, frames])
+
+ if (!frames) return
+ return
+}
+```
+
+The `typeof window !== 'undefined'` check prevents bundling this module for SSR, optimizing server bundle size and build speed.
+
+### 2.3 Defer Non-Critical Third-Party Libraries
+
+**Impact: MEDIUM (loads after hydration)**
+
+Analytics, logging, and error tracking don't block user interaction. Load them after hydration.
+
+**Incorrect: blocks initial bundle**
+
+```tsx
+import { Analytics } from '@vercel/analytics/react'
+
+export default function RootLayout({ children }) {
+ return (
+
+
+ {children}
+
+
+
+ )
+}
+```
+
+**Correct: loads after hydration**
+
+```tsx
+import dynamic from 'next/dynamic'
+
+const Analytics = dynamic(
+ () => import('@vercel/analytics/react').then(m => m.Analytics),
+ { ssr: false }
+)
+
+export default function RootLayout({ children }) {
+ return (
+
+
+ {children}
+
+
+
+ )
+}
+```
+
+### 2.4 Dynamic Imports for Heavy Components
+
+**Impact: CRITICAL (directly affects TTI and LCP)**
+
+Use `next/dynamic` to lazy-load large components not needed on initial render.
+
+**Incorrect: Monaco bundles with main chunk ~300KB**
+
+```tsx
+import { MonacoEditor } from './monaco-editor'
+
+function CodePanel({ code }: { code: string }) {
+ return
+}
+```
+
+**Correct: Monaco loads on demand**
+
+```tsx
+import dynamic from 'next/dynamic'
+
+const MonacoEditor = dynamic(
+ () => import('./monaco-editor').then(m => m.MonacoEditor),
+ { ssr: false }
+)
+
+function CodePanel({ code }: { code: string }) {
+ return
+}
+```
+
+### 2.5 Preload Based on User Intent
+
+**Impact: MEDIUM (reduces perceived latency)**
+
+Preload heavy bundles before they're needed to reduce perceived latency.
+
+**Example: preload on hover/focus**
+
+```tsx
+function EditorButton({ onClick }: { onClick: () => void }) {
+ const preload = () => {
+ if (typeof window !== 'undefined') {
+ void import('./monaco-editor')
+ }
+ }
+
+ return (
+
+ )
+}
+```
+
+**Example: preload when feature flag is enabled**
+
+```tsx
+function FlagsProvider({ children, flags }: Props) {
+ useEffect(() => {
+ if (flags.editorEnabled && typeof window !== 'undefined') {
+ void import('./monaco-editor').then(mod => mod.init())
+ }
+ }, [flags.editorEnabled])
+
+ return
+ {children}
+
+}
+```
+
+The `typeof window !== 'undefined'` check prevents bundling preloaded modules for SSR, optimizing server bundle size and build speed.
+
+---
+
+## 3. Server-Side Performance
+
+**Impact: HIGH**
+
+Optimizing server-side rendering and data fetching eliminates server-side waterfalls and reduces response times.
+
+### 3.1 Cross-Request LRU Caching
+
+**Impact: HIGH (caches across requests)**
+
+`React.cache()` only works within one request. For data shared across sequential requests (user clicks button A then button B), use an LRU cache.
+
+**Implementation:**
+
+```typescript
+import { LRUCache } from 'lru-cache'
+
+const cache = new LRUCache({
+ max: 1000,
+ ttl: 5 * 60 * 1000 // 5 minutes
+})
+
+export async function getUser(id: string) {
+ const cached = cache.get(id)
+ if (cached) return cached
+
+ const user = await db.user.findUnique({ where: { id } })
+ cache.set(id, user)
+ return user
+}
+
+// Request 1: DB query, result cached
+// Request 2: cache hit, no DB query
+```
+
+Use when sequential user actions hit multiple endpoints needing the same data within seconds.
+
+**With Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute):** LRU caching is especially effective because multiple concurrent requests can share the same function instance and cache. This means the cache persists across requests without needing external storage like Redis.
+
+**In traditional serverless:** Each invocation runs in isolation, so consider Redis for cross-process caching.
+
+Reference: [https://github.com/isaacs/node-lru-cache](https://github.com/isaacs/node-lru-cache)
+
+### 3.2 Minimize Serialization at RSC Boundaries
+
+**Impact: HIGH (reduces data transfer size)**
+
+The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
+
+**Incorrect: serializes all 50 fields**
+
+```tsx
+async function Page() {
+ const user = await fetchUser() // 50 fields
+ return
+}
+
+'use client'
+function Profile({ user }: { user: User }) {
+ return
{user.name}
// uses 1 field
+}
+```
+
+**Correct: serializes only 1 field**
+
+```tsx
+async function Page() {
+ const user = await fetchUser()
+ return
+}
+
+'use client'
+function Profile({ name }: { name: string }) {
+ return
{name}
+}
+```
+
+### 3.3 Parallel Data Fetching with Component Composition
+
+**Impact: CRITICAL (eliminates server-side waterfalls)**
+
+React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.
+
+**Incorrect: Sidebar waits for Page's fetch to complete**
+
+```tsx
+export default async function Page() {
+ const header = await fetchHeader()
+ return (
+
+
{header}
+
+
+ )
+}
+
+async function Sidebar() {
+ const items = await fetchSidebarItems()
+ return
+}
+```
+
+**Correct: both fetch simultaneously**
+
+```tsx
+async function Header() {
+ const data = await fetchHeader()
+ return