create-lyrajs 1.1.3 → 2.0.1

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.
Files changed (31) hide show
  1. package/README.md +55 -17
  2. package/package.json +2 -2
  3. package/template/backups/README.md +93 -0
  4. package/template/config/security.yaml +0 -1
  5. package/template/migrations/README.md +247 -0
  6. package/template/package.json +2 -6
  7. package/template/public/assets/logo.png +0 -0
  8. package/template/public/assets/styles/app.css +158 -0
  9. package/template/src/controller/AuthController.ts +100 -71
  10. package/template/src/controller/ErrorController.ts +126 -0
  11. package/template/src/controller/ExampleController.ts +28 -0
  12. package/template/src/controller/ExampleStaticController.ts +40 -0
  13. package/template/src/controller/UserController.ts +63 -45
  14. package/template/src/fixtures/{AppFixtures.ts → UserFixtures.ts} +4 -5
  15. package/template/src/jobs/ExampleJob.ts +63 -0
  16. package/template/src/middleware/YourMiddleware.ts +1 -1
  17. package/template/src/repository/UserRepository.ts +2 -3
  18. package/template/src/router/index.ts +3 -10
  19. package/template/src/router/routes/exampleRoutes.ts +7 -0
  20. package/template/src/router/routes/index.ts +4 -6
  21. package/template/src/server.ts +41 -26
  22. package/template/src/services/YourService.ts +3 -1
  23. package/template/src/templates/ExampleRender.tsx +24 -0
  24. package/template/src/templates/README.md +271 -0
  25. package/template/src/templates/layout/Base.tsx +23 -0
  26. package/template/src/templates/layout/Footer.tsx +11 -0
  27. package/template/src/templates/layout/Header.tsx +10 -0
  28. package/template/tsconfig.json +8 -4
  29. package/template/migrations/migration_1752052338457.sql +0 -4
  30. package/template/src/router/routes/authRoutes.ts +0 -13
  31. package/template/src/router/routes/userRoutes.ts +0 -11
package/README.md CHANGED
@@ -31,20 +31,44 @@ When developers run `npm create lyrajs`, this tool copies the template folder to
31
31
  - JWT token generation (access + refresh tokens)
32
32
  - Password hashing with bcrypt
33
33
  - Protected routes via configuration
34
+ - Enhanced with dependency injection 🆕
34
35
 
35
36
  2. **User Management**
36
37
  - User entity with role support
37
38
  - UserRepository with custom queries
38
- - UserController with CRUD operations
39
- - Complete user routes
39
+ - UserController with CRUD operations and decorator support 🆕
40
+ - Flexible routing (traditional routes or decorators) 🆕
40
41
 
41
42
  3. **Database Setup**
42
43
  - MySQL/MariaDB configuration
43
- - Migration system ready to use
44
+ - Migration system with backup/restore 🆕
44
45
  - Example entity (User)
45
- - Fixture system for seed data
46
-
47
- 4. **Configuration Files**
46
+ - Enhanced fixture system with dependencies 🆕
47
+
48
+ 4. **Server-Side Rendering (SSR)** 🆕
49
+ - JSX/TSX template engine configured
50
+ - Example template files
51
+ - Layout system for consistent page structure
52
+ - Ready to use for HTML responses
53
+
54
+ 5. **Job Scheduling** 🆕
55
+ - Pre-configured scheduler system
56
+ - Example job with cron schedule
57
+ - Timezone support
58
+ - Jobs auto-discovered from `src/jobs/`
59
+
60
+ 6. **Static Assets** 🆕
61
+ - Public directory for static files
62
+ - Configured static file serving
63
+ - Ready for images, CSS, fonts, etc.
64
+
65
+ 7. **Dependency Injection** 🆕
66
+ - DI container configured
67
+ - Third-party libraries registered (bcrypt, jwt)
68
+ - Auto-injection in controllers and services
69
+ - Singleton service management
70
+
71
+ 8. **Configuration Files**
48
72
  - `database.yaml` - Database connection settings
49
73
  - `security.yaml` - JWT and access control rules
50
74
  - `router.yaml` - API base path configuration
@@ -52,46 +76,55 @@ When developers run `npm create lyrajs`, this tool copies the template folder to
52
76
  - `mailer.yaml` - Email service settings
53
77
  - `.env` - Environment variables
54
78
 
55
- 5. **Project Structure**
79
+ 9. **Project Structure**
56
80
  - TypeScript configuration
