@schandlergarcia/sf-web-components 2.3.16 → 2.4.0

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 (78) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/CLAUDE.md +12 -13
  3. package/README.md +0 -15
  4. package/dist/styles/global.css +46 -48
  5. package/package.json +1 -2
  6. package/scripts/apply-brand.mjs +47 -30
  7. package/scripts/postinstall.mjs +1 -11
  8. package/src/styles/global.css +46 -48
  9. package/brands/engine/PARTNER_HUB_PRD.md +0 -584
  10. package/brands/engine/agentApiConfig.ts +0 -36
  11. package/brands/engine/app/api/graphql-operations-types.ts +0 -11260
  12. package/brands/engine/app/api/graphqlClient.ts +0 -25
  13. package/brands/engine/app/api/partnerQueries.ts +0 -212
  14. package/brands/engine/app/appLayout.tsx +0 -5
  15. package/brands/engine/app/components/AgentPanel.tsx +0 -402
  16. package/brands/engine/app/components/AgentforceConversationClient.tsx +0 -201
  17. package/brands/engine/app/components/__inherit_AgentforceConversationClient.tsx +0 -3
  18. package/brands/engine/app/components/alerts/status-alert.tsx +0 -49
  19. package/brands/engine/app/components/layouts/card-layout.tsx +0 -29
  20. package/brands/engine/app/components/workspace/CommandCenter.tsx +0 -16
  21. package/brands/engine/app/config/agentApi.ts +0 -36
  22. package/brands/engine/app/features/object-search/__examples__/api/accountSearchService.ts +0 -46
  23. package/brands/engine/app/features/object-search/__examples__/api/query/distinctAccountIndustries.graphql +0 -19
  24. package/brands/engine/app/features/object-search/__examples__/api/query/distinctAccountTypes.graphql +0 -19
  25. package/brands/engine/app/features/object-search/__examples__/api/query/getAccountDetail.graphql +0 -121
  26. package/brands/engine/app/features/object-search/__examples__/api/query/searchAccounts.graphql +0 -51
  27. package/brands/engine/app/features/object-search/__examples__/pages/AccountObjectDetailPage.tsx +0 -357
  28. package/brands/engine/app/features/object-search/__examples__/pages/AccountSearch.tsx +0 -312
  29. package/brands/engine/app/features/object-search/__examples__/pages/Home.tsx +0 -34
  30. package/brands/engine/app/features/object-search/api/objectSearchService.ts +0 -84
  31. package/brands/engine/app/features/object-search/components/ActiveFilters.tsx +0 -89
  32. package/brands/engine/app/features/object-search/components/FilterContext.tsx +0 -83
  33. package/brands/engine/app/features/object-search/components/ObjectBreadcrumb.tsx +0 -66
  34. package/brands/engine/app/features/object-search/components/PaginationControls.tsx +0 -109
  35. package/brands/engine/app/features/object-search/components/SearchBar.tsx +0 -41
  36. package/brands/engine/app/features/object-search/components/SortControl.tsx +0 -143
  37. package/brands/engine/app/features/object-search/components/filters/BooleanFilter.tsx +0 -78
  38. package/brands/engine/app/features/object-search/components/filters/DateFilter.tsx +0 -128
  39. package/brands/engine/app/features/object-search/components/filters/DateRangeFilter.tsx +0 -70
  40. package/brands/engine/app/features/object-search/components/filters/FilterFieldWrapper.tsx +0 -33
  41. package/brands/engine/app/features/object-search/components/filters/MultiSelectFilter.tsx +0 -97
  42. package/brands/engine/app/features/object-search/components/filters/NumericRangeFilter.tsx +0 -163
  43. package/brands/engine/app/features/object-search/components/filters/SearchFilter.tsx +0 -50
  44. package/brands/engine/app/features/object-search/components/filters/SelectFilter.tsx +0 -97
  45. package/brands/engine/app/features/object-search/components/filters/TextFilter.tsx +0 -91
  46. package/brands/engine/app/features/object-search/hooks/useAsyncData.ts +0 -54
  47. package/brands/engine/app/features/object-search/hooks/useCachedAsyncData.ts +0 -184
  48. package/brands/engine/app/features/object-search/hooks/useDebouncedCallback.ts +0 -34
  49. package/brands/engine/app/features/object-search/hooks/useObjectSearchParams.ts +0 -252
  50. package/brands/engine/app/features/object-search/utils/debounce.ts +0 -25
  51. package/brands/engine/app/features/object-search/utils/fieldUtils.ts +0 -29
  52. package/brands/engine/app/features/object-search/utils/filterUtils.ts +0 -404
  53. package/brands/engine/app/features/object-search/utils/sortUtils.ts +0 -38
  54. package/brands/engine/app/hooks/useEngineLiveData.ts +0 -49
  55. package/brands/engine/app/hooks/useEvaAgent.ts +0 -288
  56. package/brands/engine/app/hooks/usePartnerDashboardData.ts +0 -141
  57. package/brands/engine/app/navigationMenu.tsx +0 -80
  58. package/brands/engine/app/pages/AccountObjectDetailPage.tsx +0 -361
  59. package/brands/engine/app/pages/AccountSearch.tsx +0 -305
  60. package/brands/engine/app/pages/BlankDashboard.tsx +0 -15
  61. package/brands/engine/app/pages/DataTest.tsx +0 -78
  62. package/brands/engine/app/pages/Home.tsx +0 -5
  63. package/brands/engine/app/pages/NotFound.tsx +0 -19
  64. package/brands/engine/app/pages/PartnerHubDashboard.tsx +0 -2077
  65. package/brands/engine/app/pages/Search.tsx +0 -13
  66. package/brands/engine/app/router-utils.tsx +0 -35
  67. package/brands/engine/app/routes.tsx +0 -39
  68. package/brands/engine/app/styles/global.css +0 -269
  69. package/brands/engine/brand.css +0 -40
  70. package/brands/engine/engine-command-center-prd.md +0 -575
  71. package/brands/engine/engine-live-data.js +0 -135
  72. package/brands/engine/engine-sample-data.js +0 -378
  73. package/brands/engine/engine_logo.png +0 -0
  74. package/brands/engine/global.css +0 -269
  75. package/brands/engine/partner-hub-sample-data.js +0 -281
  76. package/brands/engine/schema.graphql +0 -292
  77. package/brands/engine/useEngineLiveData.ts +0 -49
  78. package/brands/engine/useEvaAgent.ts +0 -288
