# VMall frontend conventions (READ FIRST — applies to every app agent) Repo: /Users/chengdzhang/github/jamyun/vmall (pnpm workspace). The Rust API is COMPLETE and tested; do not touch apps/api, packages/shared, openspec, or any app other than yours. ## Your app - Nuxt 3 + pinia + @nuxtjs/i18n. Deps installed. Verify with `pnpm --filter @vmall/ build` at the end (MUST pass). Do not run dev servers, do not run other apps' builds, do not run cargo. - The API may not be running while you work — code against the contract, prove with `nuxt build` (type safety + compile). NEVER mock the API. ## Contract (packages/shared/src) - `useNuxtApp().$api` is a typed `ApiClient` (see packages/shared/src/api.ts for every method + request body types). Provided by plugins/api.ts (already wired, reads baseUrl from runtimeConfig public.apiBase, token from localStorage `vmall.token`). - Types in packages/shared/src/types.ts (User, Product, Sku, Cart, Order, Shipment, Invoice, Currency, Paged, etc.). Money = integer minor units + ISO currency code. - `t(localizedText, locale)` picks the display string from a JSONB {"en","zh"} map. `formatMoney(amountMinor, currency, exponent, locale)` formats minor units. - All UI strings via $t with keys from @vmall/shared/locales (en + zh exist). If you need a key that doesn't exist, add it to YOUR app's locales-extra.ts (enExtra/zhExtra, same nested shape) — NEVER edit packages/shared. - Shared stylesheet `@vmall/shared/ui.css` is loaded: use its classes (.card, .btn .primary .sm .danger, .table, .badge .green/.blue/.orange/.red, .field, .grid.products, .product-card, .page-title, .page-head, .form-narrow, .muted, .row, .between, .mt, .mb, .error-text). Add app-scoped CSS only in a