57
81
  - ESLint and Prettier setup
58
- - Organized folder structure (controller, entity, repository, router, etc.)
59
- - Example code demonstrating patterns
82
+ - Organized folder structure with new v2 directories
83
+ - Example code demonstrating both traditional and modern patterns
60
84
 
61
- 6. **Development Tools**
85
+ 10. **Development Tools**
62
86
  - Hot reload with `npm run dev`
63
87
  - Build scripts
64
88
  - Type definitions
65
89
  - Path aliases configured
90
+ - Enhanced CLI with new commands 🆕
66
91
 
67
92
  ### Project Structure
68
93
 
69
94
  ```
70
95
  my-project/
71
96
  ├── src/
72
- │ ├── controller/ # HTTP request handlers
97
+ │ ├── controller/ # HTTP controllers (decorator or traditional)
73
98
  │ │ ├── AuthController.ts # Registration, login, logout
74
99
  │ │ └── UserController.ts # User CRUD operations
75
100
  │ ├── entity/ # Database models
76
101
  │ │ └── User.ts # User entity with decorators
77
102
  │ ├── repository/ # Data access layer
78
103
  │ │ └── UserRepository.ts # User database operations
79
- │ ├── router/ # Route definitions
104
+ │ ├── router/ # Route definitions (traditional routing)
80
105
  │ │ ├── index.ts # Main router setup
81
106
  │ │ └── routes/
82
107
  │ │ ├── authRoutes.ts # Auth endpoints
83
108
  │ │ └── userRoutes.ts # User endpoints
84
- │ ├── middleware/ # Custom middleware
85
- │ │ └── YourMiddleware.ts # Example middleware
86
109
  │ ├── services/ # Business logic services
87
110
  │ │ └── YourService.ts # Example service
111
+ │ ├── middleware/ # Custom middleware
112
+ │ │ └── YourMiddleware.ts # Example middleware
113
+ │ ├── jobs/ # 🆕 Scheduled jobs
114
+ │ │ └── ExampleJob.ts # Example cron job
115
+ │ ├── templates/ # 🆕 SSR templates (JSX/TSX)
116
+ │ │ ├── ExampleRender.tsx # Example template
117
+ │ │ ├── layout/ # Layout templates
118
+ │ │ └── README.md # Template documentation
88
119
  │ ├── fixtures/ # Seed data
89
120
  │ │ └── AppFixtures.ts # Sample user data
90
121
  │ ├── tests/ # Test files
91
122
  │ │ └── exemple.test.ts # Example test
92
123
  │ ├── types/ # TypeScript types
93
124
  │ │ └── ExempleType.ts # Example types
94
- │ └── server.ts # Application entry point
125
+ │ └── server.ts # Application entry point (updated for v2)
126
+ ├── public/ # 🆕 Static assets
127
+ │ └── assets/ # Images, CSS, fonts, etc.
95
128
  ├── config/ # YAML configuration files
96
129
  │ ├── database.yaml
97
130
  │ ├── router.yaml
@@ -99,6 +132,8 @@ my-project/
99
132
  │ ├── parameters.yaml
100
133
  │ └── mailer.yaml
101
134
  ├── migrations/ # SQL migration files
135
+ ├── backups/ # 🆕 Database backups
136
+ ├── logs/ # 🆕 Application logs
102
137
  ├── .env # Environment variables
103
138
  ├── .prettierrc # Code formatting rules
104
139
  ├── eslint.config.js # Linting configuration
@@ -107,6 +142,8 @@ my-project/
107
142
  └── README.md # Project documentation
108
143
  ```
109
144
 
145
+ > **Note:** LyraJS v2 supports both traditional routing (`src/router/`) and decorator-based routing. Choose the approach that works best for your project.
146
+
110
147
  ## Usage
111
148
 
112
149
  ### Create a New Project
@@ -183,6 +220,8 @@ The template includes these working endpoints:
183
220
  - `PATCH /api/user/:id` - Update user
184
221
  - `DELETE /api/user/:id` - Delete user
185
222
 
223
+ > **Note:** In v2, you can define these routes either with traditional route files or using decorators directly in controllers (`@Get`, `@Post`, etc.).
224
+
186
225
  ## Contributing
187
226
 
188
227
  We welcome contributions to improve the template! Here's how you can help:
@@ -335,8 +374,7 @@ LyraJS is licensed under the [GPL-3.0 License](./LICENSE).
335
374
 
