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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tigra",
3
- "version": "2.6.0",
3
+ "version": "2.6.5",
4
4
  "type": "module",
5
5
  "description": "Create a production-ready full-stack app with Next.js 16 + Fastify 5 + Prisma + Redis",
6
6
  "bin": {
@@ -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 or Geist Sans)
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
- └── 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
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 v4 (variable) or Geist Sans via `next/font`.
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 inline styles**: Tailwind only. Use `cn()` for conditional classes.
41
- 6. **Import order**: React/Next third-party UI local → hooks → services → types → utils.
42
- 7. **Forms**: Validate with Zod. Always validate client-side AND server-side.
43
- 8. **Security**: Never inject raw HTML without sanitization. Never prefix secrets with `NEXT_PUBLIC_`.
44
- 9. **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.
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 [Geist](https://vercel.com/font), a new font family for Vercel.
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-geist-sans);
29
- --font-mono: var(--font-geist-mono);
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 { Geist, Geist_Mono } from 'next/font/google';
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 geistSans = Geist({
10
- variable: '--font-geist-sans',
9
+ const inter = Inter({
10
+ variable: '--font-inter',
11
11
  subsets: ['latin'],
12
12
  });
13
13
 
14
- const geistMono = Geist_Mono({
15
- variable: '--font-geist-mono',
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={`${geistSans.variable} ${geistMono.variable} font-sans antialiased`}>
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
+ }