create-agentic-app 1.1.56 → 1.1.58
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/package.json +1 -1
- package/template/.agents/skills/security-scanner/SKILL.md +157 -0
- package/template/.agents/skills/security-scanner/references/A01-broken-access-control.md +136 -0
- package/template/.agents/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
- package/template/.agents/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
- package/template/.agents/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
- package/template/.agents/skills/security-scanner/references/A05-injection.md +155 -0
- package/template/.agents/skills/security-scanner/references/A06-insecure-design.md +145 -0
- package/template/.agents/skills/security-scanner/references/A07-authentication-failures.md +150 -0
- package/template/.agents/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
- package/template/.agents/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
- package/template/.agents/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
- package/template/.agents/skills/security-scanner/references/report-template.md +148 -0
- package/template/.claude/agents/security-scanner.md +214 -0
- package/template/.claude/skills/security-scanner/SKILL.md +157 -0
- package/template/.claude/skills/security-scanner/references/A01-broken-access-control.md +136 -0
- package/template/.claude/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
- package/template/.claude/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
- package/template/.claude/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
- package/template/.claude/skills/security-scanner/references/A05-injection.md +155 -0
- package/template/.claude/skills/security-scanner/references/A06-insecure-design.md +145 -0
- package/template/.claude/skills/security-scanner/references/A07-authentication-failures.md +150 -0
- package/template/.claude/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
- package/template/.claude/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
- package/template/.claude/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
- package/template/.claude/skills/security-scanner/references/report-template.md +148 -0
- package/template/AGENTS.md +21 -77
- package/template/DESIGN.md +451 -0
- package/template/next-env.d.ts +1 -1
- package/template/specs/ui-polish-responsive/README.md +59 -0
- package/template/specs/ui-polish-responsive/action-required.md +3 -0
- package/template/specs/ui-polish-responsive/requirements.md +53 -0
- package/template/specs/ui-polish-responsive/tasks/task-01-globals-css.md +144 -0
- package/template/specs/ui-polish-responsive/tasks/task-02-layout.md +66 -0
- package/template/specs/ui-polish-responsive/tasks/task-03-site-header.md +79 -0
- package/template/specs/ui-polish-responsive/tasks/task-04-site-footer.md +63 -0
- package/template/specs/ui-polish-responsive/tasks/task-05-home-page.md +215 -0
- package/template/specs/ui-polish-responsive/tasks/task-06-dashboard.md +222 -0
- package/template/specs/ui-polish-responsive/tasks/task-07-chat-page.md +225 -0
- package/template/specs/ui-polish-responsive/tasks/task-08-profile-page.md +192 -0
- package/template/specs/ui-polish-responsive/tasks/task-09-auth-pages.md +97 -0
- package/template/specs/ui-polish-responsive/tasks/task-10-setup-checklist.md +120 -0
- package/template/specs/ui-polish-responsive/tasks/task-11-starter-prompt-modal.md +87 -0
- package/template/src/app/globals.css +65 -7
- package/template/src/app/layout.tsx +2 -2
- package/template/src/app/page.tsx +174 -174
- package/template/src/components/setup-checklist.tsx +162 -162
- package/template/src/components/site-footer.tsx +2 -2
- package/template/src/components/site-header.tsx +3 -3
- package/template/src/components/starter-prompt-modal.tsx +202 -202
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Task 09: Auth Pages
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
pending
|
|
6
|
+
|
|
7
|
+
## Wave
|
|
8
|
+
|
|
9
|
+
2
|
|
10
|
+
|
|
11
|
+
## Description
|
|
12
|
+
|
|
13
|
+
Polish all 4 auth pages (login, register, forgot-password, reset-password) with entrance animations, card shadows, a subtle background gradient, and improved vertical centering that works with the new flex layout. These pages are the first thing new users see, so visual polish matters.
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
|
|
17
|
+
**Depends on:** task-01-globals-css.md, task-02-layout.md
|
|
18
|
+
**Blocks:** None
|
|
19
|
+
|
|
20
|
+
**Context from dependencies:** Task 01 defines the `auth-bg` utility class (radial gradient from accent color) and the `animate-fade-up` animation in globals.css. Task 02 adds `flex-1` to the `<main>` element, so auth pages can use `flex-1` to fill available vertical space properly.
|
|
21
|
+
|
|
22
|
+
## Files to Modify
|
|
23
|
+
|
|
24
|
+
- `src/app/(auth)/login/page.tsx` — Add animation, shadow, background, update min-height
|
|
25
|
+
- `src/app/(auth)/register/page.tsx` — Same changes
|
|
26
|
+
- `src/app/(auth)/forgot-password/page.tsx` — Same changes
|
|
27
|
+
- `src/app/(auth)/reset-password/page.tsx` — Same changes
|
|
28
|
+
|
|
29
|
+
## Technical Details
|
|
30
|
+
|
|
31
|
+
### Implementation Steps
|
|
32
|
+
|
|
33
|
+
All 4 files follow the exact same pattern. Each has an outer wrapper div with a Card inside.
|
|
34
|
+
|
|
35
|
+
#### For each file, make these 2 changes:
|
|
36
|
+
|
|
37
|
+
**Change 1: Update the wrapper div.** Each file has:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<div className="flex min-h-[calc(100vh-4rem)] items-center justify-center p-4">
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Change to:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
<div className="auth-bg flex flex-1 min-h-[calc(100vh-8rem)] items-center justify-center p-4">
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Changes:
|
|
50
|
+
- `auth-bg` — adds the subtle radial gradient background from globals.css
|
|
51
|
+
- `flex-1` — fills available space in the flex column layout (from Task 02)
|
|
52
|
+
- `min-h-[calc(100vh-8rem)]` — accounts for both header and footer height (was just 4rem for header)
|
|
53
|
+
|
|
54
|
+
**Change 2: Add shadow and animation to the Card.** Each file has:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<Card className="w-full max-w-md">
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Change to:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<Card className="w-full max-w-md shadow-lg animate-fade-up">
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Changes:
|
|
67
|
+
- `shadow-lg` — adds elevation/depth to the card
|
|
68
|
+
- `animate-fade-up` — entrance animation (defined in globals.css keyframes, registered in @theme inline)
|
|
69
|
+
|
|
70
|
+
### File-specific locations:
|
|
71
|
+
|
|
72
|
+
**login/page.tsx:**
|
|
73
|
+
- Wrapper div: line 27
|
|
74
|
+
- Card: line 28
|
|
75
|
+
|
|
76
|
+
**register/page.tsx:**
|
|
77
|
+
- Wrapper div: line 20
|
|
78
|
+
- Card: line 21
|
|
79
|
+
|
|
80
|
+
**forgot-password/page.tsx:**
|
|
81
|
+
- Wrapper div: line 21
|
|
82
|
+
- Card: line 22
|
|
83
|
+
|
|
84
|
+
**reset-password/page.tsx:**
|
|
85
|
+
- Wrapper div: line 21
|
|
86
|
+
- Card: line 22
|
|
87
|
+
|
|
88
|
+
## Acceptance Criteria
|
|
89
|
+
|
|
90
|
+
- [ ] All 4 auth pages have `auth-bg` class on the wrapper div
|
|
91
|
+
- [ ] All 4 auth pages have `flex-1 min-h-[calc(100vh-8rem)]` on the wrapper div
|
|
92
|
+
- [ ] All 4 auth cards have `shadow-lg` for depth
|
|
93
|
+
- [ ] All 4 auth cards have `animate-fade-up` for entrance animation
|
|
94
|
+
- [ ] Cards animate upward on page load (smooth fade + translate)
|
|
95
|
+
- [ ] Subtle radial gradient visible in the background (especially visible in dark mode)
|
|
96
|
+
- [ ] Footer stays at the bottom of the viewport on all auth pages
|
|
97
|
+
- [ ] No visual regressions to auth form functionality
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Task 10: Setup Checklist Card Adoption
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
pending
|
|
6
|
+
|
|
7
|
+
## Wave
|
|
8
|
+
|
|
9
|
+
2
|
|
10
|
+
|
|
11
|
+
## Description
|
|
12
|
+
|
|
13
|
+
Replace the bare `<div>` wrapper in the SetupChecklist component with a shadcn Card component for visual consistency with the rest of the app. The checklist is displayed on the home page and currently uses `p-6 border rounded-lg` which is the same pattern as the feature cards that are being upgraded to shadcn Cards.
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
|
|
17
|
+
**Depends on:** task-01-globals-css.md
|
|
18
|
+
**Blocks:** None
|
|
19
|
+
|
|
20
|
+
**Context from dependencies:** Task 01 updates the color palette. The setup checklist does not use `card-interactive` since it's an informational display, not a clickable card.
|
|
21
|
+
|
|
22
|
+
## Files to Modify
|
|
23
|
+
|
|
24
|
+
- `src/components/setup-checklist.tsx` — Replace wrapper div with shadcn Card
|
|
25
|
+
|
|
26
|
+
## Technical Details
|
|
27
|
+
|
|
28
|
+
### Implementation Steps
|
|
29
|
+
|
|
30
|
+
1. **Add Card imports.** Add at the top:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import {
|
|
34
|
+
Card,
|
|
35
|
+
CardContent,
|
|
36
|
+
CardHeader,
|
|
37
|
+
CardTitle,
|
|
38
|
+
} from "@/components/ui/card";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. **Replace the outer wrapper** (line 124). The current structure is:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
<div className="p-6 border rounded-lg text-left">
|
|
45
|
+
<div className="flex items-center justify-between mb-4">
|
|
46
|
+
<div>
|
|
47
|
+
<h3 className="font-semibold">Setup checklist</h3>
|
|
48
|
+
<p className="text-sm text-muted-foreground">
|
|
49
|
+
{completed}/{steps.length} completed
|
|
50
|
+
</p>
|
|
51
|
+
</div>
|
|
52
|
+
<Button size="sm" onClick={load} disabled={loading}>
|
|
53
|
+
{loading ? "Checking..." : "Re-check"}
|
|
54
|
+
</Button>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
{error ? <div className="text-sm text-destructive">{error}</div> : null}
|
|
58
|
+
|
|
59
|
+
<ul className="space-y-2">
|
|
60
|
+
...checklist items...
|
|
61
|
+
</ul>
|
|
62
|
+
|
|
63
|
+
{data ? (
|
|
64
|
+
<div className="mt-4 text-xs text-muted-foreground">
|
|
65
|
+
Last checked: {new Date(data.timestamp).toLocaleString()}
|
|
66
|
+
</div>
|
|
67
|
+
) : null}
|
|
68
|
+
</div>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Replace with:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<Card className="text-left">
|
|
75
|
+
<CardHeader className="pb-4">
|
|
76
|
+
<div className="flex items-center justify-between">
|
|
77
|
+
<div>
|
|
78
|
+
<CardTitle className="text-base">Setup checklist</CardTitle>
|
|
79
|
+
<p className="text-sm text-muted-foreground">
|
|
80
|
+
{completed}/{steps.length} completed
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
83
|
+
<Button size="sm" onClick={load} disabled={loading}>
|
|
84
|
+
{loading ? "Checking..." : "Re-check"}
|
|
85
|
+
</Button>
|
|
86
|
+
</div>
|
|
87
|
+
</CardHeader>
|
|
88
|
+
<CardContent>
|
|
89
|
+
{error ? <div className="text-sm text-destructive mb-4">{error}</div> : null}
|
|
90
|
+
|
|
91
|
+
<ul className="space-y-2">
|
|
92
|
+
...checklist items stay the same...
|
|
93
|
+
</ul>
|
|
94
|
+
|
|
95
|
+
{data ? (
|
|
96
|
+
<div className="mt-4 text-xs text-muted-foreground">
|
|
97
|
+
Last checked: {new Date(data.timestamp).toLocaleString()}
|
|
98
|
+
</div>
|
|
99
|
+
) : null}
|
|
100
|
+
</CardContent>
|
|
101
|
+
</Card>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Key changes:
|
|
105
|
+
- Outer `<div>` → `<Card>`
|
|
106
|
+
- Title area wrapped in `<CardHeader>` with the flex row inside
|
|
107
|
+
- `h3` → `<CardTitle className="text-base">` (text-base to match current visual size)
|
|
108
|
+
- Content wrapped in `<CardContent>`
|
|
109
|
+
- Error div gets `mb-4` since CardContent doesn't have the same padding structure
|
|
110
|
+
- All checklist items and timestamp stay exactly the same
|
|
111
|
+
|
|
112
|
+
## Acceptance Criteria
|
|
113
|
+
|
|
114
|
+
- [ ] Setup checklist uses shadcn `Card`/`CardHeader`/`CardTitle`/`CardContent`
|
|
115
|
+
- [ ] Visual appearance is consistent — no jarring size or spacing changes
|
|
116
|
+
- [ ] Title uses `CardTitle` with `text-base` to maintain current size
|
|
117
|
+
- [ ] Re-check button still works and is positioned to the right of the title
|
|
118
|
+
- [ ] Error state still displays correctly
|
|
119
|
+
- [ ] Checklist items render identically to before
|
|
120
|
+
- [ ] No TypeScript errors
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Task 11: Starter Prompt Modal
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
pending
|
|
6
|
+
|
|
7
|
+
## Wave
|
|
8
|
+
|
|
9
|
+
2
|
|
10
|
+
|
|
11
|
+
## Description
|
|
12
|
+
|
|
13
|
+
Replace the native `<textarea>` in the StarterPromptModal with the shadcn Textarea component for visual consistency, and make the button row responsive so buttons stack on very small screens.
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
|
|
17
|
+
**Depends on:** task-01-globals-css.md
|
|
18
|
+
**Blocks:** None
|
|
19
|
+
|
|
20
|
+
**Context from dependencies:** Task 01 updates the color palette. No utility classes from Task 01 are used in this component.
|
|
21
|
+
|
|
22
|
+
## Files to Modify
|
|
23
|
+
|
|
24
|
+
- `src/components/starter-prompt-modal.tsx` — Replace native textarea, update button layout
|
|
25
|
+
|
|
26
|
+
## Technical Details
|
|
27
|
+
|
|
28
|
+
### Implementation Steps
|
|
29
|
+
|
|
30
|
+
1. **Add Textarea import.** Add at the top:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
2. **Replace native `<textarea>`** (lines 161-167). Change:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<textarea
|
|
40
|
+
id="project-description"
|
|
41
|
+
placeholder="e.g., A task management app for teams with real-time collaboration, project timelines, and AI-powered task prioritization..."
|
|
42
|
+
value={projectDescription}
|
|
43
|
+
onChange={(e) => setProjectDescription(e.target.value)}
|
|
44
|
+
className="w-full h-24 px-3 py-2 border rounded-md resize-none text-sm"
|
|
45
|
+
/>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
<Textarea
|
|
52
|
+
id="project-description"
|
|
53
|
+
placeholder="e.g., A task management app for teams with real-time collaboration, project timelines, and AI-powered task prioritization..."
|
|
54
|
+
value={projectDescription}
|
|
55
|
+
onChange={(e) => setProjectDescription(e.target.value)}
|
|
56
|
+
className="h-24 resize-none"
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Key changes:
|
|
61
|
+
- `<textarea>` → `<Textarea>` (shadcn component)
|
|
62
|
+
- Remove explicit `w-full px-3 py-2 border rounded-md text-sm` — the shadcn Textarea handles these styles internally
|
|
63
|
+
- Keep `h-24 resize-none` as overrides
|
|
64
|
+
|
|
65
|
+
3. **Update button row** (line 174). Change:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
className="flex gap-2"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
To:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
className="flex flex-col-reverse sm:flex-row gap-2"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This makes the buttons stack on mobile (with Cancel on top via `flex-col-reverse`) and sit side-by-side on sm+.
|
|
78
|
+
|
|
79
|
+
## Acceptance Criteria
|
|
80
|
+
|
|
81
|
+
- [ ] Textarea uses shadcn `Textarea` component, not a native `<textarea>`
|
|
82
|
+
- [ ] Textarea has consistent focus ring styling matching other form elements
|
|
83
|
+
- [ ] Button row stacks on mobile (`flex-col-reverse`) and is horizontal on sm+ (`sm:flex-row`)
|
|
84
|
+
- [ ] "Copy Starter Prompt" button appears before "Cancel" button in both layouts
|
|
85
|
+
- [ ] Textarea placeholder text renders correctly
|
|
86
|
+
- [ ] Copy functionality still works (the `projectDescription` state binding is unchanged)
|
|
87
|
+
- [ ] No TypeScript errors
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
2
3
|
|
|
3
4
|
@theme inline {
|
|
4
5
|
--color-background: var(--background);
|
|
@@ -36,6 +37,9 @@
|
|
|
36
37
|
--radius-md: calc(var(--radius) - 2px);
|
|
37
38
|
--radius-lg: var(--radius);
|
|
38
39
|
--radius-xl: calc(var(--radius) + 4px);
|
|
40
|
+
--animate-fade-in: fade-in 0.3s ease-out;
|
|
41
|
+
--animate-fade-up: fade-up 0.4s ease-out;
|
|
42
|
+
--animate-scale-in: scale-in 0.2s ease-out;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
:root {
|
|
@@ -46,18 +50,18 @@
|
|
|
46
50
|
--card-foreground: oklch(0.141 0.005 285.823);
|
|
47
51
|
--popover: oklch(1 0 0);
|
|
48
52
|
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
49
|
-
--primary: oklch(0.21 0.
|
|
53
|
+
--primary: oklch(0.21 0.034 270);
|
|
50
54
|
--primary-foreground: oklch(0.985 0 0);
|
|
51
55
|
--secondary: oklch(0.967 0.001 286.375);
|
|
52
56
|
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
53
57
|
--muted: oklch(0.967 0.001 286.375);
|
|
54
58
|
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
55
|
-
--accent: oklch(0.
|
|
59
|
+
--accent: oklch(0.96 0.012 270);
|
|
56
60
|
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
57
61
|
--destructive: oklch(0.577 0.245 27.325);
|
|
58
62
|
--border: oklch(0.92 0.004 286.32);
|
|
59
63
|
--input: oklch(0.92 0.004 286.32);
|
|
60
|
-
--ring: oklch(0.705 0.
|
|
64
|
+
--ring: oklch(0.705 0.06 270);
|
|
61
65
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
62
66
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
63
67
|
--chart-3: oklch(0.398 0.07 227.392);
|
|
@@ -80,18 +84,18 @@
|
|
|
80
84
|
--card-foreground: oklch(0.985 0 0);
|
|
81
85
|
--popover: oklch(0.21 0.006 285.885);
|
|
82
86
|
--popover-foreground: oklch(0.985 0 0);
|
|
83
|
-
--primary: oklch(0.92 0.
|
|
87
|
+
--primary: oklch(0.92 0.02 270);
|
|
84
88
|
--primary-foreground: oklch(0.21 0.006 285.885);
|
|
85
89
|
--secondary: oklch(0.274 0.006 286.033);
|
|
86
90
|
--secondary-foreground: oklch(0.985 0 0);
|
|
87
91
|
--muted: oklch(0.274 0.006 286.033);
|
|
88
92
|
--muted-foreground: oklch(0.705 0.015 286.067);
|
|
89
|
-
--accent: oklch(0.
|
|
93
|
+
--accent: oklch(0.28 0.018 270);
|
|
90
94
|
--accent-foreground: oklch(0.985 0 0);
|
|
91
95
|
--destructive: oklch(0.704 0.191 22.216);
|
|
92
96
|
--border: oklch(1 0 0 / 10%);
|
|
93
97
|
--input: oklch(1 0 0 / 15%);
|
|
94
|
-
--ring: oklch(0.552 0.
|
|
98
|
+
--ring: oklch(0.552 0.05 270);
|
|
95
99
|
--chart-1: oklch(0.488 0.243 264.376);
|
|
96
100
|
--chart-2: oklch(0.696 0.17 162.48);
|
|
97
101
|
--chart-3: oklch(0.769 0.188 70.08);
|
|
@@ -107,11 +111,65 @@
|
|
|
107
111
|
--sidebar-ring: oklch(0.552 0.016 285.938);
|
|
108
112
|
}
|
|
109
113
|
|
|
114
|
+
@keyframes fade-in {
|
|
115
|
+
from {
|
|
116
|
+
opacity: 0;
|
|
117
|
+
}
|
|
118
|
+
to {
|
|
119
|
+
opacity: 1;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@keyframes fade-up {
|
|
124
|
+
from {
|
|
125
|
+
opacity: 0;
|
|
126
|
+
transform: translateY(8px);
|
|
127
|
+
}
|
|
128
|
+
to {
|
|
129
|
+
opacity: 1;
|
|
130
|
+
transform: translateY(0);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@keyframes scale-in {
|
|
135
|
+
from {
|
|
136
|
+
opacity: 0;
|
|
137
|
+
transform: scale(0.97);
|
|
138
|
+
}
|
|
139
|
+
to {
|
|
140
|
+
opacity: 1;
|
|
141
|
+
transform: scale(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
110
145
|
@layer base {
|
|
111
146
|
* {
|
|
112
147
|
@apply border-border;
|
|
113
148
|
}
|
|
149
|
+
html {
|
|
150
|
+
scroll-behavior: smooth;
|
|
151
|
+
}
|
|
114
152
|
body {
|
|
115
153
|
@apply bg-background text-foreground;
|
|
154
|
+
font-feature-settings: "rlig" 1, "calt" 1;
|
|
155
|
+
}
|
|
156
|
+
:focus-visible {
|
|
157
|
+
@apply outline-2 outline-offset-2 outline-ring;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@layer utilities {
|
|
162
|
+
.card-interactive {
|
|
163
|
+
@apply transition-all duration-200 ease-out;
|
|
164
|
+
}
|
|
165
|
+
.card-interactive:hover {
|
|
166
|
+
@apply shadow-md -translate-y-0.5;
|
|
116
167
|
}
|
|
117
|
-
|
|
168
|
+
.auth-bg {
|
|
169
|
+
background-image: radial-gradient(
|
|
170
|
+
circle at 50% 0%,
|
|
171
|
+
var(--accent) 0%,
|
|
172
|
+
transparent 50%
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -89,7 +89,7 @@ export default function RootLayout({
|
|
|
89
89
|
/>
|
|
90
90
|
</head>
|
|
91
91
|
<body
|
|
92
|
-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
92
|
+
className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`}
|
|
93
93
|
>
|
|
94
94
|
<ThemeProvider
|
|
95
95
|
attribute="class"
|
|
@@ -98,7 +98,7 @@ export default function RootLayout({
|
|
|
98
98
|
disableTransitionOnChange
|
|
99
99
|
>
|
|
100
100
|
<SiteHeader />
|
|
101
|
-
<main id="main-content">{children}</main>
|
|
101
|
+
<main id="main-content" className="flex-1">{children}</main>
|
|
102
102
|
<SiteFooter />
|
|
103
103
|
<Toaster richColors position="top-right" />
|
|
104
104
|
</ThemeProvider>
|