336
375
  ## Authors
337
376
 
338
- - **Matthieu Fergola** - Core Developer
339
- - **Anthony Dewitte** - Core Developer
377
+ - Matthieu Fergola
340
378
 
341
379
  ## Acknowledgments
342
380
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-lyrajs",
3
- "version": "1.1.3",
3
+ "version": "2.0.1",
4
4
  "description": "CLI tool to create new LyraJS projects",
5
5
  "keywords": [
6
6
  "create",
@@ -12,7 +12,7 @@
12
12
  "cli",
13
13
  "scaffold"
14
14
  ],
15
- "author": "Matthieu Fergola & Anthony Dewitte",
15
+ "author": "Matthieu Fergola",
16
16
  "license": "GPL-3.0",
17
17
  "repository": {
18
18
  "type": "git",
@@ -0,0 +1,93 @@
1
+ # Database Backups
2
+
3
+ This directory stores automatic database backups created by the LyraJS migration system.
4
+
5
+ ## Purpose
6
+
7
+ The `backups/` folder contains SQL dump files that serve as safety checkpoints for your database. These backups are automatically created before destructive migration operations to ensure data can be recovered if needed.
8
+
9
+ ## When Backups Are Created
10
+
11
+ Backups are automatically generated in the following scenarios:
12
+
13
+ - **Before destructive migrations**: When running migrations marked as `isDestructive = true`
14
+ - **Before rollback operations**: When using `maestro migration:rollback`
15
+ - **Before refresh operations**: When using `maestro migration:refresh`
16
+ - **Before fresh migrations**: When using `maestro migration:fresh`
17
+
18
+ ## Backup File Format
19
+
20
+ Backup files follow this naming convention:
21
+
22
+ ```
23
+ backup_YYYY-MM-DD_HH-MM-SS_<version>.sql
24
+ ```
25
+
26
+ Example: `backup_2026-01-05_14-30-45_1767607917120.sql`
27
+
28
+ Where:
29
+ - **Date/Time**: Timestamp of when the backup was created
30
+ - **Version**: Migration version number associated with the backup
31
+
32
+ ## Managing Backups
33
+
34
+ ### List All Backups
35
+
36
+ ```bash
37
+ npx maestro list:backups
38
+ ```
39
+
40
+ ### Restore a Backup
41
+
42
+ ```bash
43
+ npx maestro restore:backup <filename>
44
+ ```
45
+
46
+ Example:
47
+ ```bash
48
+ npx maestro restore:backup backup_2026-01-05_14-30-45_1767607917120.sql
49
+ ```
50
+
51
+ ### Clean Up Old Backups
52
+
53
+ ```bash
54
+ npx maestro cleanup:backups --days=30
55
+ ```
56
+
57
+ This removes backups older than 30 days (default: 7 days).
58
+
59
+ ## Best Practices
60
+
61
+ 1. **Keep backups**: Don't delete backups immediately after migrations succeed
62
+ 2. **Regular cleanup**: Use `cleanup:backups` to manage disk space
63
+ 3. **External backups**: Consider copying important backups to external storage
64
+ 4. **Test restores**: Periodically test backup restoration in development
65
+
66
+ ## Storage Considerations
67
+
68
+ - Backup files can be large depending on database size
69
+ - Regular cleanup is recommended to prevent disk space issues
70
+ - The migration system tracks backup paths in the `migrations` table
71
+
72
+ ## Security
73
+
74
+ - Backup files contain your complete database schema and data
75
+ - Keep this directory secure and excluded from version control
76
+ - The `.gitignore` should include `backups/*.sql`
77
+
78
+ ## Related Commands
79
+
80
+ ```bash
81
+ # View migration status with backup information
82
+ npx maestro migration:status
83
+
84
+ # Run migration with automatic backup
85
+ npx maestro migration:migrate
86
+
87
+ # Rollback with automatic backup
88
+ npx maestro migration:rollback
89
+ ```
90
+
91
+ ---
92
+
93
+ For more information, visit the [LyraJS Documentation](https://lyrajs.dev/).
@@ -14,7 +14,6 @@ security:
14
14
  max_attempts: 5
15
15
  message: 'Too many login attempts, please try again later'
16
16
  access_control:
17
- - { path: /api/auth/sign-out, roles: [ROLE_USER] }
18
17
  - { path: /api/auth/user, roles: [ROLE_USER] }
19
18
  - { path: /api/admin, roles: [ROLE_ADMIN] }
20
19
  role_hierarchy:
@@ -0,0 +1,247 @@
1
+ # Database Migrations
2
+
3
+ This directory contains database migration files that track and version your database schema changes.
4
+
5
+ ## Purpose
6
+
7
+ The `migrations/` folder stores TypeScript migration files that define how your database schema evolves over time. Each migration represents a specific change to your database structure.
8
+
9
+ ## What Are Migrations?
10
+
11
+ Migrations are version control for your database. They allow you to:
12
+
13
+ - **Track schema changes**: Every database modification is recorded
14
+ - **Collaborate safely**: Team members can sync database changes through version control
15
+ - **Rollback changes**: Undo migrations if something goes wrong
16
+ - **Deploy consistently**: Apply the same schema changes across environments
17
+
18
+ ## Migration File Structure
19
+
20
+ Migration files follow this naming convention:
21
+
22
+ ```
23
+ Migration_<timestamp>.ts
24
+ ```
25
+
26
+ Example: `Migration_1767607917120.ts`
27
+
28
+ Each migration file implements the `MigrationInterface` with three methods:
29
+
30
+ ```typescript
31
+ import { MigrationInterface } from "@lyra-js/core"
32
+
33
+ export class Migration_1767607917120 implements MigrationInterface {
34
+ readonly version = "1767607917120"
35
+ readonly isDestructive = false
36
+ readonly canRunInParallel = false
37
+
38
+ async up(connection: any): Promise<void> {
39
+ // SQL to apply the migration
40
+ }
41
+
42
+ async down(connection: any): Promise<void> {
43
+ // SQL to undo the migration
44
+ }
45
+
46
+ async dryRun(connection: any): Promise<string[]> {
47
+ // Return SQL statements for preview
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Generating Migrations
53
+
54
+ ### Automatic Generation (Recommended)
55
+
56
+ LyraJS automatically detects schema changes by comparing your entities to the database:
57
+
58
+ ```bash
59
+ npx maestro make:migration
60
+ ```
61
+
62
+ This command:
63
+ 1. Introspects your current database schema
64
+ 2. Compares it with your entity definitions
65
+ 3. Generates migration code for detected differences
66
+ 4. Includes smart rename detection to prevent data loss
67
+
68
+ ### Manual Migration
69
+
70
+ For complex operations, you can create migrations manually by copying the file structure above.
71
+
72
+ ## Running Migrations
73
+
74
+ ### Apply Pending Migrations
75
+
76
+ ```bash
77
+ npx maestro migration:migrate
78
+ ```
79
+
80
+ ### View Migration Status
81
+
82
+ ```bash
83
+ npx maestro migration:status
84
+ ```
85
+
86
+ ### Rollback Last Migration
87
+
88
+ ```bash
89
+ npx maestro migration:rollback
90
+ ```
91
+
92
+ ### Rollback Multiple Migrations
93
+
94
+ ```bash
95
+ npx maestro migration:rollback --steps=3
96
+ ```
97
+
98
+ ### Fresh Installation (⚠️ Destructive)
99
+
100
+ Drops all tables and re-runs all migrations:
101
+
102
+ ```bash
103
+ npx maestro migration:fresh
104
+ ```
105
+
106
+ ### Refresh Database (⚠️ Destructive)
107
+
108
+ Rolls back all migrations and re-runs them:
109
+
110
+ ```bash
111
+ npx maestro migration:refresh
112
+ ```
113
+
114
+ ## Migration Squashing
115
+
116
+ For mature projects with many migrations, you can combine them into a single baseline migration:
117
+
118
+ ```bash
119
+ # Squash all executed migrations
120
+ npx maestro migration:squash
121
+
122
+ # Squash up to a specific version
123
+ npx maestro migration:squash --to=1767607917120
124
+ ```
125
+
126
+ Squashed migrations:
127
+ - Reduce migration count for fresh installations
128
+ - Improve migration performance
129
+ - Keep the migrations folder organized
130
+ - Mark old migrations as archived
131
+
132
+ ## Migration Features
133
+
134
+ ### Smart Rename Detection
135
+
136
+ The migration generator can detect when columns or tables are renamed (instead of dropped and recreated):
137
+
138
+ ```
139
+ ? Detected potential rename: firstname -> first_name (85% confidence)
140
+ Do you want to rename instead of drop+create? (Y/n)
141
+ ```
142
+
143
+ ### Automatic Backups
144
+
145
+ Backups are automatically created before destructive operations:
146
+ - The backup is saved to `backups/backup_YYYY-MM-DD_HH-MM-SS_<version>.sql`
147
+ - Tracked in the migrations table for easy restoration
148
+
149
+ ### Migration Batching
150
+
151
+ Migrations are organized in batches, making it easy to rollback related changes together.
152
+
153
+ ### Parallel Execution
154
+
155
+ Some migrations can run in parallel for better performance (set `canRunInParallel = true`).
156
+
157
+ ## Best Practices
158
+
159
+ 1. **Never modify executed migrations**: Create new migrations for changes
160
+ 2. **Test migrations**: Always test in development before production
161
+ 3. **Write reversible migrations**: Ensure `down()` properly undoes `up()`
162
+ 4. **Use transactions**: Migrations run in transactions by default
163
+ 5. **Keep migrations small**: One logical change per migration
164
+ 6. **Review generated SQL**: Check auto-generated migrations before running
165
+ 7. **Version control**: Commit migration files to your repository
166
+
167
+ ## Common Operations
168
+
169
+ ### Adding a Column
170
+
171
+ ```bash
172
+ # 1. Add column to your entity
173
+ # 2. Generate migration
174
+ npx maestro make:migration
175
+
176
+ # 3. Review and run
177
+ npx maestro migration:migrate
178
+ ```
179
+
180
+ ### Creating a Table
181
+
182
+ ```bash
183
+ # 1. Create entity class
184
+ # 2. Generate migration
185
+ npx maestro make:migration
186
+
187
+ # 3. Run migration
188
+ npx maestro migration:migrate
189
+ ```
190
+
191
+ ### Renaming a Column
192
+
193
+ ```bash
194
+ # 1. Rename field in entity
195
+ # 2. Generate migration (will detect rename)
196
+ npx maestro make:migration
197
+
198
+ # 3. Confirm rename when prompted
199
+ # 4. Run migration
200
+ npx maestro migration:migrate
201
+ ```
202
+
203
+ ## Troubleshooting
204
+
205
+ ### Migration Failed
206
+
207
+ If a migration fails:
208
+ 1. Check the error message
209
+ 2. Fix the migration file or database state
210
+ 3. Rollback if needed: `npx maestro migration:rollback`
211
+ 4. Re-run: `npx maestro migration:migrate`
212
+
213
+ ### Out of Sync
214
+
215
+ If your database is out of sync with migrations:
216
+ 1. Use `npx maestro migration:status` to check state
217
+ 2. Manually fix the database or migrations table
218
+ 3. Or use `npx maestro migration:fresh` (⚠️ destroys data)
219
+
220
+ ### Restore from Backup
221
+
222
+ If something goes wrong:
223
+
224
+ ```bash
225
+ npx maestro list:backups
226
+ npx maestro restore:backup <filename>
227
+ ```
228
+
229
+ ## Related Commands
230
+
231
+ ```bash
232
+ # Show all controllers
233
+ npx maestro show:controllers
234
+
235
+ # Show all entities
236
+ npx maestro show:entities
237
+
238
+ # Show all migrations
239
+ npx maestro show:migrations
240
+
241
+ # Show database structure
242
+ npx maestro show:routes
243
+ ```
244
+
245
+ ---
246
+
247
+ For more information, visit the [LyraJS Documentation](https://lyrajs.dev/).
@@ -7,13 +7,11 @@
7
7
  "maestro": "maestro"
8
8
  },
9
9
  "dependencies": {
10
- "@lyra-js/core": "^1.1.3",
10
+ "@lyra-js/core": "^2.0.1",
11
11
  "bcrypt": "^6.0.0",
12
- "cookie-parser": "^1.4.7",
13
12
  "cors": "^2.8.5",
14
13
  "dotenv": "^16.5.0",
15
- "express": "^5.1.0",
16
- "express-rate-limit": "^8.2.1",
14
+ "esbuild": "^0.27.2",
17
15
  "jsonwebtoken": "^9.0.2",
18
16
  "mysql2": "^3.14.1",
19
17
  "nodemailer": "^7.0.7",
@@ -22,9 +20,7 @@
22
20
  },
23
21
  "devDependencies": {
24
22
  "@types/bcrypt": "^5.0.2",
25
- "@types/cookie-parser": "^1.4.8",
26
23
  "@types/cors": "^2.8.18",
27
- "@types/express": "^5.0.1",
28
24
  "@types/jsonwebtoken": "^9.0.9",
29
25
  "@types/node": "^22.15.17",
30
26
  "@types/nodemailer": "^6.4.17",
Binary file
@@ -0,0 +1,158 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ html, body {
6
+ margin: 0;
7
+ padding: 0;
8
+ }
9
+
10
+ html {
11
+ font-size: 62.5%;
12
+ }
13
+
14
+ body {
15
+ background-color: #1f202a;
16
+ color: #dedff6;
17
+ font-size: 1.8rem;
18
+ font-family: sans-serif;
19
+ text-align: center;
20
+ }
21
+
22
+ h1 {
23
+ font-size: 5rem;
24
+ }
25
+
26
+ a {
27
+ color: #ffad70;
28
+ text-decoration: none;
29
+ transition: color .2s;
30
+ }
31
+
32
+ a:hover {
33
+ color: #ff657d;
34
+ transition: color .2s;
35
+ }
36
+
37
+ header {
38
+ display: flex;
39
+ flex-direction: row;
40
+ align-items: center;
41
+ justify-content: center;
42
+ height: 7rem;
43
+ box-shadow: 0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;
44
+ }
45
+
46
+ header nav {
47
+ display: flex;
48
+ flex-direction: row;
49
+ justify-content: center;
50
+ }
51
+
52
+ header nav a {
53
+ margin: .5rem 1rem;
54
+ }
55
+
56
+ header nav a:not(:last-of-type)::after {
57
+ content: "|";
58
+ margin-left: 2rem;
59
+ color: #dedff6;
60
+ }
61
+
62
+ main {
63
+ height: calc(100vh - 14rem);
64
+ align-items: center;
65
+ display: flex;
66
+ flex-direction: row;
67
+ justify-content: center;
68
+ }
69
+
70
+ main > section {
71
+ width: 50%;
72
+ }
73
+
74
+ footer {
75
+ display: flex;
76
+ flex-flow: row wrap;
77
+ align-items: center;
78
+ justify-content: center;
79
+ height: 7rem;
80
+ }
81
+
82
+ footer > p {
83
+ margin: 0;
84
+ padding-top: 1.3rem;
85
+ border-top: 1px solid #dedff61a;
86
+ width: 60%;
87
+ }
88
+
89
+ footer span {
90
+ color: #ef4444;
91
+ margin: 0 .5rem;
92
+ }
93
+
94
+ footer a {
95
+ color: #dedff6;
96
+ }
97
+
98
+ footer a:hover {
99
+ color: #dedff6;
100
+ text-decoration: underline;
101
+ }
102
+
103
+ .logo {
104
+ width: fit-content;
105
+ margin: 0 auto;
106
+ }
107
+
108
+ .logo > img {
109
+ max-height: 180px;
110
+ }
111
+
112
+ .text-gradient {
113
+ background-color: #ffad70;
114
+ background-image: linear-gradient(45deg, #ffad70, #ff657d);
115
+ -webkit-background-clip: text;
116
+ -webkit-text-fill-color: transparent;
117
+ -moz-background-clip: text;
118
+ -moz-text-fill-color: transparent;
119
+ background-clip: text;
120
+ width: fit-content;
121
+ padding-bottom: .2em;
122
+ margin: 0 auto;
123
+ }
124
+
125
+ .doc-links {
126
+ margin-top: 6rem;
127
+ }
128
+
129
+ .btn, .btn-outline {
130
+ font-weight: 700;
131
+ font-size: 2rem;
132
+ border-radius: 3.4rem;
133
+ margin: 1rem;
134
+ padding: 2rem 2rem;
135
+ transition: all .2s;
136
+ }
137
+
138
+ .btn {
139
+ color: oklch(15.092% .036 346.812);
140
+ background-color: #ffad70;
141
+ }
142
+
143
+ .btn:hover {
144
+ color: oklch(15.092% .036 346.812);
145
+ background-color: #c68755;
146
+ transition: all .2s;
147
+ }
148
+
149
+ .btn-outline {
150
+ color: #ffad70;
151
+ border: 1px solid #ffad70;
152
+ }
153
+
154
+ .btn-outline:hover {
155
+ color: oklch(15.092% .036 346.812);
156
+ background-color: #ffad70;
157
+ transition: all .2s;
158
+ }