also looking at this
Deploy: uniform auth session model (main → production)
#7
282 files
+3028
-64856
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -16,7 +16,7 @@ For taste-level guidance on *which* utilities to reach for (layout variance, spa | ||
| 16 | 16 | |
| 17 | 17 | ## Key Paths |
| 18 | 18 | - Package: `node_modules/@cwcss/crosswind/` |
| 19 | - UI config: `config/stx.ts` (Crosswind options referencing Crosswind) | |
| 19 | - UI config: `config/ui.ts` (Crosswind options referencing Crosswind) | |
| 20 | 20 | - Default styles: `storage/framework/defaults/styles/` |
| 21 | 21 | - Output: `storage/framework/assets/crosswind.css` |
| 22 | 22 | |
| @@ -181,7 +181,7 @@ interface ParsedClass { | ||
| 181 | 181 | |
| 182 | 182 | ## Gotchas |
| 183 | 183 | - **Not Tailwind** — Crosswind is a separate implementation with Tailwind-compatible syntax |
| 184 | - **Stacks uses Crosswind config** — `config/stx.ts` defines Crosswind options which feed Crosswind | |
| 184 | - **Stacks uses Crosswind config** — `config/ui.ts` defines Crosswind options which feed Crosswind | |
| 185 | 185 | - **Output goes to `storage/framework/assets/crosswind.css`** — not a typical `dist/` directory |
| 186 | 186 | - **Bun plugin available** — can be used as a Bun build plugin for automatic CSS generation |
| 187 | 187 | - **Attributify mode** — optional mode where utilities can be written as HTML attributes instead of classes |
| @@ -17,7 +17,7 @@ The Stacks admin dashboard provides a full-featured admin panel with 136+ routes | ||
| 17 | 17 | - Dashboard layouts: `storage/framework/defaults/layouts/dashboard/` |
| 18 | 18 | - Dashboard router types: `storage/framework/types/dashboard-router.d.ts` (136+ routes) |
| 19 | 19 | - Dashboard actions: `storage/framework/defaults/actions/Dashboard/` |
| 20 | - Configuration: `config/stx.ts` | |
| 20 | - Configuration: `config/ui.ts` | |
| 21 | 21 | |
| 22 | 22 | ## Dashboard Sections |
| 23 | 23 | |
| @@ -53,7 +53,7 @@ Typography is the primary structural and decorative infrastructure. Imagery is s | ||
| 53 | 53 | ## 4. Color System |
| 54 | 54 | The color architecture is uncompromising. Gradients, soft drop shadows, and modern translucency are strictly prohibited. Colors simulate physical media or primitive emissive displays. |
| 55 | 55 | |
| 56 | **CRITICAL: Choose ONE substrate palette per project and use it consistently. Never mix light and dark substrates within the same interface.** Expose these as Crosswind theme tokens in `config/stx.ts`. | |
| 56 | **CRITICAL: Choose ONE substrate palette per project and use it consistently. Never mix light and dark substrates within the same interface.** Expose these as Crosswind theme tokens in `config/ui.ts`. | |
| 57 | 57 | |
| 58 | 58 | ### If Swiss Industrial Print (Light): |
| 59 | 59 | - **Background:** `#F4F4F0` or `#EAE8E3` (matte, unbleached documentation paper). |
| @@ -43,7 +43,7 @@ Color is a scarce resource, used only for semantic meaning or subtle accents. | ||
| 43 | 43 | - Pale Green: `#EDF3EC` (Text: `#346538`) |
| 44 | 44 | - Pale Yellow: `#FBF3DB` (Text: `#956400`) |
| 45 | 45 | |
| 46 | Expose these as Crosswind theme tokens or CSS custom properties in `config/stx.ts` so dark mode (`dark:` + `useColorMode()` / `useDark()`) stays consistent. | |
| 46 | Expose these as Crosswind theme tokens or CSS custom properties in `config/ui.ts` so dark mode (`dark:` + `useColorMode()` / `useDark()`) stays consistent. | |
| 47 | 47 | |
| 48 | 48 | ## 5. Component Specifications |
| 49 | 49 | - Bento Box Feature Grids: |
| @@ -17,7 +17,7 @@ allowed-tools: Read Edit Write Bash Grep Glob | ||
| 17 | 17 | - Buddy CLI dev commands: `storage/framework/core/buddy/src/commands/dev.ts` |
| 18 | 18 | - Preloader: `storage/framework/defaults/resources/plugins/preloader.ts` |
| 19 | 19 | - Port config: `config/ports.ts` |
| 20 | - STX config: `config/stx.ts` | |
| 20 | - STX config: `config/ui.ts` | |
| 21 | 21 | - IDE defaults: `storage/framework/defaults/ide/` |
| 22 | 22 | - SSL setup: `storage/framework/core/actions/src/setup/ssl.ts` |
| 23 | 23 | - Bun config: `bunfig.toml` |
| @@ -268,7 +268,7 @@ Default configurations provided at `storage/framework/defaults/ide/`: | ||
| 268 | 268 | - `.env` file presence (warn if missing, not a failure) |
| 269 | 269 | - `APP_KEY` is set (warn if not, suggests `buddy key:generate`) |
| 270 | 270 | |
| 271 | ## STX Configuration (config/stx.ts) | |
| 271 | ## STX Configuration (config/ui.ts) | |
| 272 | 272 | |
| 273 | 273 | ```typescript |
| 274 | 274 | { |
| @@ -329,7 +329,7 @@ Use standard `<img>` with explicit `width`/`height` to reserve space and avoid C | ||
| 329 | 329 | |
| 330 | 330 | ### 12.H Dark mode |
| 331 | 331 | |
| 332 | Crosswind `dark:` variant (`bg-white dark:bg-neutral-900`). Runtime toggle via `useColorMode()` / `useDark()`. Config in `config/stx.ts`. | |
| 332 | Crosswind `dark:` variant (`bg-white dark:bg-neutral-900`). Runtime toggle via `useColorMode()` / `useDark()`. Config in `config/ui.ts`. | |
| 333 | 333 | |
| 334 | 334 | ### 12.I Motion: CSS + composables (no GSAP / Motion / Framer) |
| 335 | 335 | |
| @@ -14,7 +14,7 @@ allowed-tools: Read Edit Write Bash Grep Glob | ||
| 14 | 14 | |
| 15 | 15 | When applied to an existing Stacks project, follow this sequence: |
| 16 | 16 | |
| 17 | 1. **Scan** - Read the codebase. Confirm the stack is stx + Crosswind + composables. Locate `resources/views/*.stx`, `resources/components/*.stx`, `resources/layouts/*.stx`, `config/stx.ts`, `config/crosswind.ts`, and the `fonts` config. Note current design patterns. | |
| 17 | 1. **Scan** - Read the codebase. Confirm the stack is stx + Crosswind + composables. Locate `resources/views/*.stx`, `resources/components/*.stx`, `resources/layouts/*.stx`, `config/ui.ts`, `config/crosswind.ts`, and the `fonts` config. Note current design patterns. | |
| 18 | 18 | 2. **Diagnose** - Run through the audit below. List every generic pattern, weak point, and missing state you find. |
| 19 | 19 | 3. **Fix** - Apply targeted upgrades working with the existing stx + Crosswind stack. Do not rewrite from scratch and do not migrate frameworks. Improve what is there. |
| 20 | 20 | |
| @@ -15,7 +15,7 @@ STX is the full-stack templating and component framework for Stacks. It handles | ||
| 15 | 15 | When the task is how a page should *look* (not just how stx renders), pair this skill with the design-taste family: `stacks-design-taste` (flagship), the aesthetic presets `stacks-design-soft` / `stacks-design-minimalist` / `stacks-design-brutalist`, `stacks-redesign`, `stacks-design-output`, and the image-first `stacks-image-to-code` / `stacks-imagegen-web` / `stacks-imagegen-mobile` / `stacks-brandkit`. They translate premium design rules into stx + Crosswind + composables. |
| 16 | 16 | |
| 17 | 17 | ## Key Paths |
| 18 | - STX config: `config/stx.ts` | |
| 18 | - STX config: `config/ui.ts` | |
| 19 | 19 | - STX plugin: `bun-plugin-stx` (loaded via bunfig.toml) |
| 20 | 20 | - STX state: `.stx/` |
| 21 | 21 | - Components: `resources/components/` |
| @@ -58,7 +58,7 @@ function increment() { | ||
| 58 | 58 | </style> |
| 59 | 59 | ``` |
| 60 | 60 | |
| 61 | ## Configuration (config/stx.ts) | |
| 61 | ## Configuration (config/ui.ts) | |
| 62 | 62 | |
| 63 | 63 | ```typescript |
| 64 | 64 | import type { StxOptions } from '@stacksjs/stx' |
| @@ -19,8 +19,8 @@ For premium, non-templated UI (layout, typography, color, motion) built on stx + renamed throughout | ||
| 19 | 19 | ## Key Paths |
| 20 | 20 | - Core package: `storage/framework/core/ui/src/` |
| 21 | 21 | - Components: `storage/framework/core/ui/src/components/` |
| 22 | - UI config: `config/stx.ts` (Crosswind) | |
| 23 | - STX config: `config/stx.ts` | |
| 22 | - UI config: `config/ui.ts` (Crosswind) | |
| 23 | - STX config: `config/ui.ts` | |
| 24 | 24 | - STX engine: `node_modules/@stacksjs/stx/` |
| 25 | 25 | - Crosswind: `node_modules/@cwcss/crosswind/` |
| 26 | 26 | - Component types: `storage/framework/types/components.d.ts` |
| @@ -196,7 +196,7 @@ defineStore('theme', () => { | ||
| 196 | 196 | }, { persist: true }) |
| 197 | 197 | ``` |
| 198 | 198 | |
| 199 | ## Crosswind Configuration (config/stx.ts) | |
| 199 | ## Crosswind Configuration (config/ui.ts) | |
| 200 | 200 | |
| 201 | 201 | ```typescript |
| 202 | 202 | export default { |
| @@ -210,7 +210,7 @@ export default { | ||
| 210 | 210 | } satisfies CrosswindOptions |
| 211 | 211 | ``` |
| 212 | 212 | |
| 213 | ## STX Configuration (config/stx.ts) | |
| 213 | ## STX Configuration (config/ui.ts) | |
| 214 | 214 | |
| 215 | 215 | ```typescript |
| 216 | 216 | export default { |
Renamed from config/stx.ts. The contents are unchanged.
| @@ -78,7 +78,7 @@ | ||
| 78 | 78 | "bun-query-builder": "^0.2.57", |
| 79 | 79 | "stacks": "^0.74.0" |
| 80 | 80 | }, |
| 81 | "//overrides": "stx is not a direct dependency \u2014 the only reference is a type import in config/stx.ts. But it arrives through nine transitive paths, and bun-plugin-stx asks for a range so loose (^0.2.72) that dropping the old direct pin let the hoisted copy fall to 0.2.176 while the framework packages sat on 0.2.231. bun-plugin-stx resolves to the HOISTED copy, so that is the version that renders every .stx file. Every constraint in the tree (^0.2.230, 0.2.231, ^0.2.82, ^0.2.72) is satisfied by 0.2.231, so pinning it here collapses the tree to one copy without re-declaring a dependency this app does not have. Re-check after a stacks bump.", | |
| 81 | "//overrides": "stx is not a direct dependency \u2014 the only reference is a type import in config/ui.ts. But it arrives through nine transitive paths, and bun-plugin-stx asks for a range so loose (^0.2.72) that dropping the old direct pin let the hoisted copy fall to 0.2.176 while the framework packages sat on 0.2.231. bun-plugin-stx resolves to the HOISTED copy, so that is the version that renders every .stx file. Every constraint in the tree (^0.2.230, 0.2.231, ^0.2.82, ^0.2.72) is satisfied by 0.2.231, so pinning it here collapses the tree to one copy without re-declaring a dependency this app does not have. Re-check after a stacks bump.", | |
| 82 | 82 | "overrides": { |
| 83 | 83 | "@stacksjs/stx": "0.2.231" |
| 84 | 84 | }, |
| @@ -14,7 +14,7 @@ | ||
| 14 | 14 | * substitute, and it is also the router-safe home — the SPA router destroys |
| 15 | 15 | * every <head> style that is not the Crosswind tag, but leaves <link>s alone. |
| 16 | 16 | * |
| 17 | * Linked once from config/stx.ts `app.head.link`, after /tokens.css so it can | |
| 17 | * Linked once from config/ui.ts `app.head.link`, after /tokens.css so it can | |
| 18 | 18 | * read the palette, before the Crosswind sheet so utilities still win a |
| 19 | 19 | * specificity tie against anything here. |
| 20 | 20 | * |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* loghq design tokens — the single source for the app surface. |
| 2 | 2 | * |
| 3 | * Linked once from config/stx.ts `app.head.link`, so every page gets it without | |
| 3 | * Linked once from config/ui.ts `app.head.link`, so every page gets it without | |
| 4 | 4 | * repeating it. Ten app views used to declare their own byte-similar copy of |
| 5 | 5 | * this block: 90 custom-property declarations in four subtly diverging |
| 6 | 6 | * variants, which is how the dashboard's `--mono` stack ended up one entry |
| @@ -238,7 +238,7 @@ body { | ||
| 238 | 238 | * before first paint. |
| 239 | 239 | * |
| 240 | 240 | * stx's color-mode boot script sets data-theme on the root above every |
| 241 | * stylesheet (config/stx.ts app.colorMode), and useColorMode keeps it current | |
| 241 | * stylesheet (config/ui.ts app.colorMode), and useColorMode keeps it current | |
| 242 | 242 | * afterwards, so the correct icon paints immediately and the mirror signal the |
| 243 | 243 | * binding needed is gone from all three pages. */ |
| 244 | 244 | :root[data-theme='light'] .theme-btn .ic-sun { |
| @@ -1,14 +1,14 @@ | ||
| 1 | 1 | {{-- App and auth chrome. Layout group 'default'. |
| 2 | 2 | |
| 3 | 3 | A FRAGMENT, not a document. stx synthesises the doctype, the html/head/body |
| 4 | elements and their contents from config/stx.ts `app.head` merged with each | |
| 4 | elements and their contents from config/ui.ts `app.head` merged with each | |
| 5 | 5 | page's useSeoMeta() (process.js:205-233 → document-shell.js). Writing a |
| 6 | 6 | document here would make hasDocumentShell() true (document-shell.js:64), |
| 7 | 7 | turn ensureDocumentShell() into a no-op, and silently drop every page's |
| 8 | 8 | title, description and og tags on the floor. |
| 9 | 9 | |
| 10 | 10 | This layout owns the single router container, and that is load-bearing |
| 11 | rather than cosmetic. config/stx.ts pins `router.container: 'main'`; | |
| 11 | rather than cosmetic. config/ui.ts pins `router.container: 'main'`; | |
| 12 | 12 | getContainer() (stx-router client.js:193-195) returns the FIRST match, and |
| 13 | 13 | when it returns null shouldIntercept bails at client.js:796 and swap() |
| 14 | 14 | falls back to a full location assignment at client.js:395 — every link |
| @@ -57,7 +57,7 @@ | ||
| 57 | 57 | lives here instead. --}} |
| 58 | 58 | |
| 59 | 59 | @head |
| 60 | {{-- Marketing-only stylesheet, deliberately NOT in config/stx.ts app.head: app | |
| 60 | {{-- Marketing-only stylesheet, deliberately NOT in config/ui.ts app.head: app | |
| 61 | 61 | pages never linked it and define their own conflicting .btn and .panel |
| 62 | 62 | rules. The shared fonts, charset, viewport and favicon DO live in app.head — |
| 63 | 63 | they are genuinely site-wide, and injectConfigHeadTags dedupes by exact href |
| @@ -77,7 +77,7 @@ | ||
| 77 | 77 | |
| 78 | 78 | @include('SiteNav') |
| 79 | 79 | |
| 80 | {{-- The single router container (config/stx.ts router.container). Pages must not | |
| 80 | {{-- The single router container (config/ui.ts router.container). Pages must not | |
| 81 | 81 | declare their own: the server slices the fragment between the first opening |
| 82 | 82 | tag and the last closing one, so a second one makes the span ambiguous. --}} |
| 83 | 83 | <main> |
| @@ -505,7 +505,7 @@ const pro = state(false) | ||
| 505 | 505 | |
| 506 | 506 | // `theme` mirrors the root element's data-theme — the root is owned by no |
| 507 | 507 | // component, and stx's color-mode boot script — emitted from app.colorMode in |
| 508 | // config/stx.ts — sets it before hydration to avoid a flash. | |
| 508 | // config/ui.ts — sets it before hydration to avoid a flash. | |
| 509 | 509 | function toggleTheme(): void { |
| 510 | 510 | // The theme store owns persistence, the prefers-color-scheme listener, the |
| 511 | 511 | // cross-tab storage listener and the dark-class write. This used to do the |
| @@ -625,7 +625,7 @@ onMount(() => { | ||
| 625 | 625 | @extends('layouts/default') |
| 626 | 626 | |
| 627 | 627 | @section('content') |
| 628 | {{-- No hand-written theme guard here. config/stx.ts declares app.colorMode, and | |
| 628 | {{-- No hand-written theme guard here. config/ui.ts declares app.colorMode, and | |
| 629 | 629 | stx emits the pre-paint boot script from that one declaration — first inside |
| 630 | 630 | <head>, above every stylesheet, reading the same loghq_theme key and setting |
| 631 | 631 | the same data-theme attribute this script used to set by hand. The generated |
| @@ -79,7 +79,7 @@ useSeoMeta({ | ||
| 79 | 79 | // |
| 80 | 80 | // The theme button holds no state at all now. Its icon swap is a CSS rule keyed |
| 81 | 81 | // off the root element's data-theme (public/tokens.css), which stx's color-mode |
| 82 | // boot script sets before first paint from app.colorMode in config/stx.ts. The | |
| 82 | // boot script sets before first paint from app.colorMode in config/ui.ts. The | |
| 83 | 83 | // mirror signal this file used to keep — and the :data-t binding it fed — meant |
| 84 | 84 | // neither icon matched until hydration, so the button rendered empty. |
| 85 | 85 | function toggleTheme(): void { |
| @@ -103,7 +103,7 @@ function logout(): void { | ||
| 103 | 103 | @extends('layouts/default') |
| 104 | 104 | |
| 105 | 105 | @section('content') |
| 106 | {{-- No hand-written theme guard here. config/stx.ts declares app.colorMode, and | |
| 106 | {{-- No hand-written theme guard here. config/ui.ts declares app.colorMode, and | |
| 107 | 107 | stx emits the pre-paint boot script from that one declaration — first inside |
| 108 | 108 | <head>, above every stylesheet, reading the same loghq_theme key and setting |
| 109 | 109 | the same data-theme attribute this script used to set by hand. The generated |
| @@ -1193,7 +1193,7 @@ onMount(() => { | ||
| 1193 | 1193 | @extends('layouts/default') |
| 1194 | 1194 | |
| 1195 | 1195 | @section('content') |
| 1196 | {{-- No hand-written theme guard here. config/stx.ts declares app.colorMode, and | |
| 1196 | {{-- No hand-written theme guard here. config/ui.ts declares app.colorMode, and | |
| 1197 | 1197 | stx emits the pre-paint boot script from that one declaration — first inside |
| 1198 | 1198 | <head>, above every stylesheet, reading the same loghq_theme key and setting |
| 1199 | 1199 | the same data-theme attribute this script used to set by hand. The generated |
| @@ -28,7 +28,7 @@ | ||
| 28 | 28 | "@/*": ["./resources/*"] |
| 29 | 29 | } |
| 30 | 30 | }, |
| 31 | // `satisfies UiOptions` in config/stx.ts is only evaluated if tsc sees the | |
| 31 | // `satisfies UiOptions` in config/ui.ts is only evaluated if tsc sees the | |
| 32 | 32 | // file. It previously did not: this list covered nine project files and |
| 33 | 33 | // matched nothing under config/ or resources/, so the one place a typo costs |
| 34 | 34 | // an entire subsystem was unchecked. resources/stores/**/*.ts is here because |