diff --git a/.cursor/rules/after-changes.mdc b/.cursor/rules/after-changes.mdc
new file mode 100644
index 000000000..81a245000
--- /dev/null
+++ b/.cursor/rules/after-changes.mdc
@@ -0,0 +1,38 @@
+---
+description: Always run typecheck and lint after making code changes
+globs: **/*.{ts,tsx}
+alwaysApply: true
+---
+
+# After Code Changes
+
+After making any code changes, **always run these checks**:
+
+```bash
+# TypeScript type checking
+bun run typecheck
+
+# ESLint linting
+bun run lint
+```
+
+## Fix Errors Before Committing
+
+If either check fails:
+
+1. Fix all TypeScript errors first (they break the build)
+2. Fix ESLint errors/warnings
+3. Re-run checks until both pass
+4. Only then commit or deploy
+
+## Common TypeScript Fixes
+
+- **Property does not exist**: Check interface/type definitions, ensure correct property names
+- **Type mismatch**: Verify the expected type vs actual type being passed
+- **Empty interface extends**: Use `type X = SomeType` instead of `interface X extends SomeType {}`
+
+## Common ESLint Fixes
+
+- **Unused variables**: Remove or prefix with `_`
+- **Any type**: Add proper typing
+- **Empty object type**: Use `type` instead of `interface` for type aliases
diff --git a/.cursor/rules/better-auth.mdc b/.cursor/rules/better-auth.mdc
deleted file mode 100644
index 4986ca7a2..000000000
--- a/.cursor/rules/better-auth.mdc
+++ /dev/null
@@ -1,28 +0,0 @@
----
-description: When dealing with auth or authClient related code.
-globs:
-alwaysApply: false
----
-Only use auth.ts and auth.api methods serverside. To use them you have to pass Next.js headers as follows:
-auth.api.hasPermission({
- headers: await headers(),
- body: {
- permissions: {
- project: ["create"] // This must match the structure in your access control
- }
- }
-});
-
-
-
- Only use auth-client.ts and authClient on clienside. You do not need to pass headers, it's already contextually aware.
-
- const canCreateProject = await authClient.organization.hasPermission({
- permissions: {
- project: ["create"]
- }
-})
-
-
-For the full list of methods/supported actions reference:
-https://www.better-auth.com/docs/plugins/organization
\ No newline at end of file
diff --git a/.cursor/rules/code-standards.mdc b/.cursor/rules/code-standards.mdc
new file mode 100644
index 000000000..da46b64d1
--- /dev/null
+++ b/.cursor/rules/code-standards.mdc
@@ -0,0 +1,186 @@
+---
+description: General code quality standards and file size limits
+globs: **/*.{ts,tsx}
+alwaysApply: true
+---
+
+# Code Standards
+
+## File Size Limits
+
+**Files must not exceed 300 lines.** When a file approaches this limit, split it.
+
+### ✅ How to Split Large Files
+
+```
+# Before: One 400-line file
+components/TaskList.tsx (400 lines)
+
+# After: Multiple focused files
+components/
+├── TaskList.tsx # Main component (~100 lines)
+├── TaskListItem.tsx # Individual item (~80 lines)
+├── TaskListFilters.tsx # Filter controls (~60 lines)
+└── TaskListEmpty.tsx # Empty state (~40 lines)
+```
+
+### Splitting Strategies
+
+| File Type | Split By |
+| --------- | -------------------------------------------- |
+| Component | Extract sub-components, hooks, utils |
+| Hook | Extract helper functions, split by concern |
+| Utils | Group by domain (dates, strings, validation) |
+| Types | Split by entity (Task, User, Organization) |
+
+### ❌ Warning Signs
+
+```tsx
+// ❌ File is too long
+// TaskList.tsx - 450 lines with inline helpers, multiple components
+
+// ❌ Multiple components in one file
+export function TaskList() { ... }
+export function TaskCard() { ... } // Should be separate file
+export function TaskBadge() { ... } // Should be separate file
+```
+
+## Code Quality
+
+### ✅ Always Do This
+
+```tsx
+// Early returns for readability
+function processTask(task: Task | null) {
+ if (!task) return null;
+ if (task.deleted) return null;
+
+ return ;
+}
+
+// Descriptive names
+const handleTaskComplete = (taskId: string) => { ... };
+const isTaskOverdue = (task: Task) => task.dueDate < new Date();
+
+// Const arrow functions with types
+const formatDate = (date: Date): string => {
+ return date.toLocaleDateString();
+};
+```
+
+### ❌ Never Do This
+
+```tsx
+// No early returns - deeply nested
+function processTask(task) {
+ if (task) {
+ if (!task.deleted) {
+ return ;
+ }
+ }
+ return null;
+}
+
+// Vague names
+const handleClick = () => { ... }; // Click on what?
+const data = fetchStuff(); // What data?
+
+// Function keyword when const works
+function formatDate(date) { ... }
+```
+
+## Function Parameters
+
+**Use named parameters (object destructuring) for functions with 2+ parameters.**
+
+### ✅ Always Do This
+
+```tsx
+// Named parameters - clear at call site
+const createTask = ({ title, assigneeId, dueDate }: CreateTaskParams) => { ... };
+createTask({ title: 'Review PR', assigneeId: user.id, dueDate: tomorrow });
+
+// Hook with options object
+const useTasks = ({ organizationId, initialData }: UseTasksOptions) => { ... };
+const { tasks } = useTasks({ organizationId: orgId, initialData: serverTasks });
+
+// Component props (always named)
+function TaskCard({ task, onComplete, showDetails }: TaskCardProps) { ... }
+
+```
+
+### ❌ Never Do This
+
+```tsx
+// Positional parameters - unclear at call site
+const createTask = (title: string, assigneeId: string, dueDate: Date) => { ... };
+createTask('Review PR', user.id, tomorrow); // What's the 2nd param?
+
+// Multiple positional args are confusing
+const formatRange = (start: Date, end: Date, format: string, timezone: string) => { ... };
+formatRange(startDate, endDate, 'MM/dd', 'UTC'); // Hard to read
+
+// Boolean positional params are the worst
+fetchTasks(orgId, true, false, true); // What do these booleans mean?
+```
+
+### Exception: Single Parameter
+
+```tsx
+// Single param is fine as positional
+const getTask = (taskId: string) => { ... };
+const formatDate = (date: Date) => { ... };
+const isOverdue = (task: Task) => { ... };
+```
+
+## Accessibility
+
+### ✅ Always Include
+
+```tsx
+// Interactive elements need keyboard support
+
e.key === 'Enter' && handleClick()}
+ aria-label="Delete task"
+>
+
+
+
+// Form inputs need labels
+
+
+
+// Images need alt text
+
+```
+
+## DRY Principle
+
+### ✅ Extract Repeated Logic
+
+```tsx
+// Before: Duplicated validation
+if (email && email.includes('@') && email.length > 5) { ... }
+if (email && email.includes('@') && email.length > 5) { ... }
+
+// After: Extracted helper
+const isValidEmail = (email: string) =>
+ email?.includes('@') && email.length > 5;
+
+if (isValidEmail(email)) { ... }
+```
+
+## Checklist
+
+Before committing:
+
+- [ ] No file exceeds 300 lines
+- [ ] Uses early returns for conditionals
+- [ ] Variable/function names are descriptive
+- [ ] Functions with 2+ params use named parameters
+- [ ] Interactive elements have keyboard support
+- [ ] No duplicated logic (DRY)
+- [ ] Const arrow functions with types
diff --git a/.cursor/rules/componentization.mdc b/.cursor/rules/componentization.mdc
new file mode 100644
index 000000000..23fa0af67
--- /dev/null
+++ b/.cursor/rules/componentization.mdc
@@ -0,0 +1,439 @@
+---
+description: Componentization philosophy - reuse over repetition with TailwindCSS and shadcn/ui
+globs: **/*.{ts,tsx}
+alwaysApply: true
+---
+
+# Componentization Philosophy
+
+## Core Principles
+
+### 1. Componentize Everything
+
+**Reuse over repetition.**
+
+- If a pattern appears 2+ times, it MUST be a component
+- No copy-paste UI patterns
+- Every visual element should trace back to a reusable component
+- Manual implementations are technical debt
+
+### 2. Hard Component Enforcement
+
+**Components are immutable contracts.**
+
+```tsx
+// ❌ NEVER - Arbitrary className overrides on design system components
+
+Content
+Status
+
+// ✅ ALWAYS - Use component variants and props
+
+Content
+Status
+```
+
+**Rules:**
+
+- Use Tailwind utility classes in custom components, NOT on design system components
+- Use shadcn/ui variant props (`variant`, `size`) - never override with className
+- Compose from primitives (flex containers, semantic HTML)
+- Use `cn()` utility for conditional class merging
+
+### 3. Extension Strategy
+
+**When you need different styling, extend the component properly.**
+
+#### Option A: Add a Variant (using shadcn patterns)
+
+```tsx
+// In components/ui/badge.tsx - extend variants
+import { cva, type VariantProps } from "class-variance-authority";
+
+const badgeVariants = cva(
+ "inline-flex items-center rounded-md px-2 py-1 text-xs font-medium",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary/10 text-primary",
+ secondary: "bg-secondary text-secondary-foreground",
+ destructive: "bg-destructive/10 text-destructive",
+ outline: "border border-input bg-transparent",
+ // ADD NEW VARIANTS HERE
+ counter: "bg-muted text-muted-foreground tabular-nums font-mono",
+ technical: "bg-teal-500/10 text-teal-600 dark:text-teal-400 font-mono",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+);
+
+// Usage
+03
+SYS.ID
+```
+
+#### Option B: Add Props for Flexibility
+
+```tsx
+// In components/ui/text.tsx - semantic text component
+import { cn } from "@/lib/utils";
+
+interface TextProps extends React.HTMLAttributes {
+ size?: "xs" | "sm" | "base" | "lg";
+ variant?: "default" | "muted" | "primary" | "destructive";
+ mono?: boolean;
+}
+
+const sizeClasses = {
+ xs: "text-xs",
+ sm: "text-sm",
+ base: "text-base",
+ lg: "text-lg",
+};
+
+const variantClasses = {
+ default: "text-foreground",
+ muted: "text-muted-foreground",
+ primary: "text-primary",
+ destructive: "text-destructive",
+};
+
+export const Text = ({
+ size = "base",
+ variant = "default",
+ mono,
+ className,
+ ...props
+}: TextProps) => (
+
+);
+
+// Usage
+Technical Label
+```
+
+#### Option C: Create a New Component
+
+```tsx
+// components/ui/metric-number.tsx
+import { cn } from "@/lib/utils";
+
+interface MetricNumberProps {
+ value: number;
+ size?: "2xl" | "3xl" | "4xl";
+ variant?: "default" | "destructive" | "success";
+}
+
+const sizeClasses = {
+ "2xl": "text-2xl",
+ "3xl": "text-3xl",
+ "4xl": "text-4xl",
+};
+
+const variantClasses = {
+ default: "text-foreground",
+ destructive: "text-red-600 dark:text-red-400",
+ success: "text-green-600 dark:text-green-400",
+};
+
+export const MetricNumber = ({
+ value,
+ size = "4xl",
+ variant = "default"
+}: MetricNumberProps) => (
+
+ {String(value).padStart(2, "0")}
+
+);
+
+// Usage
+
+```
+
+### 4. Reusability Through Composition
+
+**Build complex UIs from simple, focused components.**
+
+```tsx
+// ❌ BAD: Monolithic custom implementation with raw divs and classes
+
+
+
+
+
+ TITLE
+
+ META
+
+
+ 42
+
+
+ SYS.ID
+
+
+
+
+// ✅ GOOD: Composed from reusable components
+
+
+
+```
+
+## Component Development Workflow
+
+### When You Need Custom Styling
+
+1. **Check existing variants**
+ - Review shadcn component variants (`variant`, `size`)
+ - Check if existing props achieve what you need
+
+2. **If existing variants aren't enough, extend the component**
+
+ ```tsx
+ // Add new variant to the cva definition
+ const buttonVariants = cva("...", {
+ variants: {
+ variant: {
+ // existing...
+ newVariant: "bg-teal-500 text-white hover:bg-teal-600", // ADD HERE
+ },
+ },
+ });
+ ```
+
+3. **If it's a new pattern, CREATE A COMPONENT**
+
+ ```tsx
+ // components/ui/your-new-component.tsx
+ import { cn } from "@/lib/utils";
+
+ interface YourNewComponentProps {
+ children: React.ReactNode;
+ variant?: "default" | "muted";
+ }
+
+ export const YourNewComponent = ({
+ children,
+ variant = "default"
+ }: YourNewComponentProps) => (
+
+ {children}
+
+ );
+ ```
+
+4. **NEVER bypass the design system**
+ - Don't add random className overrides
+ - It breaks consistency
+ - It creates technical debt
+
+## Pattern Recognition
+
+### If You See This Pattern 2+ Times → Componentize
+
+```tsx
+// Repeated list item layout
+
+
+ {title}
+ {status}
+
+
+
+→ Create ListItem component
+
+// Repeated counter pattern
+
+ LABEL
+ {count}
+
+→ Create CounterBadge component
+
+// Repeated status dot
+
+→ Create StatusDot component
+
+// Repeated large numbers
+
+ {String(value).padStart(2, "0")}
+
+→ Create MetricNumber component
+```
+
+## Testing Component Compliance
+
+### Before Committing, Check:
+
+- [ ] Uses shadcn/ui base components without className overrides
+- [ ] Semantic props exposed (`variant`, `size`)
+- [ ] No arbitrary style overrides on design system components
+- [ ] Repeated patterns extracted to components
+- [ ] Works in light and dark mode (uses semantic tokens)
+- [ ] Uses Tailwind responsive prefixes (`sm:`, `md:`, `lg:`)
+- [ ] Proper TypeScript types with inference where possible
+
+## Anti-Patterns to Avoid
+
+### ❌ Never Do This
+
+```tsx
+// 1. Raw inline styles
+Content
+
+// 2. Overriding design system components with className
+
+
+// 3. Hardcoded colors instead of semantic tokens
+
+
+// 4. Mixing approaches
+
+
+// 5. Copy-paste UI patterns
+// If you copy UI code, STOP and componentize it first
+
+// 6. Non-responsive hardcoded values
+
+```
+
+### ✅ Always Do This
+
+```tsx
+// 1. Use component variants
+