package/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.4.0] - 2026-05-07
9
+
10
+ ### Removed
11
+ - **Engine brand assets** — deleted `brands/engine/` (global.css, app/, sample data, PRD, GraphQL schema, Engine logo, Engine-specific hooks like `useEvaAgent` and `useEngineLiveData`).
12
+ - **Top-level `data/` directory** — removed all Engine Travel Command Center data, schema, agent API config, and the README/USAGE docs that documented Engine-only assets.
13
+ - **`brand:engine` and `demo:engine` npm scripts** — removed from `package.json` and from the postinstall script that adds scripts to consuming projects.
14
+
15
+ ### Changed
16
+ - **`src/styles/global.css` is now truly neutral** — replaced the `--color-engine-*` palette and the Cyan/Engine-Black brand ramp with a slate-based neutral `--color-brand-*` ramp; replaced the Engine-coded `.heroui-scope` (Engine Black `#0D1117`, Cyan `#7DCBD9`, Orange-Red `#FD4B23`, Amber `#FFB200`, Engine Blue `#157DE5`) with neutral `oklch()` defaults. The `:root` `--dash-*` tokens (which previously used Engine amber/cream) now use neutral slate/standard semantic colors.
17
+ - **`scripts/apply-brand.mjs` is now brand-agnostic** — sample-data file copying discovers `*-sample-data.js` / `*-live-data.js` / `*-data.{js,ts}` files dynamically instead of hardcoding `engine-sample-data.js`, `engine-live-data.js`, `partner-hub-sample-data.js`. Logo copying discovers any `*.png|jpg|svg|webp|gif` file at the brand root instead of hardcoding `engine_logo.png`. Updated header docs to remove Engine examples.
18
+ - **`CLAUDE.md` Brand System section rewritten** — removed the "Engine Brand" callout and the `brand:engine` example. Now explains the brand system as optional infrastructure (no brands ship by default) and documents the conventions a `brands/<name>/` folder can use.
19
+ - **`README.md` Sample Data section removed** — the package no longer ships Engine Travel sample data.
20
+
21
+ ### Context
22
+ - The package and its source files no longer carry any Engine Travel branding so it can be used as a neutral baseline for building a new app on top of the component library and Command Center builder. The brand system itself remains available; teams can drop their own brand under `brands/<name>/`.
23
+
24
+ ## [2.3.17] - 2026-04-15
25
+
26
+ ### Changed
27
+ - **Two-agent chat system** — AgentPanel now supports Partner Service Agent (booking recovery, default) and Engine Virtual Agent (case triage with handoff). Agents swap via `npm run agent:partner` / `agent:engine` which edits the source directly for instant HMR.
28
+ - **Structured card renderer for chat** — Messages with headers (OPEN CASES SUMMARY, CANCELED BOOKING, PROMOTION LIVE) render as formatted cards with priority dots, key-value pairs, and color-coded sections instead of plain text.
29
+ - **Improved chat readability** — Replaced CSS variable colors with high-contrast solid colors. Warm parchment backgrounds, dark text, visible borders. Bumped all font sizes +1px.
30
+ - **Cascading skeleton loading** — Tab switch skeletons now fade in with randomized stagger delays per element instead of uniform pulse. Each element has a unique random delay for natural feel.
31
+ - **Streamlined promo flow** — Removed ENGINE NETWORK PROMOTION card; upsell pitch now follows directly after CANCELED BOOKING card in a single conversational message.
32
+ - **Demo state manager** — `demo.sh` now tracks AgentPanel.tsx. Added `demo:d360` npm shortcut to fast-forward to Data 360 tab state.
33
+ - **Data 360 demo state** — Pre-built demo version with Data 360 booking segmentation tab, saveable/restorable via `demo:d360` / `demo:reset`.
34
+
8
35
  ## [2.3.16] - 2026-04-14
