create-brainerce-store 1.52.2 → 1.52.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/dist/index.js +7 -2
- package/package.json +1 -1
- package/templates/nextjs/base/AGENTS.md.ejs +65 -0
- package/templates/nextjs/base/AI-GUIDE.md +31 -0
- package/templates/nextjs/base/CLAUDE.md.ejs +76 -0
- package/templates/nextjs/base/next.config.ts +11 -1
- package/templates/nextjs/base/src/app/layout.tsx.ejs +7 -3
- package/templates/nextjs/base/src/core/providers/store-provider.tsx.ejs +10 -1
- package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +7 -3
- package/templates/nextjs/designs/atelier/ui/shared/icons.tsx +1 -1
- package/templates/nextjs/base/AGENTS.md +0 -41
- package/templates/nextjs/base/CLAUDE.md +0 -52
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-brainerce-store",
|
|
34
|
-
version: "1.52.
|
|
34
|
+
version: "1.52.5",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
bin: {
|
|
37
37
|
"create-brainerce-store": "dist/index.js"
|
|
@@ -393,6 +393,9 @@ async function scaffold(options) {
|
|
|
393
393
|
const templateVars = {
|
|
394
394
|
projectName: options.projectName,
|
|
395
395
|
connectionId: options.connectionId,
|
|
396
|
+
/** Raw store name for prose contexts (markdown docs) — JS/env contexts
|
|
397
|
+
* must keep using the escaped storeNameJs / storeNameEnv variants. */
|
|
398
|
+
storeName: cleanStoreName,
|
|
396
399
|
storeNameJs: toJsStringLiteral(cleanStoreName),
|
|
397
400
|
titleTemplateJs: toJsStringLiteral(`%s | ${cleanStoreName}`),
|
|
398
401
|
storeNameEnv: toEnvLiteral(cleanStoreName),
|
|
@@ -969,7 +972,9 @@ live in messages/ (or let an AI session rewrite them).`
|
|
|
969
972
|
);
|
|
970
973
|
logger.info(
|
|
971
974
|
`
|
|
972
|
-
Want a unique design? Open
|
|
975
|
+
Want a unique design? Open THE STORE FOLDER ITSELF in Claude Code
|
|
976
|
+
(not a parent folder \u2014 that's how CLAUDE.md auto-loads and the AI
|
|
977
|
+
knows this is a live, connected Brainerce storefront), then run:
|
|
973
978
|
/design <your art-direction brief>
|
|
974
979
|
(commerce stays intact \u2014 see AI-GUIDE.md)`
|
|
975
980
|
);
|
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# AGENTS.md — this is a LIVE Brainerce storefront
|
|
2
|
+
|
|
3
|
+
**Store: "<%- storeName %>" · sales channel `<%- connectionId %>` — already
|
|
4
|
+
connected.** Products, cart, checkout, coupons, discounts, orders and content
|
|
5
|
+
flow in real time from the Brainerce dashboard. There is nothing to hook up.
|
|
6
|
+
|
|
7
|
+
- **NEVER suggest connecting this store to Shopify, WooCommerce, or "a real
|
|
8
|
+
system"** — Brainerce IS the commerce backend, and this store is wired to
|
|
9
|
+
it end-to-end.
|
|
10
|
+
- **NEVER build standalone HTML mockups or demo pages** — design THIS Next.js
|
|
11
|
+
app. Run `pnpm dev` and you are working against live data.
|
|
12
|
+
- **NEVER hardcode products, prices, or currency** — the catalog is live.
|
|
13
|
+
- **No server side is needed** — the backend is Brainerce's cloud. This repo
|
|
14
|
+
is a frontend (plus thin, already-included API proxy routes under
|
|
15
|
+
`src/app/api/`). Do not scaffold databases, auth servers, or admin panels —
|
|
16
|
+
the merchant manages everything in the Brainerce dashboard.
|
|
17
|
+
|
|
18
|
+
Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
|
|
19
|
+
— AI-readable index: https://brainerce.com/llms.txt
|
|
20
|
+
|
|
21
|
+
**Before building any feature the merchant asks for** (loyalty points,
|
|
22
|
+
shipping zones, subscriptions, gift cards, multi-currency, reviews,
|
|
23
|
+
abandoned-cart recovery, etc.) — check the docs first. Brainerce likely
|
|
24
|
+
already has it as a platform capability (dashboard toggle + hook/SDK
|
|
25
|
+
method) that only needs a UI in `src/ui/`, not a feature built from scratch.
|
|
26
|
+
|
|
27
|
+
Your job here is almost always **design**.
|
|
28
|
+
|
|
29
|
+
## The one rule
|
|
30
|
+
|
|
31
|
+
**`src/core/` is the platform's. `src/ui/` is yours.**
|
|
32
|
+
|
|
33
|
+
The shipped `src/ui/` is a working reference, not a design to preserve —
|
|
34
|
+
full delete-and-rebuild of ui files is encouraged and expected.
|
|
35
|
+
Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
|
|
36
|
+
like — the store keeps working. Never modify `src/core/`, `src/app/api/`, or
|
|
37
|
+
the checkout/auth/account components. Data and behavior come exclusively from
|
|
38
|
+
`@/core/hooks/*` and `@/core/providers/store-provider` — hooks return state
|
|
39
|
+
and handlers, never JSX. Never hardcode catalog content.
|
|
40
|
+
|
|
41
|
+
**Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
|
|
42
|
+
contracts, motion language, and hard-won RTL/i18n gotchas that will save you
|
|
43
|
+
real debugging time.
|
|
44
|
+
|
|
45
|
+
## Redesigning?
|
|
46
|
+
|
|
47
|
+
Follow the process documented in AI-GUIDE.md: commit to one art direction,
|
|
48
|
+
rewrite tokens first, then surfaces in order (header, home, card, product
|
|
49
|
+
page, cart), then verify.
|
|
50
|
+
|
|
51
|
+
## Verify before declaring done
|
|
52
|
+
|
|
53
|
+
1. `pnpm exec tsc --noEmit` → 0 errors
|
|
54
|
+
2. `pnpm dev` → drive the changed flow in a real browser (home → product →
|
|
55
|
+
add to cart → cart)
|
|
56
|
+
3. Screenshot desktop (1440px) and mobile (390px)
|
|
57
|
+
4. RTL stores: check anchoring and arrow directions
|
|
58
|
+
|
|
59
|
+
## i18n
|
|
60
|
+
|
|
61
|
+
Every user-facing string goes through `useTranslations()` with keys in **all**
|
|
62
|
+
files under `messages/`. The shipped copy is example boutique content — a
|
|
63
|
+
starting point meant to be rewritten in the store's real voice. Hebrew: no
|
|
64
|
+
uppercase transforms, no wide letter-spacing on headings, logical CSS
|
|
65
|
+
properties only (`ms-/me-`, `ps-/pe-`, `start-/end-`).
|
|
@@ -103,6 +103,37 @@ Beautiful is the top priority — the first render must wow. Hard rules:
|
|
|
103
103
|
it ("would a Lovable user accept this?"), fix, and only then move on.
|
|
104
104
|
|
|
105
105
|
|
|
106
|
+
## Motion language (CSS-first)
|
|
107
|
+
|
|
108
|
+
The store should feel alive, premium and intentional — every animation guides
|
|
109
|
+
attention, confirms an action, or rewards exploration. Rules:
|
|
110
|
+
|
|
111
|
+
- **Timing tokens** (use these, never ad-hoc numbers): 80ms instant feedback ·
|
|
112
|
+
180ms hover · 300ms UI state change · 500-600ms section entrance · 900ms
|
|
113
|
+
hero only. Stagger siblings 40-80ms.
|
|
114
|
+
- **Easing**: entrances `cubic-bezier(0.16, 1, 0.3, 1)` (out-expo); springy
|
|
115
|
+
pops `cubic-bezier(0.34, 1.56, 0.64, 1)` (out-back); loops and hovers
|
|
116
|
+
ease-in-out. Exits faster than entrances.
|
|
117
|
+
- **Reveals**: below-the-fold sections animate on viewport entry
|
|
118
|
+
(IntersectionObserver — see `src/ui/shared/reveal.tsx`), never tied to
|
|
119
|
+
scroll distance. One orchestrated reveal per section beats scattered
|
|
120
|
+
effects; `viewport once` — do not re-animate on every scroll.
|
|
121
|
+
- **Micro-interactions**: CSS/WAAPI first (see `src/ui/shared/fly-to-cart.ts`
|
|
122
|
+
for the pattern) — ripple, bump, image zoom, quick-add slide-up are all
|
|
123
|
+
achievable without a library.
|
|
124
|
+
- **Pointer effects** (magnetic buttons, tilt cards, custom cursor, mouse
|
|
125
|
+
parallax): desktop only — gate on `(pointer: fine)` and no-op under
|
|
126
|
+
`prefers-reduced-motion`. `will-change: transform` ONLY on elements animated
|
|
127
|
+
per-frame; never sprinkle it broadly.
|
|
128
|
+
- **Never `transition-all`** — always name the property
|
|
129
|
+
(`transition-transform`, `transition-opacity`). Animate only compositor
|
|
130
|
+
properties (`transform`, `opacity`) — never layout properties
|
|
131
|
+
(width/height/top/margin). 60fps is non-negotiable.
|
|
132
|
+
- **Ambient effects** (gradient blobs, particles): maximum one per page, hero
|
|
133
|
+
only — never on inner pages.
|
|
134
|
+
- **framer-motion / GSAP are not installed.** They are allowed, but they are
|
|
135
|
+
new runtime dependencies — flag it to the user before adding.
|
|
136
|
+
|
|
106
137
|
## Hard-won gotchas (each one cost a real debugging session)
|
|
107
138
|
|
|
108
139
|
- **RTL + cloned images**: `next/image` renders its `<img>` with `inset: 0`.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# CLAUDE.md — this is a LIVE Brainerce storefront
|
|
2
|
+
|
|
3
|
+
**Store: "<%- storeName %>" · sales channel `<%- connectionId %>` — already
|
|
4
|
+
connected.** Products, cart, checkout, coupons, discounts, orders and content
|
|
5
|
+
flow in real time from the Brainerce dashboard. There is nothing to hook up.
|
|
6
|
+
|
|
7
|
+
- **NEVER suggest connecting this store to Shopify, WooCommerce, or "a real
|
|
8
|
+
system"** — Brainerce IS the commerce backend, and this store is wired to
|
|
9
|
+
it end-to-end.
|
|
10
|
+
- **NEVER build standalone HTML mockups or demo pages** — design THIS Next.js
|
|
11
|
+
app. Run `pnpm dev` and you are working against live data.
|
|
12
|
+
- **NEVER hardcode products, prices, or currency** — the catalog is live.
|
|
13
|
+
- **No server side is needed** — the backend is Brainerce's cloud. This repo
|
|
14
|
+
is a frontend (plus thin, already-included API proxy routes under
|
|
15
|
+
`src/app/api/`). Do not scaffold databases, auth servers, or admin panels —
|
|
16
|
+
the merchant manages everything in the Brainerce dashboard.
|
|
17
|
+
|
|
18
|
+
Platform docs (endpoints, SDK, integration recipes): https://brainerce.com/docs
|
|
19
|
+
— AI-readable index: https://brainerce.com/llms.txt
|
|
20
|
+
|
|
21
|
+
**Before building any feature the merchant asks for** (loyalty points,
|
|
22
|
+
shipping zones, subscriptions, gift cards, multi-currency, reviews,
|
|
23
|
+
abandoned-cart recovery, etc.) — check the docs first. Brainerce likely
|
|
24
|
+
already has it as a platform capability (dashboard toggle + hook/SDK
|
|
25
|
+
method) that only needs a UI in `src/ui/`, not a feature built from scratch.
|
|
26
|
+
|
|
27
|
+
Your job here is almost always **design**.
|
|
28
|
+
|
|
29
|
+
## The one rule
|
|
30
|
+
|
|
31
|
+
**`src/core/` is the platform's. `src/ui/` is yours.**
|
|
32
|
+
|
|
33
|
+
The shipped `src/ui/` is a working reference, not a design to preserve —
|
|
34
|
+
full delete-and-rebuild of ui files is encouraged and expected. (Stores
|
|
35
|
+
scaffolded with `--canvas` ship `src/ui/` as bare unstyled skeletons —
|
|
36
|
+
there is no reference look at all; the design is entirely yours to create.)
|
|
37
|
+
Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
|
|
38
|
+
like — the store keeps working. Never modify `src/core/`, `src/app/api/`, or
|
|
39
|
+
the checkout/auth/account components. Data and behavior come exclusively from
|
|
40
|
+
`@/core/hooks/*` and `@/core/providers/store-provider` — hooks return state
|
|
41
|
+
and handlers, never JSX. Never hardcode catalog content.
|
|
42
|
+
|
|
43
|
+
**Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
|
|
44
|
+
contracts, motion language, and hard-won RTL/i18n gotchas that will save you
|
|
45
|
+
real debugging time.
|
|
46
|
+
|
|
47
|
+
## The dialect
|
|
48
|
+
|
|
49
|
+
- `src/components/ui/` = official **shadcn/ui primitives** (Button, Card,
|
|
50
|
+
Badge, Input, Select, Accordion, Dialog, Sheet, Skeleton, …). Compose them;
|
|
51
|
+
extend looks via CVA **variants**, never repeated inline overrides.
|
|
52
|
+
- Icons: **lucide-react only** — no inline `<svg>`, no emoji-as-icons.
|
|
53
|
+
- Class merging: **`cn()`** from `@/core/lib/utils`.
|
|
54
|
+
- Colors/radius come from the semantic HSL tokens in `globals.css`
|
|
55
|
+
(`--primary`, `--card`, `--ring`, `--radius`, …) — restyle via tokens.
|
|
56
|
+
|
|
57
|
+
## Redesigning? Use the ready-made flow
|
|
58
|
+
|
|
59
|
+
Run `/design <your art-direction brief>` — it walks the whole process:
|
|
60
|
+
concept → implementation in `ui/` → verification.
|
|
61
|
+
|
|
62
|
+
## Verify before declaring done
|
|
63
|
+
|
|
64
|
+
1. `pnpm exec tsc --noEmit` → 0 errors
|
|
65
|
+
2. `pnpm dev` → drive the changed flow in a real browser (home → product →
|
|
66
|
+
add to cart → cart)
|
|
67
|
+
3. Screenshot desktop (1440px) and mobile (390px)
|
|
68
|
+
4. RTL stores: check anchoring and arrow directions
|
|
69
|
+
|
|
70
|
+
## i18n
|
|
71
|
+
|
|
72
|
+
Every user-facing string goes through `useTranslations()` with keys in **all**
|
|
73
|
+
files under `messages/`. The shipped copy is example boutique content — a
|
|
74
|
+
starting point meant to be rewritten in the store's real voice. Hebrew: no
|
|
75
|
+
uppercase transforms, no wide letter-spacing on headings, logical CSS
|
|
76
|
+
properties only (`ms-/me-`, `ps-/pe-`, `start-/end-`).
|
|
@@ -26,7 +26,17 @@ const nextConfig: NextConfig = {
|
|
|
26
26
|
// isomorphic-dompurify ships jsdom, which at runtime reads stylesheet files
|
|
27
27
|
// from its own package directory. Webpack bundling breaks those relative
|
|
28
28
|
// lookups — loading it externally from node_modules keeps the paths intact.
|
|
29
|
-
|
|
29
|
+
//
|
|
30
|
+
// brainerce (the SDK) is imported across both the server and client
|
|
31
|
+
// compilation boundaries in ~60 files, including the [locale]/layout.tsx
|
|
32
|
+
// route (see generateStaticParams below) whose static params are resolved
|
|
33
|
+
// by a separate jest-worker child process in `next dev` (webpack). That
|
|
34
|
+
// worker requires the compiled page against the vendor-chunks manifest
|
|
35
|
+
// while the main dev server may still be writing it, which can throw
|
|
36
|
+
// "Cannot find module './vendor-chunks/brainerce.js'". Excluding it from
|
|
37
|
+
// server bundling (loaded externally from node_modules instead) avoids the
|
|
38
|
+
// race.
|
|
39
|
+
serverExternalPackages: ['isomorphic-dompurify', 'brainerce'],
|
|
30
40
|
images: {
|
|
31
41
|
// The storefront is a consumer of the Brainerce API — it has to render
|
|
32
42
|
// whatever image URLs the API returns. In practice those URLs are
|
|
@@ -7,7 +7,7 @@ import { SiteHeader } from '@/ui/layout/site-header';
|
|
|
7
7
|
import { SiteFooter } from '@/ui/layout/site-footer';
|
|
8
8
|
import { BrainerceBotWidget } from '@/components/brainerce-bot';
|
|
9
9
|
import { getServerClient, fetchStoreInfo } from '@/core/lib/brainerce';
|
|
10
|
-
import { getDirection, supportedLocales } from '@/i18n';
|
|
10
|
+
import { getDirection, getMessages, supportedLocales } from '@/i18n';
|
|
11
11
|
import { getNonce } from '@/core/lib/nonce';
|
|
12
12
|
import '../globals.css';
|
|
13
13
|
|
|
@@ -62,7 +62,7 @@ export default async function RootLayout({
|
|
|
62
62
|
// seeded a particular content type yet. New stores ship with default rows
|
|
63
63
|
// seeded by the backend (StoresService.seedDefaultContent).
|
|
64
64
|
const client = getServerClient(locale);
|
|
65
|
-
const [announcements, siteHeader, siteFooter, storeInfo] = await Promise.all([
|
|
65
|
+
const [announcements, siteHeader, siteFooter, storeInfo, messages] = await Promise.all([
|
|
66
66
|
client.content.announcement.list(locale).catch(() => []),
|
|
67
67
|
client.content.header.get('main', locale).catch(() => null),
|
|
68
68
|
client.content.footer.get('main', locale).catch(() => null),
|
|
@@ -70,6 +70,10 @@ export default async function RootLayout({
|
|
|
70
70
|
// render with the real currency, feature flags, and i18n config at frame 0
|
|
71
71
|
// — without this, Googlebot sees USD/defaults baked into the HTML.
|
|
72
72
|
fetchStoreInfo(locale),
|
|
73
|
+
// SSR-fetch UI message strings so translated text renders at frame 0 —
|
|
74
|
+
// without this, every page (and every locale switch) shows raw
|
|
75
|
+
// "namespace.key" strings until the client-only fetch resolves.
|
|
76
|
+
getMessages(locale),
|
|
73
77
|
]);
|
|
74
78
|
|
|
75
79
|
return (
|
|
@@ -100,7 +104,7 @@ export default async function RootLayout({
|
|
|
100
104
|
/>
|
|
101
105
|
</head>
|
|
102
106
|
<body className={font.className}>
|
|
103
|
-
<StoreProvider locale={locale} initialStoreInfo={storeInfo}>
|
|
107
|
+
<StoreProvider locale={locale} initialStoreInfo={storeInfo} initialMessages={messages}>
|
|
104
108
|
<div className="min-h-screen flex flex-col">
|
|
105
109
|
<AnnouncementBar announcements={announcements} />
|
|
106
110
|
<SiteHeader header={siteHeader} storeName={<%- storeNameJs %>} />
|
|
@@ -74,10 +74,12 @@ export function StoreProvider({
|
|
|
74
74
|
children,
|
|
75
75
|
locale,
|
|
76
76
|
initialStoreInfo = null,
|
|
77
|
+
initialMessages,
|
|
77
78
|
}: {
|
|
78
79
|
children: React.ReactNode;
|
|
79
80
|
locale?: string;
|
|
80
81
|
initialStoreInfo?: PublicStoreInfo | null;
|
|
82
|
+
initialMessages?: Record<string, Record<string, string>>;
|
|
81
83
|
}) {
|
|
82
84
|
<% } else { %>
|
|
83
85
|
export function StoreProvider({
|
|
@@ -99,7 +101,14 @@ export function StoreProvider({
|
|
|
99
101
|
const [cart, setCart] = useState<Cart | null>(null);
|
|
100
102
|
const [cartLoading, setCartLoading] = useState(true);
|
|
101
103
|
<% if (i18nEnabled) { %>
|
|
102
|
-
|
|
104
|
+
// Seed from server-rendered messages (see RootLayout) so translated text
|
|
105
|
+
// renders at frame 0 instead of a window of raw "namespace.key" strings
|
|
106
|
+
// before the client-only fetch in the effect below resolves — this also
|
|
107
|
+
// closes the same gap on every locale switch, since RootLayout re-runs
|
|
108
|
+
// server-side per locale and StoreProvider remounts with fresh initial data.
|
|
109
|
+
const [messages, setMessages] = useState<Record<string, Record<string, string>>>(
|
|
110
|
+
initialMessages ?? {}
|
|
111
|
+
);
|
|
103
112
|
<% } %>
|
|
104
113
|
|
|
105
114
|
// Check auth status via httpOnly cookie (server-side validation)
|
|
@@ -8,7 +8,7 @@ import { SiteFooter } from '@/ui/layout/site-footer';
|
|
|
8
8
|
import { CartDrawer } from '@/ui/cart/cart-drawer';
|
|
9
9
|
import { BrainerceBotWidget } from '@/components/brainerce-bot';
|
|
10
10
|
import { getServerClient, fetchStoreInfo } from '@/core/lib/brainerce';
|
|
11
|
-
import { getDirection, supportedLocales } from '@/i18n';
|
|
11
|
+
import { getDirection, getMessages, supportedLocales } from '@/i18n';
|
|
12
12
|
import { getNonce } from '@/core/lib/nonce';
|
|
13
13
|
import '../globals.css';
|
|
14
14
|
|
|
@@ -75,7 +75,7 @@ export default async function RootLayout({
|
|
|
75
75
|
// seeded a particular content type yet. New stores ship with default rows
|
|
76
76
|
// seeded by the backend (StoresService.seedDefaultContent).
|
|
77
77
|
const client = getServerClient(locale);
|
|
78
|
-
const [announcements, siteHeader, siteFooter, storeInfo] = await Promise.all([
|
|
78
|
+
const [announcements, siteHeader, siteFooter, storeInfo, messages] = await Promise.all([
|
|
79
79
|
client.content.announcement.list(locale).catch(() => []),
|
|
80
80
|
client.content.header.get('main', locale).catch(() => null),
|
|
81
81
|
client.content.footer.get('main', locale).catch(() => null),
|
|
@@ -83,6 +83,10 @@ export default async function RootLayout({
|
|
|
83
83
|
// render with the real currency, feature flags, and i18n config at frame 0
|
|
84
84
|
// — without this, Googlebot sees USD/defaults baked into the HTML.
|
|
85
85
|
fetchStoreInfo(locale),
|
|
86
|
+
// SSR-fetch UI message strings so translated text renders at frame 0 —
|
|
87
|
+
// without this, every page (and every locale switch) shows raw
|
|
88
|
+
// "namespace.key" strings until the client-only fetch resolves.
|
|
89
|
+
getMessages(locale),
|
|
86
90
|
]);
|
|
87
91
|
|
|
88
92
|
return (
|
|
@@ -113,7 +117,7 @@ export default async function RootLayout({
|
|
|
113
117
|
/>
|
|
114
118
|
</head>
|
|
115
119
|
<body className={`${sans.variable} ${serif.variable} font-sans`}>
|
|
116
|
-
<StoreProvider locale={locale} initialStoreInfo={storeInfo}>
|
|
120
|
+
<StoreProvider locale={locale} initialStoreInfo={storeInfo} initialMessages={messages}>
|
|
117
121
|
<div className="min-h-screen flex flex-col">
|
|
118
122
|
<AnnouncementBar announcements={announcements} />
|
|
119
123
|
<SiteHeader header={siteHeader} storeName={<%- storeNameJs %>} />
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
|
|
9
9
|
export type IconProps = {
|
|
10
|
-
size?: 16 | 18 | 20 | 24 | 28 | 32;
|
|
10
|
+
size?: 16 | 18 | 20 | 24 | 28 | 32 | 56;
|
|
11
11
|
className?: string;
|
|
12
12
|
/** stroke width — 1.75 default matches the light, jewelry-grade look */
|
|
13
13
|
strokeWidth?: number;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# AGENTS.md — this is a Brainerce storefront
|
|
2
|
-
|
|
3
|
-
This store's commerce engine (cart, checkout, variants, auth, i18n) is
|
|
4
|
-
already wired and working. Your job here is almost always **design**.
|
|
5
|
-
|
|
6
|
-
## The one rule
|
|
7
|
-
|
|
8
|
-
**`src/core/` is the platform's. `src/ui/` is yours.**
|
|
9
|
-
|
|
10
|
-
The shipped `src/ui/` is a working reference, not a design to preserve —
|
|
11
|
-
full delete-and-rebuild of ui files is encouraged and expected.
|
|
12
|
-
Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
|
|
13
|
-
like — the store keeps working. Never modify `src/core/`, `src/app/api/`, or
|
|
14
|
-
the checkout/auth/account components. Data and behavior come exclusively from
|
|
15
|
-
`@/core/hooks/*` and `@/core/providers/store-provider` — hooks return state
|
|
16
|
-
and handlers, never JSX. Never hardcode catalog content.
|
|
17
|
-
|
|
18
|
-
**Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
|
|
19
|
-
contracts, and hard-won RTL/i18n gotchas that will save you real debugging
|
|
20
|
-
time.
|
|
21
|
-
|
|
22
|
-
## Redesigning?
|
|
23
|
-
|
|
24
|
-
Follow the process documented in AI-GUIDE.md: commit to one art direction,
|
|
25
|
-
rewrite tokens first, then surfaces in order (header, home, card, product
|
|
26
|
-
page, cart), then verify.
|
|
27
|
-
|
|
28
|
-
## Verify before declaring done
|
|
29
|
-
|
|
30
|
-
1. `pnpm exec tsc --noEmit` → 0 errors
|
|
31
|
-
2. `pnpm dev` → drive the changed flow in a real browser (home → product →
|
|
32
|
-
add to cart → cart)
|
|
33
|
-
3. Screenshot desktop (1440px) and mobile (390px)
|
|
34
|
-
4. RTL stores: check anchoring and arrow directions
|
|
35
|
-
|
|
36
|
-
## i18n
|
|
37
|
-
|
|
38
|
-
Every user-facing string goes through `useTranslations()` with keys in **all**
|
|
39
|
-
files under `messages/`. Hebrew: no uppercase transforms, no wide
|
|
40
|
-
letter-spacing on headings, logical CSS properties only (`ms-/me-`, `ps-/pe-`,
|
|
41
|
-
`start-/end-`).
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md — this is a Brainerce storefront
|
|
2
|
-
|
|
3
|
-
This store's commerce engine (cart, checkout, variants, auth, i18n) is
|
|
4
|
-
already wired and working. Your job here is almost always **design**.
|
|
5
|
-
|
|
6
|
-
## The one rule
|
|
7
|
-
|
|
8
|
-
**`src/core/` is the platform's. `src/ui/` is yours.**
|
|
9
|
-
|
|
10
|
-
The shipped `src/ui/` is a working reference, not a design to preserve —
|
|
11
|
-
full delete-and-rebuild of ui files is encouraged and expected. (Stores
|
|
12
|
-
scaffolded with `--canvas` ship `src/ui/` as bare unstyled skeletons —
|
|
13
|
-
there is no reference look at all; the design is entirely yours to create.)
|
|
14
|
-
Rewrite anything under `src/ui/` and `src/app/globals.css` as boldly as you
|
|
15
|
-
like — the store keeps working. Never modify `src/core/`, `src/app/api/`, or
|
|
16
|
-
the checkout/auth/account components. Data and behavior come exclusively from
|
|
17
|
-
`@/core/hooks/*` and `@/core/providers/store-provider` — hooks return state
|
|
18
|
-
and handlers, never JSX. Never hardcode catalog content.
|
|
19
|
-
|
|
20
|
-
**Read `AI-GUIDE.md` before any redesign** — it has the full file map, hook
|
|
21
|
-
contracts, and hard-won RTL/i18n gotchas that will save you real debugging
|
|
22
|
-
time.
|
|
23
|
-
|
|
24
|
-
## The dialect
|
|
25
|
-
|
|
26
|
-
- `src/components/ui/` = official **shadcn/ui primitives** (Button, Card,
|
|
27
|
-
Badge, Input, Select, Accordion, Dialog, Sheet, Skeleton, …). Compose them;
|
|
28
|
-
extend looks via CVA **variants**, never repeated inline overrides.
|
|
29
|
-
- Icons: **lucide-react only** — no inline `<svg>`, no emoji-as-icons.
|
|
30
|
-
- Class merging: **`cn()`** from `@/core/lib/utils`.
|
|
31
|
-
- Colors/radius come from the semantic HSL tokens in `globals.css`
|
|
32
|
-
(`--primary`, `--card`, `--ring`, `--radius`, …) — restyle via tokens.
|
|
33
|
-
|
|
34
|
-
## Redesigning? Use the ready-made flow
|
|
35
|
-
|
|
36
|
-
Run `/design <your art-direction brief>` — it walks the whole process:
|
|
37
|
-
concept → implementation in `ui/` → verification.
|
|
38
|
-
|
|
39
|
-
## Verify before declaring done
|
|
40
|
-
|
|
41
|
-
1. `pnpm exec tsc --noEmit` → 0 errors
|
|
42
|
-
2. `pnpm dev` → drive the changed flow in a real browser (home → product →
|
|
43
|
-
add to cart → cart)
|
|
44
|
-
3. Screenshot desktop (1440px) and mobile (390px)
|
|
45
|
-
4. RTL stores: check anchoring and arrow directions
|
|
46
|
-
|
|
47
|
-
## i18n
|
|
48
|
-
|
|
49
|
-
Every user-facing string goes through `useTranslations()` with keys in **all**
|
|
50
|
-
files under `messages/`. Hebrew: no uppercase transforms, no wide
|
|
51
|
-
letter-spacing on headings, logical CSS properties only (`ms-/me-`, `ps-/pe-`,
|
|
52
|
-
`start-/end-`).
|