@polymorphism-tech/morph-spec 4.16.0 → 4.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +36 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +3 -0
- package/bin/task-manager.js +999 -962
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/agents/ai-agents/vector-search-expert.md +247 -233
- package/framework/agents/backend/ms-agent-expert.md +1 -1
- package/framework/agents/backend/neon-expert.md +379 -0
- package/framework/agents/frontend/gsap-animator.md +131 -0
- package/framework/agents/integrations/neon-auth.md +151 -0
- package/framework/agents.json +1183 -1085
- package/framework/commands/morph-preflight.md +200 -192
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +1 -1
- package/framework/rules/gsap-standards.md +13 -0
- package/framework/rules/neon-auth-standards.md +13 -0
- package/framework/rules/neon-standards.md +26 -0
- package/framework/skills/level-0-meta/mcp-registry.json +1 -1
- package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +472 -472
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +12 -12
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +7 -7
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +24 -24
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +12 -12
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +9 -9
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -143
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
- package/framework/standards/STANDARDS.json +197 -116
- package/framework/standards/ai-agents/production.md +1 -0
- package/framework/standards/ai-agents/setup.md +3 -2
- package/framework/standards/ai-agents/workflows.md +1 -0
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +4 -4
- package/framework/standards/backend/database/postgresql/database.md +63 -83
- package/framework/standards/backend/dotnet/scalar-ui.md +172 -172
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -274
- package/framework/standards/backend/integrations/asaas/asaas-api.md +2 -2
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +364 -0
- package/framework/standards/frontend/design-system/animations.md +9 -0
- package/framework/standards/frontend/gsap/gsap-core.md +463 -0
- package/framework/standards/frontend/gsap/gsap-plugins.md +294 -0
- package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +318 -0
- package/framework/standards/frontend/nextjs/motion-patterns.md +1 -0
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +47 -37
- package/framework/standards/infrastructure/docker/easypanel-deploy.md +4 -8
- package/framework/standards/infrastructure/neon/neon-pgrag.md +239 -0
- package/framework/standards/infrastructure/neon/neon-pgvector.md +236 -0
- package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +310 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +186 -0
- package/framework/standards/integration/mcp/mcp-tools.md +32 -34
- package/framework/templates/README.md +20 -20
- package/framework/templates/REGISTRY.json +54 -101
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/backend/repository.cs +148 -148
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
- package/framework/templates/code/dotnet/database/vector-entity.cs +93 -0
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +1 -1
- package/framework/templates/code/sql/{supabase-migration.sql → postgresql-migration.sql} +12 -21
- package/framework/templates/code/sql/{supabase-migration.template.sql → postgresql-migration.template.sql} +13 -18
- package/framework/templates/code/sql/{rls-policy.sql → postgresql-rls-policy.sql} +6 -9
- package/framework/templates/code/typescript/contracts.ts +167 -168
- package/framework/templates/context/CONTEXT.md +3 -3
- package/framework/templates/docs/proposal.md +6 -6
- package/framework/templates/docs/ui-components.md +1 -1
- package/framework/templates/feature/decisions.md +122 -121
- package/framework/templates/feature/recap.md +145 -145
- package/framework/templates/feature/tasks.md +199 -199
- package/framework/templates/frontend/nextjs/gsap-scroll-section.tsx.hbs +44 -0
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -67
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/docker/easypanel.template.json +46 -54
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/integrations/neon-auth-config.cs +133 -0
- package/framework/templates/integrations/semantic-kernel-neon.cs +125 -0
- package/framework/workflows/README.md +1 -1
- package/framework/workflows/docs/full-morph.md +69 -69
- package/package.json +1 -1
- package/src/commands/agents/dispatch-agents.js +19 -15
- package/src/commands/state/advance-phase.js +5 -0
- package/src/commands/tasks/task.js +3 -0
- package/src/core/state/state-manager.js +45 -1
- package/src/core/templates/template-registry.js +1 -66
- package/src/lib/detectors/index.js +4 -4
- package/src/lib/generators/architecture-scanner.js +639 -640
- package/src/lib/installers/mcp-installer.js +1 -1
- package/src/lib/tasks/task-classifier.js +15 -1
- package/src/lib/tasks/test-runner.js +5 -1
- package/src/lib/validators/content/content-validator.js +9 -10
- package/src/lib/validators/validation-runner.js +7 -5
- package/framework/agents/backend/supabase-expert.md +0 -256
- package/framework/agents/integrations/clerk-auth.md +0 -109
- package/framework/rules/clerk-standards.md +0 -13
- package/framework/rules/supabase-standards.md +0 -29
- package/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
- package/framework/standards/infrastructure/supabase/mcp-setup.md +0 -142
- package/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
- package/framework/standards/infrastructure/supabase/supabase-custom-jwt.md +0 -206
- package/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
- package/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
- package/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
- package/framework/templates/integrations/clerk-config.cs +0 -217
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Neon Auth (Better Auth) Integration Standard
|
|
2
|
+
|
|
3
|
+
> **Scope:** universal
|
|
4
|
+
> **Layer:** 2 (on keyword)
|
|
5
|
+
> **Keywords:** neon auth, better auth, authentication, nextjs, user management, session, JWT
|
|
6
|
+
> **Load When:** neon auth or authentication keywords detected
|
|
7
|
+
|
|
8
|
+
Managed authentication powered by Better Auth, with all auth data stored directly in your Neon database (`neon_auth` schema). No external auth providers, no webhooks, no sync delays.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
Neon Auth provides:
|
|
15
|
+
- Pre-built UI components (AuthView, UserButton, SignedIn)
|
|
16
|
+
- Social auth (Google, GitHub, etc.)
|
|
17
|
+
- Session management with HTTP-only cookies
|
|
18
|
+
- JWT tokens for Row-Level Security
|
|
19
|
+
- Branch-isolated auth data (perfect for preview environments)
|
|
20
|
+
- Database as single source of truth
|
|
21
|
+
|
|
22
|
+
**Primary Use Case:** Next.js 15 + App Router + Neon PostgreSQL
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Core Principles
|
|
27
|
+
|
|
28
|
+
1. **Database-First**: Auth data lives in `neon_auth` schema — no external service to sync
|
|
29
|
+
2. **Branch Isolation**: Each Neon branch gets isolated users, sessions, and auth config
|
|
30
|
+
3. **Server-First**: Use server-side auth checks with `auth.getSession()`
|
|
31
|
+
4. **JWT for RLS**: Tokens contain `sub` (user ID), `email`, `role: "authenticated"` for database policies
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Installation & Setup
|
|
36
|
+
|
|
37
|
+
### Install Packages
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install @neondatabase/auth@latest
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Environment Variables
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# .env.local
|
|
47
|
+
NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.us-east-2.aws.neon.build/neondb/auth
|
|
48
|
+
NEON_AUTH_COOKIE_SECRET=your-secret-at-least-32-characters-long
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Generate cookie secret:
|
|
52
|
+
```bash
|
|
53
|
+
openssl rand -base64 32
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### SDK Initialization
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// lib/auth/client.ts
|
|
60
|
+
'use client';
|
|
61
|
+
import { createAuthClient } from '@neondatabase/auth/next';
|
|
62
|
+
export const authClient = createAuthClient();
|
|
63
|
+
|
|
64
|
+
// lib/auth/server.ts
|
|
65
|
+
import { createNeonAuth } from '@neondatabase/auth/next/server';
|
|
66
|
+
export const auth = createNeonAuth({
|
|
67
|
+
baseUrl: process.env.NEON_AUTH_BASE_URL!,
|
|
68
|
+
cookies: {
|
|
69
|
+
secret: process.env.NEON_AUTH_COOKIE_SECRET!,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Root Layout Provider
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// app/providers.tsx
|
|
78
|
+
'use client';
|
|
79
|
+
import { NeonAuthUIProvider } from '@neondatabase/auth/react';
|
|
80
|
+
import '@neondatabase/auth/ui/css';
|
|
81
|
+
import Link from 'next/link';
|
|
82
|
+
import { useRouter } from 'next/navigation';
|
|
83
|
+
import { authClient } from '@/lib/auth/client';
|
|
84
|
+
|
|
85
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
86
|
+
const router = useRouter();
|
|
87
|
+
return (
|
|
88
|
+
<NeonAuthUIProvider
|
|
89
|
+
authClient={authClient}
|
|
90
|
+
navigate={router.push}
|
|
91
|
+
replace={router.replace}
|
|
92
|
+
onSessionChange={router.refresh}
|
|
93
|
+
Link={Link}
|
|
94
|
+
>
|
|
95
|
+
{children}
|
|
96
|
+
</NeonAuthUIProvider>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Auth API Route
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// app/api/auth/[...path]/route.ts
|
|
105
|
+
import { auth } from '@/lib/auth/server';
|
|
106
|
+
|
|
107
|
+
export const { GET, POST } = auth.handler();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Common Patterns
|
|
113
|
+
|
|
114
|
+
### Sign In / Sign Up Pages
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
// app/auth/sign-in/page.tsx
|
|
118
|
+
import { AuthView } from '@neondatabase/auth/react';
|
|
119
|
+
|
|
120
|
+
export default function SignInPage() {
|
|
121
|
+
return (
|
|
122
|
+
<div className="flex items-center justify-center min-h-screen">
|
|
123
|
+
<AuthView pathname="sign-in" />
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// app/auth/sign-up/page.tsx
|
|
129
|
+
import { AuthView } from '@neondatabase/auth/react';
|
|
130
|
+
|
|
131
|
+
export default function SignUpPage() {
|
|
132
|
+
return (
|
|
133
|
+
<div className="flex items-center justify-center min-h-screen">
|
|
134
|
+
<AuthView pathname="sign-up" />
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Server-Side Auth Check
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// app/dashboard/page.tsx
|
|
144
|
+
import { auth } from '@/lib/auth/server';
|
|
145
|
+
import { redirect } from 'next/navigation';
|
|
146
|
+
|
|
147
|
+
export const dynamic = 'force-dynamic';
|
|
148
|
+
|
|
149
|
+
export default async function DashboardPage() {
|
|
150
|
+
const { data: session } = await auth.getSession();
|
|
151
|
+
|
|
152
|
+
if (!session?.user) {
|
|
153
|
+
redirect('/auth/sign-in');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return <div>Dashboard for {session.user.name || session.user.email}</div>;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Client Component with User Data
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
// components/UserProfile.tsx
|
|
164
|
+
'use client';
|
|
165
|
+
import { useSession } from '@/lib/auth/client';
|
|
166
|
+
|
|
167
|
+
export function UserProfile() {
|
|
168
|
+
const { data } = useSession();
|
|
169
|
+
const user = data?.user;
|
|
170
|
+
|
|
171
|
+
if (!user) return <div>Not signed in</div>;
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div>
|
|
175
|
+
<p>Welcome, {user.name || user.email}!</p>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Route Protection (Middleware)
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// middleware.ts
|
|
185
|
+
import { auth } from '@/lib/auth/server';
|
|
186
|
+
|
|
187
|
+
export default auth.middleware({
|
|
188
|
+
loginUrl: '/auth/sign-in',
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
export const config = {
|
|
192
|
+
matcher: [
|
|
193
|
+
'/dashboard/:path*',
|
|
194
|
+
'/settings/:path*',
|
|
195
|
+
'/((?!_next/static|_next/image|favicon.ico|auth).*)',
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Component-Level Protection
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
import { SignedIn, RedirectToSignIn } from '@neondatabase/auth/react';
|
|
204
|
+
|
|
205
|
+
export default function ProtectedPage() {
|
|
206
|
+
return (
|
|
207
|
+
<>
|
|
208
|
+
<SignedIn>
|
|
209
|
+
<div>Protected content</div>
|
|
210
|
+
</SignedIn>
|
|
211
|
+
<RedirectToSignIn />
|
|
212
|
+
</>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## OAuth (Social Login)
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Trigger OAuth sign-in
|
|
223
|
+
await authClient.signIn.social({
|
|
224
|
+
provider: 'google',
|
|
225
|
+
callbackURL: 'http://localhost:3000/auth/callback',
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Configure OAuth providers in the Neon Console under Auth > Configuration.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## API Route Protection
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// app/api/protected/route.ts
|
|
237
|
+
import { auth } from '@/lib/auth/server';
|
|
238
|
+
|
|
239
|
+
export const dynamic = 'force-dynamic';
|
|
240
|
+
|
|
241
|
+
export async function GET() {
|
|
242
|
+
const { data: session } = await auth.getSession();
|
|
243
|
+
|
|
244
|
+
if (!session?.user) {
|
|
245
|
+
return new Response('Unauthorized', { status: 401 });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return Response.json({ userId: session.user.id });
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## .NET Backend Integration
|
|
255
|
+
|
|
256
|
+
Neon Auth issues standard JWTs. The .NET API validates these tokens directly — no external auth SDK needed.
|
|
257
|
+
|
|
258
|
+
### JWT Bearer Configuration
|
|
259
|
+
|
|
260
|
+
```csharp
|
|
261
|
+
// Program.cs
|
|
262
|
+
builder.Services.AddAuthentication("NeonAuth")
|
|
263
|
+
.AddJwtBearer("NeonAuth", options =>
|
|
264
|
+
{
|
|
265
|
+
options.Authority = builder.Configuration["NeonAuth:BaseUrl"];
|
|
266
|
+
options.TokenValidationParameters = new()
|
|
267
|
+
{
|
|
268
|
+
ValidateIssuer = true,
|
|
269
|
+
ValidateAudience = false,
|
|
270
|
+
ValidateLifetime = true,
|
|
271
|
+
ValidateIssuerSigningKey = true,
|
|
272
|
+
NameClaimType = "sub"
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
builder.Services.AddAuthorization();
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Protected Endpoints
|
|
280
|
+
|
|
281
|
+
```csharp
|
|
282
|
+
app.MapGet("/api/profile", (ClaimsPrincipal user) =>
|
|
283
|
+
{
|
|
284
|
+
var userId = user.FindFirstValue("sub");
|
|
285
|
+
if (userId is null) return Results.Unauthorized();
|
|
286
|
+
return Results.Ok(new { UserId = userId });
|
|
287
|
+
}).RequireAuthorization();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### appsettings.json
|
|
291
|
+
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"NeonAuth": {
|
|
295
|
+
"BaseUrl": "https://ep-xxx.neonauth.us-east-2.aws.neon.build/neondb/auth"
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Row-Level Security Integration
|
|
303
|
+
|
|
304
|
+
Neon Auth JWT tokens are automatically validated by the Data API. The `auth.user_id()` function (via `pg_session_jwt` extension) exposes the authenticated user ID from the JWT `sub` claim.
|
|
305
|
+
|
|
306
|
+
```sql
|
|
307
|
+
-- Enable RLS
|
|
308
|
+
ALTER TABLE public.documents ENABLE ROW LEVEL SECURITY;
|
|
309
|
+
|
|
310
|
+
-- Users can only access their own rows
|
|
311
|
+
CREATE POLICY "Users can view own documents"
|
|
312
|
+
ON public.documents FOR SELECT TO authenticated
|
|
313
|
+
USING (user_id = auth.user_id());
|
|
314
|
+
|
|
315
|
+
CREATE POLICY "Users can insert own documents"
|
|
316
|
+
ON public.documents FOR INSERT TO authenticated
|
|
317
|
+
WITH CHECK (user_id = auth.user_id());
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Database Schema
|
|
323
|
+
|
|
324
|
+
Neon Auth automatically manages the `neon_auth` schema with these tables:
|
|
325
|
+
- `neon_auth.user` — User profiles
|
|
326
|
+
- `neon_auth.session` — Active sessions
|
|
327
|
+
- `neon_auth.account` — Auth credentials (password hashes, OAuth tokens)
|
|
328
|
+
|
|
329
|
+
You can query these tables directly for user data — no webhook sync needed:
|
|
330
|
+
```sql
|
|
331
|
+
SELECT id, email, name FROM neon_auth.user WHERE id = auth.user_id();
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Branch Isolation
|
|
337
|
+
|
|
338
|
+
Each Neon branch gets its own isolated auth data. This means:
|
|
339
|
+
- Preview branches have separate users and sessions
|
|
340
|
+
- Feature branches don't share auth state with production
|
|
341
|
+
- Perfect for PR preview environments
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Best Practices
|
|
346
|
+
|
|
347
|
+
1. **Always use `force-dynamic`** on pages/routes that call `auth.getSession()`
|
|
348
|
+
2. **Cookie secret must be 32+ characters** — generate with `openssl rand -base64 32`
|
|
349
|
+
3. **Use `auth.user_id()` for RLS** — never extract JWT claims manually in SQL
|
|
350
|
+
4. **Configure OAuth in Neon Console** — not in code
|
|
351
|
+
5. **Use `SignedIn` / `RedirectToSignIn`** for client-side protection
|
|
352
|
+
6. **Use middleware** for broad route protection patterns
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## References
|
|
357
|
+
|
|
358
|
+
- [Neon Auth Documentation](https://neon.com/docs/auth)
|
|
359
|
+
- [Neon Auth Authentication Flow](https://neon.com/docs/auth/authentication-flow)
|
|
360
|
+
- [Migration from Legacy Auth](https://neon.com/docs/auth/migrate/from-legacy-auth)
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -146,6 +146,15 @@ else { <h2>@_title</h2> }
|
|
|
146
146
|
- [ ] `@media (prefers-reduced-motion)` implemented
|
|
147
147
|
- [ ] Shimmer for loading states
|
|
148
148
|
|
|
149
|
+
## JavaScript Animation Libraries
|
|
150
|
+
|
|
151
|
+
For animations beyond CSS capabilities:
|
|
152
|
+
|
|
153
|
+
| Need | Library | Standard |
|
|
154
|
+
|------|---------|----------|
|
|
155
|
+
| Simple UI transitions (enter/exit, layout, gestures) | Framer Motion | `frontend/nextjs/motion-patterns.md` |
|
|
156
|
+
| Complex animations (ScrollTrigger, SVG morph, timelines) | GSAP | `frontend/gsap/gsap-core.md` |
|
|
157
|
+
|
|
149
158
|
---
|
|
150
159
|
|
|
151
160
|
*MORPH-SPEC by Polymorphism Tech*
|