start-vibing-stacks 1.9.2 → 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.
package/dist/ui.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Start Vibing Stacks — Terminal UI
3
3
  */
4
4
  import chalk from 'chalk';
5
- const VERSION = '1.9.2';
5
+ const VERSION = '2.0.1';
6
6
  const gradient = (text) => {
7
7
  const colors = [chalk.hex('#FF6B6B'), chalk.hex('#FF8E53'), chalk.hex('#FFBD2E'), chalk.hex('#48BB78'), chalk.hex('#4299E1'), chalk.hex('#9F7AEA')];
8
8
  return text.split('').map((c, i) => colors[i % colors.length](c)).join('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-vibing-stacks",
3
- "version": "1.9.2",
3
+ "version": "2.0.1",
4
4
  "description": "AI-powered multi-stack dev workflow for Claude Code. Supports PHP, Node.js, Python and more.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,362 @@
1
+ # Preline UI — Component & Theme System for TailwindCSS 4
2
+
3
+ **ALWAYS invoke when using Preline components, creating themes, or customizing design tokens.**
4
+
5
+ ## What is Preline
6
+
7
+ Preline is a **semantic token-based design system** built on TailwindCSS. It provides:
8
+ - 220+ CSS tokens for full UI consistency
9
+ - Pre-built components (navbar, sidebar, card, dropdown, overlay, etc.)
10
+ - Theme generator for custom color schemes
11
+ - Light + dark mode via `data-theme` + `.dark`
12
+
13
+ ## Installation (Laravel + Inertia)
14
+
15
+ ### Step 1: Install
16
+
17
+ ```bash
18
+ npm install preline @tailwindcss/forms
19
+ ```
20
+
21
+ ### Step 2: CSS Config
22
+
23
+ ```css
24
+ /* resources/css/app.css */
25
+ @import "tailwindcss";
26
+
27
+ /* Preline — MUST be in this order */
28
+ @source "./node_modules/preline/dist/*.js"; /* JS component scanning */
29
+ @import "./node_modules/preline/variants.css"; /* CSS variants */
30
+ @plugin "@tailwindcss/forms"; /* Forms plugin */
31
+ @import "./node_modules/preline/themes/theme.css"; /* Base theme */
32
+ ```
33
+
34
+ ### Step 3: Vite Config
35
+
36
+ ```js
37
+ // vite.config.js
38
+ import { defineConfig } from 'vite';
39
+ import laravel from 'laravel-vite-plugin';
40
+ import react from '@vitejs/plugin-react';
41
+
42
+ export default defineConfig({
43
+ plugins: [
44
+ laravel({ input: ['resources/css/app.css', 'resources/js/app.tsx'], refresh: true }),
45
+ react(),
46
+ ],
47
+ });
48
+ ```
49
+
50
+ ### Step 4: Init Preline in Inertia (MANDATORY)
51
+
52
+ ```tsx
53
+ // resources/js/app.tsx
54
+ import { router } from '@inertiajs/react';
55
+
56
+ // Re-init Preline components after every SPA navigation
57
+ router.on('navigate', () => {
58
+ setTimeout(() => {
59
+ import('preline/preline').then(({ HSStaticMethods }) => {
60
+ HSStaticMethods.autoInit();
61
+ });
62
+ }, 100);
63
+ });
64
+ ```
65
+
66
+ **Rule:** Without `HSStaticMethods.autoInit()`, dropdowns, modals, and accordions will NOT work after Inertia navigation.
67
+
68
+ ## Templates & Components (840+ free)
69
+
70
+ ### Where to Find
71
+
72
+ | Source | URL | What |
73
+ |---|---|---|
74
+ | **Docs (components)** | https://preline.co/docs | Buttons, modals, forms, tables, navs |
75
+ | **Examples (blocks)** | https://preline.co/examples.html | 220+ UI blocks (hero, testimonials, pricing, etc.) |
76
+ | **Pro templates** | https://preline.co/pro/templates.html | 21 dashboard/app templates (paid) |
77
+ | **GitHub** | https://github.com/htmlstreamofficial/preline | Source + examples |
78
+
79
+ ### How to Use Templates
80
+
81
+ 1. Browse https://preline.co/examples.html
82
+ 2. Click a block → copy the HTML/JSX
83
+ 3. Adapt to React + Inertia:
84
+ - Replace `<a href>` with `<Link href>` (Inertia)
85
+ - Replace `class=` with `className=`
86
+ - Add Preline `data-*` attributes for interactive components
87
+ - Use `usePage().props` for dynamic data
88
+
89
+ ### Example: Copy a Hero Block
90
+
91
+ ```tsx
92
+ // From preline.co/examples.html → Hero sections
93
+ // Adapt HTML to React component:
94
+ export default function HeroSection() {
95
+ return (
96
+ <div className="relative overflow-hidden">
97
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24">
98
+ <div className="text-center">
99
+ <h1 className="text-4xl sm:text-6xl font-bold text-foreground">
100
+ Build your next idea
101
+ </h1>
102
+ <p className="mt-4 text-lg text-muted-foreground max-w-2xl mx-auto">
103
+ Preline UI is an open-source set of prebuilt UI components.
104
+ </p>
105
+ <div className="mt-8 flex justify-center gap-3">
106
+ <Link href="/register"
107
+ className="px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary-hover font-medium transition-colors">
108
+ Get Started
109
+ </Link>
110
+ <Link href="/docs"
111
+ className="px-6 py-3 bg-layer border border-layer-line text-layer-foreground rounded-lg hover:bg-layer-hover font-medium transition-colors">
112
+ Documentation
113
+ </Link>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ );
119
+ }
120
+ ```
121
+
122
+ ### Key Component Categories (free)
123
+
124
+ | Category | Count | Examples |
125
+ |---|---|---|
126
+ | **Navigation** | 20+ | Navbar, sidebar, breadcrumb, pagination |
127
+ | **Hero** | 11 | Landing page headers |
128
+ | **Cards** | 15+ | Product, blog, profile, pricing |
129
+ | **Forms** | 20+ | Login, register, contact, checkout |
130
+ | **Tables** | 10+ | Sortable, paginated, striped |
131
+ | **Modals** | 8+ | Confirmation, form, full-screen |
132
+ | **Dropdowns** | 10+ | Menu, select, multi-select |
133
+ | **Testimonials** | 10+ | Quotes, carousel, grid |
134
+ | **Pricing** | 8+ | Monthly/yearly toggle, comparison |
135
+ | **Dashboard** | 5+ | Stats, charts, activity feed |
136
+
137
+ ## Token Architecture
138
+
139
+ ```
140
+ Layer 1 — Tailwind primitives: var(--color-blue-600)
141
+ Layer 2 — Preline semantic: --primary: var(--color-blue-600)
142
+ Layer 3 — Component tokens: --navbar-nav-hover: var(--color-gray-100)
143
+ Layer 4 — Usage in HTML: className="bg-primary text-primary-foreground"
144
+ ```
145
+
146
+ ### Core Token Groups
147
+
148
+ | Group | Example Tokens | Purpose |
149
+ |---|---|---|
150
+ | **Background** | `--background`, `--background-1`, `--background-2` | App surfaces |
151
+ | **Foreground** | `--foreground`, `--foreground-inverse` | Text colors |
152
+ | **Primary** | `--primary`, `--primary-hover`, `--primary-foreground`, `--primary-50`→`950` | Brand/action color |
153
+ | **Secondary** | `--secondary`, `--secondary-hover`, `--secondary-foreground` | Secondary emphasis |
154
+ | **Muted** | `--muted`, `--muted-foreground`, `--muted-foreground-1`, `--muted-foreground-2` | Subdued elements |
155
+ | **Destructive** | `--destructive`, `--destructive-hover`, `--destructive-foreground` | Danger actions |
156
+ | **Border** | `--border`, `--border-line-1`→`8` | Border scale (light→dark) |
157
+ | **Surface** | `--surface`, `--surface-1`→`5`, `--surface-foreground` | Elevated layers |
158
+ | **Layer** | `--layer`, `--layer-hover`, `--layer-foreground` | Stacked elements |
159
+
160
+ ### Component Token Groups
161
+
162
+ | Component | Tokens | Notes |
163
+ |---|---|---|
164
+ | **Navbar** | `--navbar`, `--navbar-line`, `--navbar-nav-*` | 3 variants (base, `-1`, `-2`) |
165
+ | **Sidebar** | `--sidebar`, `--sidebar-line`, `--sidebar-nav-*` | 3 variants (base, `-1`, `-2`) |
166
+ | **Card** | `--card`, `--card-line`, `--card-divider`, `--card-header`, `--card-footer` | |
167
+ | **Dropdown** | `--dropdown`, `--dropdown-item-*` | hover, focus, active states |
168
+ | **Select** | `--select`, `--select-item-*` | Same state pattern |
169
+ | **Overlay** | `--overlay`, `--overlay-line`, `--overlay-header`, `--overlay-footer` | Modals |
170
+ | **Tooltip** | `--tooltip`, `--tooltip-foreground`, `--tooltip-line` | |
171
+ | **Popover** | `--popover`, `--popover-line` | |
172
+ | **Scrollbar** | `--scrollbar-track`, `--scrollbar-thumb` | + inverse variants |
173
+
174
+ ## Creating Custom Themes
175
+
176
+ ### Theme File Structure (MUST follow order)
177
+
178
+ ```css
179
+ /* 1. Import base theme */
180
+ @import "./theme.css";
181
+
182
+ /* 2. Theme scoping block — custom palettes ONLY */
183
+ @theme theme-brand inline {
184
+ --color-brand-50: oklch(98% 0.003 250);
185
+ --color-brand-100: oklch(95% 0.01 250);
186
+ --color-brand-200: oklch(88% 0.03 250);
187
+ --color-brand-300: oklch(78% 0.06 250);
188
+ --color-brand-400: oklch(68% 0.10 250);
189
+ --color-brand-500: oklch(58% 0.14 250);
190
+ --color-brand-600: oklch(50% 0.15 250);
191
+ --color-brand-700: oklch(42% 0.13 250);
192
+ --color-brand-800: oklch(35% 0.10 250);
193
+ --color-brand-900: oklch(28% 0.08 250);
194
+ --color-brand-950: oklch(20% 0.05 250);
195
+ }
196
+
197
+ /* 3. Light mode — semantic token overrides */
198
+ :root[data-theme="theme-brand"],
199
+ [data-theme="theme-brand"] {
200
+ --background: var(--color-white);
201
+ --foreground: var(--color-gray-800);
202
+
203
+ --primary: var(--color-brand-600);
204
+ --primary-foreground: var(--color-white);
205
+ --primary-hover: var(--color-brand-700);
206
+ --primary-focus: var(--color-brand-700);
207
+ --primary-active: var(--color-brand-700);
208
+
209
+ /* ... all 220+ tokens as needed */
210
+ }
211
+
212
+ /* 4. Dark mode */
213
+ [data-theme="theme-brand"].dark {
214
+ --background: var(--color-neutral-800);
215
+ --foreground: var(--color-neutral-200);
216
+
217
+ --primary: var(--color-brand-500);
218
+ --primary-foreground: var(--color-white);
219
+ --primary-hover: var(--color-brand-600);
220
+
221
+ /* ... dark overrides */
222
+ }
223
+ ```
224
+
225
+ ### Activation
226
+
227
+ ```html
228
+ <html data-theme="theme-brand">
229
+ <!-- Or with dark mode: -->
230
+ <html data-theme="theme-brand" class="dark">
231
+ ```
232
+
233
+ ```tsx
234
+ // React theme switcher
235
+ function ThemeToggle() {
236
+ const [dark, setDark] = useState(false);
237
+ return (
238
+ <button onClick={() => {
239
+ document.documentElement.classList.toggle('dark');
240
+ setDark(!dark);
241
+ }}>
242
+ {dark ? '☀️' : '🌙'}
243
+ </button>
244
+ );
245
+ }
246
+ ```
247
+
248
+ ## Using Components with React (Inertia)
249
+
250
+ ### Navbar
251
+
252
+ ```tsx
253
+ <nav className="bg-navbar border-b border-navbar-line">
254
+ <div className="max-w-7xl mx-auto px-4 flex items-center justify-between h-16">
255
+ <Link href="/" className="text-foreground font-bold text-lg">Brand</Link>
256
+ <div className="flex items-center gap-1">
257
+ <Link href="/dashboard"
258
+ className="px-3 py-2 rounded-lg text-navbar-nav-foreground hover:bg-navbar-nav-hover transition-colors">
259
+ Dashboard
260
+ </Link>
261
+ <Link href="/leads"
262
+ className="px-3 py-2 rounded-lg text-navbar-nav-foreground hover:bg-navbar-nav-hover transition-colors">
263
+ Leads
264
+ </Link>
265
+ </div>
266
+ </div>
267
+ </nav>
268
+ ```
269
+
270
+ ### Card
271
+
272
+ ```tsx
273
+ <div className="bg-card border border-card-line rounded-xl overflow-hidden">
274
+ <div className="bg-card-header px-6 py-4 border-b border-card-divider">
275
+ <h3 className="text-foreground font-semibold">Title</h3>
276
+ </div>
277
+ <div className="px-6 py-4">
278
+ <p className="text-muted-foreground">Content</p>
279
+ </div>
280
+ <div className="bg-card-footer px-6 py-3 border-t border-card-divider">
281
+ <button className="bg-primary text-primary-foreground px-4 py-2 rounded-lg hover:bg-primary-hover transition-colors">
282
+ Action
283
+ </button>
284
+ </div>
285
+ </div>
286
+ ```
287
+
288
+ ### Sidebar
289
+
290
+ ```tsx
291
+ <aside className="w-64 bg-sidebar border-r border-sidebar-line h-screen">
292
+ <nav className="p-4 space-y-1">
293
+ {navItems.map(item => (
294
+ <Link key={item.href} href={item.href}
295
+ className={`flex items-center gap-3 px-3 py-2 rounded-lg transition-colors
296
+ ${isActive(item.href)
297
+ ? 'bg-sidebar-nav-active text-primary font-medium'
298
+ : 'text-sidebar-nav-foreground hover:bg-sidebar-nav-hover'}`}>
299
+ {item.icon}
300
+ {item.label}
301
+ </Link>
302
+ ))}
303
+ </nav>
304
+ </aside>
305
+ ```
306
+
307
+ ### Dropdown (with Preline JS)
308
+
309
+ ```tsx
310
+ <div className="hs-dropdown relative">
311
+ <button className="hs-dropdown-toggle px-4 py-2 bg-layer border border-layer-line rounded-lg text-layer-foreground hover:bg-layer-hover">
312
+ Options ▾
313
+ </button>
314
+ <div className="hs-dropdown-menu hidden bg-dropdown border border-dropdown-line rounded-lg shadow-lg mt-1 p-1 min-w-48">
315
+ <button className="w-full text-left px-3 py-2 rounded-md text-dropdown-item-foreground hover:bg-dropdown-item-hover">
316
+ Edit
317
+ </button>
318
+ <div className="border-t border-dropdown-divider my-1" />
319
+ <button className="w-full text-left px-3 py-2 rounded-md text-destructive hover:bg-dropdown-item-hover">
320
+ Delete
321
+ </button>
322
+ </div>
323
+ </div>
324
+ ```
325
+
326
+ ## Theme Generator (CLI)
327
+
328
+ ```bash
329
+ # Generate theme from config
330
+ npx preline-theme-generator /tmp/config.json ./resources/css/themes/brand.css
331
+
332
+ # Config format:
333
+ {
334
+ "name": "brand",
335
+ "hue": 250,
336
+ "style": "professional",
337
+ "useCustomDarkGray": true,
338
+ "tailwindGray": "neutral"
339
+ }
340
+ ```
341
+
342
+ ## Chart Tokens (Apexcharts)
343
+
344
+ ```css
345
+ /* Charts require HEX for gradients — no oklch! */
346
+ --chart-colors-primary-hex: #2563eb;
347
+ --chart-colors-chart-1-hex: #8b5cf6;
348
+ --chart-colors-chart-2-hex: #06b6d4;
349
+ ```
350
+
351
+ ## FORBIDDEN
352
+
353
+ | ❌ Don't | ✅ Do |
354
+ |---|---|
355
+ | Modify `theme.css` (base) | Create separate theme file |
356
+ | Put tokens inside `@theme` block | Tokens in selector blocks only |
357
+ | Use raw colors (`bg-blue-500`) | Use semantic tokens (`bg-primary`) |
358
+ | `oklch()` in chart `-hex` tokens | Use hex format for charts |
359
+ | Force HTML class changes | Theme activation via `data-theme` only |
360
+ | Invent token names | Follow Preline's naming system |
361
+ | `@apply` for component styles | React components with token classes |
362
+ | Skip `HSStaticMethods.autoInit()` | Always re-init after Inertia navigation |