9
36
 
10
37
  ### Changed
package/CLAUDE.md CHANGED
@@ -67,8 +67,7 @@ sf-web-components/
67
67
  │ │ └── workspace/ # CommandCenter.tsx.template
68
68
  │ ├── lib/ # Utilities (utils.ts)
69
69
  │ └── styles/ # global.css with neutral brand tokens
70
- ├── brands/
71
- │ └── engine/ # Engine brand (global.css, sample data, PRD, hooks)
70
+ ├── brands/ # Optional brand bundles (none ship by default)
72
71
  ├── scripts/
73
72
  │ ├── postinstall.mjs # Runs after npm install in consuming projects
74
73
  │ ├── apply-brand.mjs # Apply/reset brand themes
@@ -86,23 +85,23 @@ sf-web-components/
86
85
 
87
86
  ## Brand System
88
87
 
89
- The package ships with a **neutral theme** by default. Opt into a specific brand:
88
+ The package ships with a **neutral theme** by default. No brands ship out of the box; the brand system is optional infrastructure for layering custom themes/demo apps on top of the neutral baseline.
90
89
 
91
90
  ```bash
92
- npm run brand:engine # Apply Engine brand (colors, sample data, PRD, hooks)
93
- npm run brand:reset # Revert to neutral theme
94
- npm run brand:list # Show available brands
91
+ npm run brand:list # Show available brands (empty by default)
92
+ npm run brand:reset # Restore neutral theme (clears any active brand)
95
93
  ```
96
94
 
97
- When a brand is active, the reset script (`npm run reset:command-center`) preserves the brand's `global.css` instead of restoring neutral. The `.brand` marker file tracks which brand is active.
95
+ To add a brand, drop a folder under `brands/<name>/` containing any of:
98
96
 
99
- ### Engine Brand
100
- - **Primary:** Engine Black `#0D1117`
101
- - **Accent:** Cyan `#7DCBD9`, Green `#1E9D6D`, Blue `#157DE5`
102
- - **Secondary:** Orange-Red `#FD4B23`, Amber `#FFB200`
103
- - **Neutrals:** Dark Gray `#616368`, Mid Gray `#B0B1B3`, Light Gray `#F3F3F4`
97
+ - `global.css` — overrides applied to `src/styles/global.css`
98
+ - `app/` full demo app (pages, hooks, api, features) installed via `--demo`
99
+ - `*.png` / `*.svg` logo assets installed into `src/assets/images/`
100
+ - `*-sample-data.js` / `*-live-data.js` installed into `src/data/`
101
+ - `*_PRD.md` / `*-prd.md` product requirements docs copied to project root
102
+ - `schema.graphql` — data schema copied to project root
104
103
 
105
- Installs: Engine-branded `global.css`, sample data, live data, PRD, GraphQL schema, Eva agent hook, agent config, and Engine logo.
104
+ When a brand is active, the reset script (`npm run reset:command-center`) preserves the brand's `global.css` instead of restoring neutral. The `.brand` marker file tracks which brand is active.
106
105
 
