create-tigra 2.6.0 → 2.6.5
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/_claude/commands/create-client.md +1 -1
- package/template/_claude/rules/client/01-project-structure.md +7 -5
- package/template/_claude/rules/client/04-design-system.md +95 -1
- package/template/_claude/rules/client/core.md +7 -6
- package/template/client/README.md +1 -1
- package/template/client/src/app/globals.css +15 -2
- package/template/client/src/app/layout.tsx +6 -6
- package/template/client/src/styles/fonts/inter-jetbrains.css +16 -0
package/package.json
CHANGED
|
@@ -463,7 +463,7 @@ export function Providers({ children }: { children: React.ReactNode }): React.Re
|
|
|
463
463
|
|
|
464
464
|
#### `src/app/layout.tsx`
|
|
465
465
|
Root layout:
|
|
466
|
-
- Import and use `next/font` (Inter
|
|
466
|
+
- Import and use `next/font/google` (fonts defined by the active font preset — default: Inter + JetBrains Mono)
|
|
467
467
|
- `<html lang="en" suppressHydrationWarning>`
|
|
468
468
|
- Wrap children in `<Providers>`
|
|
469
469
|
- Default metadata with app name
|
|
@@ -33,11 +33,13 @@ src/
|
|
|
33
33
|
│ ├── types/ # <domain>.types.ts
|
|
34
34
|
│ └── actions/ # <domain>.actions.ts (Server Actions)
|
|
35
35
|
├── styles/
|
|
36
|
-
│
|
|
37
|
-
│
|
|
38
|
-
│
|
|
39
|
-
│
|
|
40
|
-
│
|
|
36
|
+
│ ├── themes/ # Color theme presets (switch in globals.css import)
|
|
37
|
+
│ │ ├── warm-orange.css # Default — earthy, warm
|
|
38
|
+
│ │ ├── electric-indigo.css
|
|
39
|
+
│ │ ├── ocean-teal.css
|
|
40
|
+
│ │ └── rose-pink.css
|
|
41
|
+
│ └── fonts/ # Font presets (switch in globals.css import)
|
|
42
|
+
│ └── inter-jetbrains.css # Default — Inter + JetBrains Mono
|
|
41
43
|
├── hooks/ # Global hooks (useDebounce, useLocalStorage, useMediaQuery)
|
|
42
44
|
├── lib/
|
|
43
45
|
│ ├── api/ # axios.config.ts, api.types.ts
|
|
@@ -94,6 +94,100 @@ Each preset file defines ALL semantic color variables for both `:root` (light) a
|
|
|
94
94
|
|
|
95
95
|
---
|
|
96
96
|
|
|
97
|
+
## Font Preset System (Font Management)
|
|
98
|
+
|
|
99
|
+
**Font families are defined in font preset files, NOT hardcoded in components.** This mirrors the color theme preset system — switch the entire font pairing by changing one import.
|
|
100
|
+
|
|
101
|
+
### How It Works
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
src/
|
|
105
|
+
├── app/
|
|
106
|
+
│ ├── layout.tsx ← loads fonts via next/font/google
|
|
107
|
+
│ └── globals.css ← imports ONE font preset (switch here)
|
|
108
|
+
└── styles/fonts/
|
|
109
|
+
└── inter-jetbrains.css ← Default (Inter + JetBrains Mono)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Three Semantic Font Roles
|
|
113
|
+
|
|
114
|
+
| Role | CSS Variable | Tailwind Class | Default Font |
|
|
115
|
+
|------|-------------|----------------|--------------|
|
|
116
|
+
| Body text | `--font-sans-value` | `font-sans` | Inter |
|
|
117
|
+
| Headings | `--font-heading-value` | `font-heading` | Inter |
|
|
118
|
+
| Code/mono | `--font-mono-value` | `font-mono` | JetBrains Mono |
|
|
119
|
+
|
|
120
|
+
### How to Switch Fonts
|
|
121
|
+
|
|
122
|
+
Switching fonts requires two changes:
|
|
123
|
+
|
|
124
|
+
**Step 1 — Update font imports in `layout.tsx`:**
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
// Change these imports to your desired fonts
|
|
128
|
+
import { Roboto, Fira_Code } from 'next/font/google';
|
|
129
|
+
|
|
130
|
+
const roboto = Roboto({
|
|
131
|
+
variable: '--font-roboto',
|
|
132
|
+
subsets: ['latin'],
|
|
133
|
+
weight: ['400', '500', '600', '700'],
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const firaCode = Fira_Code({
|
|
137
|
+
variable: '--font-fira-code',
|
|
138
|
+
subsets: ['latin'],
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Update the className to use new variables
|
|
142
|
+
<body className={`${roboto.variable} ${firaCode.variable} font-sans antialiased`}>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Step 2 — Update the font preset file (or create a new one):**
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
/* styles/fonts/roboto-fira.css */
|
|
149
|
+
:root {
|
|
150
|
+
--font-sans-value: var(--font-roboto);
|
|
151
|
+
--font-heading-value: var(--font-roboto);
|
|
152
|
+
--font-mono-value: var(--font-fira-code);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Then update the import in `globals.css`:
|
|
157
|
+
```css
|
|
158
|
+
@import "../styles/fonts/roboto-fira.css";
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Font Preset Structure
|
|
162
|
+
|
|
163
|
+
Each preset maps raw font variables (set by `next/font/google` in `layout.tsx`) to semantic roles:
|
|
164
|
+
|
|
165
|
+
```css
|
|
166
|
+
:root {
|
|
167
|
+
--font-sans-value: var(--font-inter); /* body text */
|
|
168
|
+
--font-heading-value: var(--font-inter); /* headings */
|
|
169
|
+
--font-mono-value: var(--font-jetbrains-mono); /* code */
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Creating a Custom Font Preset
|
|
174
|
+
|
|
175
|
+
1. Choose your fonts from [Google Fonts](https://fonts.google.com)
|
|
176
|
+
2. Update `layout.tsx` — import fonts via `next/font/google`, set CSS variable names
|
|
177
|
+
3. Create a new preset file in `src/styles/fonts/` (or edit the existing one)
|
|
178
|
+
4. Map your font variables to the three semantic roles
|
|
179
|
+
5. Update the import in `globals.css` to point to your preset
|
|
180
|
+
|
|
181
|
+
### CRITICAL RULES — Font Management
|
|
182
|
+
|
|
183
|
+
1. **NEVER hardcode font-family values in components.** Always use Tailwind classes (`font-sans`, `font-heading`, `font-mono`).
|
|
184
|
+
2. **ALL font-family mappings live in the font preset file**, not in `globals.css` or components.
|
|
185
|
+
3. **To change fonts**: update `layout.tsx` imports + update the font preset file. Never scatter font-family values across the codebase.
|
|
186
|
+
4. **The `@theme inline` block in `globals.css` maps preset variables to Tailwind** — it does NOT define fonts. Fonts come from the preset.
|
|
187
|
+
5. **Fonts are loaded via `next/font/google`** — this self-hosts fonts automatically at build time. No external requests at runtime, no manual file downloads needed.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
97
191
|
## Mobile-First Responsive Strategy
|
|
98
192
|
|
|
99
193
|
**All Tailwind utilities are written for mobile first.** `md:` and `lg:` are progressive enhancements, not the other way around.
|
|
@@ -161,7 +255,7 @@ Each preset file defines ALL semantic color variables for both `:root` (light) a
|
|
|
161
255
|
|
|
162
256
|
## Typography
|
|
163
257
|
|
|
164
|
-
- **Font**: Inter
|
|
258
|
+
- **Font**: Defined by the active font preset (default: Inter for sans/heading, JetBrains Mono for mono). See "Font Preset System" above for how to switch.
|
|
165
259
|
- **Headings**: `text-wrap: balance`, `leading-tight`. Mobile-first responsive sizes:
|
|
166
260
|
- H1: `text-2xl md:text-3xl lg:text-4xl`
|
|
167
261
|
- H2: `text-xl md:text-2xl`
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| Creating files, folders, feature modules | `01-project-structure.md` |
|
|
10
10
|
| Building components, writing types/interfaces | `02-components-and-types.md` |
|
|
11
11
|
| Fetching data, managing state, calling APIs, forms | `03-data-and-state.md` |
|
|
12
|
-
| Choosing colors, styling, typography, spacing, motion, **theme presets** | `04-design-system.md` |
|
|
12
|
+
| Choosing colors, styling, typography, spacing, motion, **theme presets**, **font presets** | `04-design-system.md` |
|
|
13
13
|
| Auth tokens, env vars, security headers | `05-security.md` |
|
|
14
14
|
| UX psychology, cognitive load, a11y, performance | `06-ux-checklist.md` |
|
|
15
15
|
|
|
@@ -37,8 +37,9 @@ State: Server data (SSR) → Server Components
|
|
|
37
37
|
2. **Server Components by default.** Only add `'use client'` when you need hooks, state, or event handlers.
|
|
38
38
|
3. **Component limits**: Max 250 lines, max 5 props, max 3 JSX nesting levels.
|
|
39
39
|
4. **No hardcoded colors**: Use Tailwind semantic tokens (`bg-primary`, `text-foreground`). Never hex/rgb. **All color variables live in theme preset files (`src/styles/themes/*.css`), NOT in `globals.css` or components.** To change the palette, switch the import in `globals.css` or edit the active preset. Read `04-design-system.md` → "Theme Preset System" for details.
|
|
40
|
-
5. **No
|
|
41
|
-
6. **
|
|
42
|
-
7. **
|
|
43
|
-
8. **
|
|
44
|
-
9. **
|
|
40
|
+
5. **No hardcoded fonts**: Use Tailwind font classes (`font-sans`, `font-heading`, `font-mono`). Never hardcode `font-family` in components. **Font families are defined in font preset files (`src/styles/fonts/*.css`).** To change fonts, update the `next/font/google` imports in `layout.tsx` and the font preset file. Read `04-design-system.md` → "Font Preset System" for details.
|
|
41
|
+
6. **No inline styles**: Tailwind only. Use `cn()` for conditional classes.
|
|
42
|
+
7. **Import order**: React/Next → third-party → UI → local → hooks → services → types → utils.
|
|
43
|
+
8. **Forms**: Validate with Zod. Always validate client-side AND server-side.
|
|
44
|
+
9. **Security**: Never inject raw HTML without sanitization. Never prefix secrets with `NEXT_PUBLIC_`.
|
|
45
|
+
10. **Deployment**: Never remove `output: "standalone"` from `next.config.ts`. When adding `NEXT_PUBLIC_*` env vars, also add them as `ARG` + `ENV` in the Dockerfile builder stage. Read `07-deployment.md` for details.
|
|
@@ -18,7 +18,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
|
|
|
18
18
|
|
|
19
19
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
|
20
20
|
|
|
21
|
-
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [
|
|
21
|
+
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Inter](https://fonts.google.com/specimen/Inter) and [JetBrains Mono](https://fonts.google.com/specimen/JetBrains+Mono). Fonts are managed via the font preset system in `src/styles/fonts/` — see the design system rules for how to switch fonts.
|
|
22
22
|
|
|
23
23
|
## Learn More
|
|
24
24
|
|
|
@@ -20,13 +20,26 @@
|
|
|
20
20
|
@import "../styles/themes/ocean-teal.css";
|
|
21
21
|
@import "../styles/themes/rose-pink.css";
|
|
22
22
|
|
|
23
|
+
/*
|
|
24
|
+
* ============================================================
|
|
25
|
+
* FONT PRESET — Switch the entire font pairing here
|
|
26
|
+
* ============================================================
|
|
27
|
+
* To change fonts:
|
|
28
|
+
* 1. Update the font imports in layout.tsx (next/font/google)
|
|
29
|
+
* 2. Create or edit a preset in src/styles/fonts/
|
|
30
|
+
* 3. Change the import below to your preset
|
|
31
|
+
* ============================================================
|
|
32
|
+
*/
|
|
33
|
+
@import "../styles/fonts/inter-jetbrains.css";
|
|
34
|
+
|
|
23
35
|
@custom-variant dark (&:is(.dark *));
|
|
24
36
|
|
|
25
37
|
@theme inline {
|
|
26
38
|
--color-background: var(--background);
|
|
27
39
|
--color-foreground: var(--foreground);
|
|
28
|
-
--font-sans: var(--font-
|
|
29
|
-
--font-
|
|
40
|
+
--font-sans: var(--font-sans-value);
|
|
41
|
+
--font-heading: var(--font-heading-value);
|
|
42
|
+
--font-mono: var(--font-mono-value);
|
|
30
43
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
31
44
|
--color-sidebar-border: var(--sidebar-border);
|
|
32
45
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { Metadata } from 'next';
|
|
2
2
|
import type React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { Inter, JetBrains_Mono } from 'next/font/google';
|
|
4
4
|
|
|
5
5
|
import { Providers } from './providers';
|
|
6
6
|
import { APP_NAME } from '@/lib/constants/app.constants';
|
|
7
7
|
import './globals.css';
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
variable: '--font-
|
|
9
|
+
const inter = Inter({
|
|
10
|
+
variable: '--font-inter',
|
|
11
11
|
subsets: ['latin'],
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
variable: '--font-
|
|
14
|
+
const jetbrainsMono = JetBrains_Mono({
|
|
15
|
+
variable: '--font-jetbrains-mono',
|
|
16
16
|
subsets: ['latin'],
|
|
17
17
|
});
|
|
18
18
|
|
|
@@ -28,7 +28,7 @@ export default function RootLayout({
|
|
|
28
28
|
}>): React.ReactElement {
|
|
29
29
|
return (
|
|
30
30
|
<html lang="en" className="dark" suppressHydrationWarning>
|
|
31
|
-
<body className={`${
|
|
31
|
+
<body className={`${inter.variable} ${jetbrainsMono.variable} font-sans antialiased`}>
|
|
32
32
|
<Providers>{children}</Providers>
|
|
33
33
|
</body>
|
|
34
34
|
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Font Preset: Inter + JetBrains Mono
|
|
3
|
+
* Sans/Heading: Inter — clean, modern, designed for screens
|
|
4
|
+
* Mono: JetBrains Mono — developer-friendly with ligatures
|
|
5
|
+
*
|
|
6
|
+
* To switch fonts:
|
|
7
|
+
* 1. Update the font imports in layout.tsx (next/font/google)
|
|
8
|
+
* 2. Create a new preset file (or edit this one) with matching font-family names
|
|
9
|
+
* 3. Update the import in globals.css to point to your preset
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
:root {
|
|
13
|
+
--font-sans-value: var(--font-inter);
|
|
14
|
+
--font-heading-value: var(--font-inter);
|
|
15
|
+
--font-mono-value: var(--font-jetbrains-mono);
|
|
16
|
+
}
|