107
106
  ## Key Conventions
108
107
 
package/README.md CHANGED
@@ -75,21 +75,6 @@ This library includes:
75
75
  - Filter components
76
76
  - Layout components
77
77
 
78
- ## Sample Data
79
-
80
- The package includes pre-seeded sample data in the `data/` directory:
81
- - **Engine Travel Command Center** sample data with real Salesforce field names
82
- - Dashboard-ready data (map markers, chart data, metrics, etc.)
83
- - Easy to swap for live data later
84
-
85
- **Copy to your project:**
86
- ```bash
87
- # From your webapp directory
88
- cp node_modules/@schandlergarcia/sf-web-components/data/engine-sample-data.js src/data/
89
- ```
90
-
91
- See `data/README.md` and `data/USAGE.md` in the package for full documentation.
92
-
93
78
  ## Utilities
94
79
 
95
80
  ```tsx
@@ -58,18 +58,18 @@
58
58
  --color-sidebar-border: var(--sidebar-border);
59
59
  --color-sidebar-ring: var(--sidebar-ring);
60
60
 
61
- /* Brand palettecustomize these to match your brand */
62
- --color-brand-50: #F0F9FF;
63
- --color-brand-100: #E0F2FE;
64
- --color-brand-200: #BAE6FD;
65
- --color-brand-300: #7DD3FC;
66
- --color-brand-400: #38BDF8;
67
- --color-brand-500: #0EA5E9;
68
- --color-brand-600: #0284C7;
69
- --color-brand-700: #0369A1;
70
- --color-brand-800: #075985;
71
- --color-brand-900: #0C4A6E;
72
- --color-brand-950: #082F49;
61
+ /* Neutral brand ramp override per-app to apply your brand colors */
62
+ --color-brand-50: #f8fafc;
63
+ --color-brand-100: #f1f5f9;
64
+ --color-brand-200: #e2e8f0;
65
+ --color-brand-300: #cbd5e1;
66
+ --color-brand-400: #94a3b8;
67
+ --color-brand-500: #64748b;
68
+ --color-brand-600: #475569;
69
+ --color-brand-700: #334155;
70
+ --color-brand-800: #1e293b;
71
+ --color-brand-900: #0f172a;
72
+ --color-brand-950: #020617;
73
73
 
74
74
  --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
75
75
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
@@ -79,24 +79,24 @@
79
79
  }
80
80
 
81
81
  :root {
82
- --dash-text: #1e293b;
82
+ --dash-text: #0f172a;
83
83
  --dash-muted: #475569;
84
- --dash-label: #64748b;
85
- --dash-surface: #dbeafe;
86
- --dash-border: #93c5fd;
87
- --dash-accent: #2563eb;
88
- --dash-success: #16a34a;
89
- --dash-info: #7c3aed;
90
- --dash-warning: #ca8a04;
84
+ --dash-label: #94a3b8;
85
+ --dash-surface: #ffffff;
86
+ --dash-border: #e2e8f0;
87
+ --dash-accent: #64748b;
88
+ --dash-success: #34d399;
89
+ --dash-info: #67e8f9;
90
+ --dash-warning: #f59e0b;
91
91
  --dash-danger: #dc2626;
92
- --dash-dark: #1e3a8a;
93
- --dash-darker: #172554;
94
- --dash-chart-1: #2563eb;
95
- --dash-chart-2: #16a34a;
96
- --dash-chart-3: #e11d48;
97
- --dash-chart-4: #7c3aed;
98
- --dash-metric-size: 2rem;
99
- --dash-metric-sub: 1.5rem;
92
+ --dash-dark: #0f172a;
93
+ --dash-darker: #020617;
94
+ --dash-chart-1: #64748b;
95
+ --dash-chart-2: #34d399;
96
+ --dash-chart-3: #67e8f9;
97
+ --dash-chart-4: #f59e0b;
98
+ --dash-metric-size: 2.5rem;
99
+ --dash-metric-sub: 2.25rem;
100
100
  --color-dash-text: var(--dash-text);
101
101
  --color-dash-muted: var(--dash-muted);
102
102
  --color-dash-label: var(--dash-label);
@@ -193,39 +193,37 @@
193
193
 
194
194
  /*
195
195
  * Restore HeroUI theme variables inside the Command Center scope.
196
- * shadcn redefines --muted, --accent, --accent-foreground with different
197
- * semantics (bg colors vs text colors). This scope restores HeroUI's values
198
- * so HeroUI components render correctly.
196
+ * Neutral defaults override per-app to apply your brand colors.
199
197
  */
200
198
  .heroui-scope {
201
- --primary: #000000;
199
+ --primary: oklch(0.205 0 0);
202
200
  --primary-foreground: oklch(0.9911 0 0);
203
- --secondary: #0EA5E9;
201
+ --secondary: oklch(0.55 0.02 240);
204
202
  --secondary-foreground: oklch(0.9911 0 0);
205
- --success: #16A34A;
203
+ --success: #16a34a;
206
204
  --success-foreground: oklch(0.9911 0 0);
207
- --warning: #F59E0B;
208
- --warning-foreground: oklch(0.2103 0.0059 285.89);
209
- --danger: #EF4444;
205
+ --warning: #f59e0b;
206
+ --warning-foreground: oklch(0.205 0 0);
207
+ --danger: #dc2626;
210
208
  --danger-foreground: oklch(0.9911 0 0);
211
209
 
212
210
  --muted: oklch(0.5517 0.0138 285.94);
213
211
  --accent: oklch(0.6204 0.195 253.83);
214
212
  --accent-foreground: oklch(0.9911 0 0);
215
- --background: oklch(0.9702 0 0);
216
- --foreground: oklch(0.2103 0.0059 285.89);
213
+ --background: oklch(0.985 0 0);
214
+ --foreground: oklch(0.145 0 0);
217
215
  --default: oklch(94% 0.001 286.375);
218
- --default-foreground: oklch(0.2103 0.0059 285.89);
219
- --border: oklch(90% 0.004 286.32);
216
+ --default-foreground: oklch(0.145 0 0);
217
+ --border: oklch(0.85 0.005 286);
220
218
  --separator: oklch(92% 0.004 286.32);
221
219
  --segment: oklch(100% 0 0);
222
- --segment-foreground: oklch(0.2103 0.0059 285.89);
220
+ --segment-foreground: oklch(0.145 0 0);
223
221
  --surface: oklch(100% 0 0);
224
- --surface-foreground: oklch(0.2103 0.0059 285.89);
222
+ --surface-foreground: oklch(0.145 0 0);
225
223
  --overlay: oklch(100% 0 0);
226
- --overlay-foreground: oklch(0.2103 0.0059 285.89);
227
- --focus: oklch(0.6204 0.195 253.83);
228
- --link: oklch(0.2103 0.0059 285.89);
224
+ --overlay-foreground: oklch(0.145 0 0);
225
+ --focus: oklch(0.6 0.18 250);
226
+ --link: oklch(0.205 0 0);
229
227
  }
230
228
 
231
229
  /* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
@@ -250,9 +248,9 @@ body > .fixed.inset-x-0.rounded-2xl {
250
248
  --overlay: oklch(0.2103 0.0059 285.89);
251
249
  --overlay-foreground: oklch(0.9911 0 0);
252
250
  --warning: oklch(0.8203 0.1388 76.34);
253
- --warning-foreground: oklch(0.2103 0.0059 285.89);
251
+ --warning-foreground: oklch(0.145 0 0);
254
252
  --danger: oklch(0.594 0.1967 24.63);
255
253
  --danger-foreground: oklch(0.9911 0 0);
256
- --focus: oklch(0.6204 0.195 253.83);
254
+ --focus: oklch(0.6 0.18 250);
257
255
  --link: oklch(0.9911 0 0);
258
256
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schandlergarcia/sf-web-components",
3
- "version": "2.3.16",
3
+ "version": "2.4.0",
4
4
  "description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,7 +52,6 @@
52
52
  "reset:command-center": "bash scripts/reset-command-center.sh",
53
53
  "validate:dashboard": "bash scripts/validate-dashboard.sh",
54
54
  "graphql:schema": "node scripts/get-graphql-schema.mjs",
55
- "brand:engine": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs engine",
56
55
  "brand:reset": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --reset",
57
56
  "brand:list": "node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --list"
58
57
  },
@@ -4,14 +4,19 @@
4
4
  * apply-brand.mjs — Apply a brand theme or install a full demo app.
5
5
  *
6
6
  * Usage:
7
- * node scripts/apply-brand.mjs engine # Apply Engine brand colors only
8
- * node scripts/apply-brand.mjs --demo engine # Install full Engine demo app (neutral theme)
9
- * node scripts/apply-brand.mjs --list # List available brands
10
- * node scripts/apply-brand.mjs --reset # Remove brand, restore neutral theme
7
+ * node scripts/apply-brand.mjs <brand> # Apply brand colors only
8
+ * node scripts/apply-brand.mjs --demo <brand> # Install full demo app for a brand
9
+ * node scripts/apply-brand.mjs --list # List available brands
10
+ * node scripts/apply-brand.mjs --reset # Remove brand, restore neutral theme
11
11
  *
12
- * The demo command installs the full app (dashboard, routes, hooks, queries,
13
- * features) but keeps the neutral color palette. Run brand:engine afterwards
14
- * to switch to Engine colors.
12
+ * Brands live in brands/<name>/ at the package root. Each brand may provide:
13
+ * - global.css (theme overrides applied to src/styles/global.css)
14
+ * - app/ (full demo app: pages, hooks, api, features, etc.)
15
+ * - schema.graphql (data schema)
16
+ * - *.png (brand logo assets)
17
+ * - *_PRD.md / *-prd.md (product requirements docs)
18
+ *
19
+ * No brands ship with the package by default. Add your own under brands/.
15
20
  */
16
21
 
17
22
  import fs from 'fs';
@@ -184,17 +189,21 @@ if (isDemo) {
184
189
  }
185
190
  }
186
191
 
187
- // Copy sample data files
188
- const dataFiles = ['engine-sample-data.js', 'engine-live-data.js', 'partner-hub-sample-data.js'];
192
+ // Copy any *.js / *.ts data files at the brand root into src/data/
193
+ const dataFiles = fs.readdirSync(brandDir).filter(f => {
194
+ if (!fs.statSync(path.join(brandDir, f)).isFile()) return false;
195
+ return f.endsWith('-sample-data.js')
196
+ || f.endsWith('-live-data.js')
197
+ || f.endsWith('-data.ts')
198
+ || f.endsWith('-data.js');
199
+ });
189
200
  for (const file of dataFiles) {
190
201
  const src = path.join(brandDir, file);
191
202
  const dst = path.join(cwd, 'src/data', file);
192
- if (fs.existsSync(src)) {
193
- fs.mkdirSync(path.dirname(dst), { recursive: true });
194
- fs.copyFileSync(src, dst);
195
- console.log(` ✓ Installed src/data/${file}`);
196
- installed++;
197
- }
203
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
204
+ fs.copyFileSync(src, dst);
205
+ console.log(` ✓ Installed src/data/${file}`);
206
+ installed++;
198
207
  }
199
208
 
200
209
  // Copy PRDs to project root
@@ -213,13 +222,16 @@ if (isDemo) {
213
222
  installed++;
214
223
  }
215
224
 
216
- // Copy logo
217
- const logo = path.join(brandDir, 'engine_logo.png');
218
- if (fs.existsSync(logo)) {
219
- const logoTarget = path.join(cwd, 'src/assets/images/engine_logo.png');
220
- fs.mkdirSync(path.dirname(logoTarget), { recursive: true });
221
- fs.copyFileSync(logo, logoTarget);
222
- console.log(' Installed engine_logo.png');
225
+ // Copy any logo/image assets at the brand root into src/assets/images/
226
+ const imageFiles = fs.readdirSync(brandDir).filter(f =>
227
+ /\.(png|jpe?g|svg|webp|gif)$/i.test(f)
228
+ );
229
+ for (const file of imageFiles) {
230
+ const src = path.join(brandDir, file);
231
+ const dst = path.join(cwd, 'src/assets/images', file);
232
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
233
+ fs.copyFileSync(src, dst);
234
+ console.log(` ✓ Installed src/assets/images/${file}`);
223
235
  installed++;
224
236
  }
225
237
 
@@ -259,14 +271,19 @@ if (fs.existsSync(brandCSS)) {
259
271
  installed++;
260
272
  }
261
273
 
262
- // 2. Logo → src/assets/images/
263
- const logo = path.join(brandDir, 'engine_logo.png');
264
- if (fs.existsSync(logo)) {
265
- const logoTarget = path.join(cwd, 'src/assets/images/engine_logo.png');
266
- fs.mkdirSync(path.dirname(logoTarget), { recursive: true });
267
- fs.copyFileSync(logo, logoTarget);
268
- console.log(' ✓ Installed engine_logo.png');
269
- installed++;
274
+ // 2. Any logo/image assets → src/assets/images/
275
+ if (fs.existsSync(brandDir)) {
276
+ const imageFiles = fs.readdirSync(brandDir).filter(f =>
277
+ /\.(png|jpe?g|svg|webp|gif)$/i.test(f)
278
+ );
279
+ for (const file of imageFiles) {
280
+ const src = path.join(brandDir, file);
281
+ const dst = path.join(cwd, 'src/assets/images', file);
282
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
283
+ fs.copyFileSync(src, dst);
284
+ console.log(` ✓ Installed src/assets/images/${file}`);
285
+ installed++;
286
+ }
270
287
  }
271
288
 
272
289
  // 3. Write .brand marker
@@ -341,11 +341,7 @@ if (fs.existsSync(packageJsonPath)) {
341
341
  scriptsAdded.push('sfwc:setup');
342
342
  }
343
343
 
344
- // Add brand scripts
345
- if (!packageJson.scripts['brand:engine']) {
346
- packageJson.scripts['brand:engine'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs engine';
347
- scriptsAdded.push('brand:engine');
348
- }
344
+ // Add brand scripts (no brands ship by default — add your own under brands/)
349
345
  if (!packageJson.scripts['brand:reset']) {
350
346
  packageJson.scripts['brand:reset'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --reset';
351
347
  scriptsAdded.push('brand:reset');
@@ -355,12 +351,6 @@ if (fs.existsSync(packageJsonPath)) {
355
351
  scriptsAdded.push('brand:list');
356
352
  }
357
353
 
358
- // Add demo scripts
359
- if (!packageJson.scripts['demo:engine']) {
360
- packageJson.scripts['demo:engine'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --demo engine';
361
- scriptsAdded.push('demo:engine');
362
- }
363
-
364
354
  if (scriptsAdded.length > 0) {
365
355
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
366
356
  scriptsAdded.forEach(script => {
@@ -58,18 +58,18 @@
58
58
  --color-sidebar-border: var(--sidebar-border);
59
59
  --color-sidebar-ring: var(--sidebar-ring);
60
60
 
61
- /* Brand palettecustomize these to match your brand */
62
- --color-brand-50: #F0F9FF;
63
- --color-brand-100: #E0F2FE;
64
- --color-brand-200: #BAE6FD;
65
- --color-brand-300: #7DD3FC;
66
- --color-brand-400: #38BDF8;
67
- --color-brand-500: #0EA5E9;
68
- --color-brand-600: #0284C7;
69
- --color-brand-700: #0369A1;
70
- --color-brand-800: #075985;
71
- --color-brand-900: #0C4A6E;
72
- --color-brand-950: #082F49;
61
+ /* Neutral brand ramp override per-app to apply your brand colors */
62
+ --color-brand-50: #f8fafc;
63
+ --color-brand-100: #f1f5f9;
64
+ --color-brand-200: #e2e8f0;
65
+ --color-brand-300: #cbd5e1;
66
+ --color-brand-400: #94a3b8;
67
+ --color-brand-500: #64748b;
68
+ --color-brand-600: #475569;
69
+ --color-brand-700: #334155;
70
+ --color-brand-800: #1e293b;
71
+ --color-brand-900: #0f172a;
72
+ --color-brand-950: #020617;
73
73
 
74
74
  --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
75
75
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
@@ -79,24 +79,24 @@
79
79
  }
80
80
 
81
81
  :root {
82
- --dash-text: #1e293b;
82
+ --dash-text: #0f172a;
83
83
  --dash-muted: #475569;
84
- --dash-label: #64748b;
85
- --dash-surface: #dbeafe;
86
- --dash-border: #93c5fd;
87
- --dash-accent: #2563eb;
88
- --dash-success: #16a34a;
89
- --dash-info: #7c3aed;
90
- --dash-warning: #ca8a04;
84
+ --dash-label: #94a3b8;
85
+ --dash-surface: #ffffff;
86
+ --dash-border: #e2e8f0;
87
+ --dash-accent: #64748b;
88
+ --dash-success: #34d399;
89
+ --dash-info: #67e8f9;
90
+ --dash-warning: #f59e0b;
91
91
  --dash-danger: #dc2626;
92
- --dash-dark: #1e3a8a;
93
- --dash-darker: #172554;
94
- --dash-chart-1: #2563eb;
95
- --dash-chart-2: #16a34a;
96
- --dash-chart-3: #e11d48;
97
- --dash-chart-4: #7c3aed;
98
- --dash-metric-size: 2rem;
99
- --dash-metric-sub: 1.5rem;
92
+ --dash-dark: #0f172a;
93
+ --dash-darker: #020617;
94
+ --dash-chart-1: #64748b;
95
+ --dash-chart-2: #34d399;
96
+ --dash-chart-3: #67e8f9;
97
+ --dash-chart-4: #f59e0b;
98
+ --dash-metric-size: 2.5rem;
99
+ --dash-metric-sub: 2.25rem;
100
100
  --color-dash-text: var(--dash-text);
101
101
  --color-dash-muted: var(--dash-muted);
102
102
  --color-dash-label: var(--dash-label);
@@ -193,39 +193,37 @@
193
193
 
194
194
  /*
195
195
  * Restore HeroUI theme variables inside the Command Center scope.
196
- * shadcn redefines --muted, --accent, --accent-foreground with different
197
- * semantics (bg colors vs text colors). This scope restores HeroUI's values
198
- * so HeroUI components render correctly.
196
+ * Neutral defaults override per-app to apply your brand colors.
199
197
  */
200
198
  .heroui-scope {
201
- --primary: #000000;
199
+ --primary: oklch(0.205 0 0);
202
200
  --primary-foreground: oklch(0.9911 0 0);
203
- --secondary: #0EA5E9;
201
+ --secondary: oklch(0.55 0.02 240);
204
202
  --secondary-foreground: oklch(0.9911 0 0);
205
- --success: #16A34A;
203
+ --success: #16a34a;
206
204
  --success-foreground: oklch(0.9911 0 0);
207
- --warning: #F59E0B;
208
- --warning-foreground: oklch(0.2103 0.0059 285.89);
209
- --danger: #EF4444;
205
+ --warning: #f59e0b;
206
+ --warning-foreground: oklch(0.205 0 0);
207
+ --danger: #dc2626;
210
208
  --danger-foreground: oklch(0.9911 0 0);
211
209
 
212
210
  --muted: oklch(0.5517 0.0138 285.94);
213
211
  --accent: oklch(0.6204 0.195 253.83);
214
212
  --accent-foreground: oklch(0.9911 0 0);
215
- --background: oklch(0.9702 0 0);
216
- --foreground: oklch(0.2103 0.0059 285.89);
213
+ --background: oklch(0.985 0 0);
214
+ --foreground: oklch(0.145 0 0);
217
215
  --default: oklch(94% 0.001 286.375);
218
- --default-foreground: oklch(0.2103 0.0059 285.89);
219
- --border: oklch(90% 0.004 286.32);
216
+ --default-foreground: oklch(0.145 0 0);
217
+ --border: oklch(0.85 0.005 286);
220
218
  --separator: oklch(92% 0.004 286.32);
221
219
  --segment: oklch(100% 0 0);
222
- --segment-foreground: oklch(0.2103 0.0059 285.89);
220
+ --segment-foreground: oklch(0.145 0 0);
223
221
  --surface: oklch(100% 0 0);
224
- --surface-foreground: oklch(0.2103 0.0059 285.89);
222
+ --surface-foreground: oklch(0.145 0 0);
225
223
  --overlay: oklch(100% 0 0);
226
- --overlay-foreground: oklch(0.2103 0.0059 285.89);
227
- --focus: oklch(0.6204 0.195 253.83);
228
- --link: oklch(0.2103 0.0059 285.89);
224
+ --overlay-foreground: oklch(0.145 0 0);
225
+ --focus: oklch(0.6 0.18 250);
226
+ --link: oklch(0.205 0 0);
229
227
  }
230
228
 
231
229
  /* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
@@ -250,9 +248,9 @@ body > .fixed.inset-x-0.rounded-2xl {
250
248
  --overlay: oklch(0.2103 0.0059 285.89);
251
249
  --overlay-foreground: oklch(0.9911 0 0);
252
250
  --warning: oklch(0.8203 0.1388 76.34);
253
- --warning-foreground: oklch(0.2103 0.0059 285.89);
251
+ --warning-foreground: oklch(0.145 0 0);
254
252
  --danger: oklch(0.594 0.1967 24.63);
255
253
  --danger-foreground: oklch(0.9911 0 0);
256
- --focus: oklch(0.6204 0.195 253.83);
254
+ --focus: oklch(0.6 0.18 250);
257
255
  --link: oklch(0.9911 0 0);
258
256
  }