feat(ADM-018): completed feature
This commit is contained in:
242
project/specs/brand-migration/DESIGN.md
Normal file
242
project/specs/brand-migration/DESIGN.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# BRAND MIGRATION — DESIGN.md
|
||||
|
||||
## 1. Design Token Strategy
|
||||
|
||||
### 1.1 Current State
|
||||
|
||||
Both `frontend/src/app/globals.css` and `apps/admin/src/app/globals.css` use Tailwind `@theme` block:
|
||||
|
||||
```css
|
||||
@theme {
|
||||
--color-primary: #2D6A4F;
|
||||
--color-primary-dark: #1B4332;
|
||||
--color-primary-light: #40916C;
|
||||
--color-secondary: #F5F0E8;
|
||||
--color-accent: #E76F51;
|
||||
--color-text: #111827;
|
||||
--color-muted: #6B7280;
|
||||
--font-sans: "Inter", system-ui, sans-serif;
|
||||
--font-heading: "Playfair Display", Georgia, serif;
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 Decision Required
|
||||
|
||||
**Extract legacy CSS first** (see BRAND_INVENTORY.md). If legacy colors differ from current tokens, update the `@theme` block. If they match (green primary, terracotta accent), no change needed.
|
||||
|
||||
### 1.3 Token Architecture
|
||||
|
||||
```
|
||||
globals.css @theme
|
||||
│
|
||||
├── Tailwind utility classes auto-generate from @theme
|
||||
│ text-primary, bg-primary, border-primary, etc.
|
||||
│
|
||||
└── All components reference tokens, never raw hex values
|
||||
✅ text-[var(--color-primary)] / bg-[var(--color-accent)]
|
||||
❌ text-[#2D6A4F] scattered in JSX
|
||||
```
|
||||
|
||||
If any component uses a raw hex value matching a brand color, refactor to use the token.
|
||||
|
||||
## 2. Business Configuration
|
||||
|
||||
### 2.1 Single Source of Truth
|
||||
|
||||
Create `frontend/src/lib/businessConfig.ts`:
|
||||
|
||||
```typescript
|
||||
export const BUSINESS_CONFIG = {
|
||||
name: 'Natural - Mercado de Vida',
|
||||
shortName: 'MercadoDeVida',
|
||||
founders: 'Ivana & Ricardo',
|
||||
address: {
|
||||
street: 'Av. Litoral - Edif. Vistamar II - Local 18',
|
||||
postalCode: '29680',
|
||||
city: 'Estepona',
|
||||
province: 'Málaga',
|
||||
country: 'España',
|
||||
},
|
||||
phone: '+34 951 338 132',
|
||||
whatsapp: '+34 676 014 074',
|
||||
email: 'info@mercadodevida.es',
|
||||
hours: {
|
||||
weekdays: '10:00 – 18:00',
|
||||
saturday: '10:00 – 14:00',
|
||||
},
|
||||
social: {
|
||||
instagram: null, // TODO: extract from legacy site
|
||||
facebook: null, // TODO: extract from legacy site
|
||||
},
|
||||
website: 'https://mercadodevida.es',
|
||||
} as const;
|
||||
|
||||
export type BusinessConfig = typeof BUSINESS_CONFIG;
|
||||
```
|
||||
|
||||
### 2.2 Usage Points
|
||||
|
||||
```typescript
|
||||
import { BUSINESS_CONFIG } from '@/lib/businessConfig';
|
||||
|
||||
// Footer
|
||||
<span>{BUSINESS_CONFIG.name}</span>
|
||||
<span>{BUSINESS_CONFIG.address.city}</span>
|
||||
|
||||
// Contact page
|
||||
<a href={`tel:${BUSINESS_CONFIG.phone}`}>{BUSINESS_CONFIG.phone}</a>
|
||||
<a href={`mailto:${BUSINESS_CONFIG.email}`}>{BUSINESS_CONFIG.email}</a>
|
||||
|
||||
// About page
|
||||
<p>Somos {BUSINESS_CONFIG.founders}...</p>
|
||||
|
||||
// Checkout confirmation
|
||||
<p>{BUSINESS_CONFIG.address.street}, {BUSINESS_CONFIG.address.postalCode} {BUSINESS_CONFIG.address.city}</p>
|
||||
```
|
||||
|
||||
Do NOT duplicate any of these values anywhere else.
|
||||
|
||||
## 3. Logo
|
||||
|
||||
### 3.1 Source Asset
|
||||
|
||||
Download from legacy site. See BRAND_INVENTORY.md.
|
||||
|
||||
### 3.2 Placement
|
||||
|
||||
```
|
||||
Storefront Header
|
||||
└── Logo → /public/images/logo.svg (or .png)
|
||||
└── Also used in Admin sidebar
|
||||
|
||||
Storefront Footer
|
||||
└── Logo (same asset)
|
||||
|
||||
Favicon
|
||||
└── /public/favicon.ico
|
||||
└── Also /public/apple-touch-icon.png
|
||||
```
|
||||
|
||||
### 3.3 Next.js Metadata
|
||||
|
||||
In `frontend/src/app/layout.tsx`:
|
||||
```typescript
|
||||
import { BUSINESS_CONFIG } from '@/lib/businessConfig';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: { default: BUSINESS_CONFIG.name, template: `%s | ${BUSINESS_CONFIG.name}` },
|
||||
metadataBase: new URL(BUSINESS_CONFIG.website),
|
||||
};
|
||||
```
|
||||
|
||||
## 4. Static Pages Content
|
||||
|
||||
### 4.1 Architecture Decision
|
||||
|
||||
For 5–7 informational pages, typed static React components are acceptable.
|
||||
|
||||
The existing `ContentPage` component (`frontend/src/components/content/ContentPage.tsx`) should be evaluated:
|
||||
- Does it support all needed HTML elements (tables, lists, headings, blockquotes)?
|
||||
- Does it support linking to business config data?
|
||||
|
||||
If rich layout is needed for complex pages (e.g., terms with sections), consider:
|
||||
- Markdown/MDX files processed at build time
|
||||
- Single `ContentPage` component that renders parsed markdown
|
||||
|
||||
### 4.2 Page Content Plan
|
||||
|
||||
| Page | Route | Source | Status |
|
||||
|------|-------|--------|--------|
|
||||
| About | /about | /quienes-somos (migrated) | See BRAND_INVENTORY.md |
|
||||
| Contact | /contact | /contacto (partial) | Needs form + hours |
|
||||
| Shipping | /shipping | New + legacy /envios-y-formas-de-pago (404) | Create from scratch |
|
||||
| Terms | /terms | /terminos-y-condiciones (migrated) | Needs legal review |
|
||||
| Privacy | /privacy | New (legacy 404) | Create from scratch |
|
||||
| Cookies | /cookies | New (legacy 404) | Create from scratch |
|
||||
| Legal | /legal | New (no legacy) | Create if needed |
|
||||
|
||||
### 4.3 Legal Content Flag
|
||||
|
||||
All legal pages (Terms, Privacy, Cookies) must be flagged:
|
||||
```
|
||||
⚠️ MIGRATED LEGAL CONTENT — REQUIRES HUMAN REVIEW BEFORE PUBLISHING
|
||||
```
|
||||
|
||||
Do not mark migrated legal text as newly legally approved.
|
||||
|
||||
## 5. SEO Redirects
|
||||
|
||||
### 5.1 Implementation
|
||||
|
||||
In `frontend/next.config.ts`:
|
||||
|
||||
```typescript
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
async redirects() {
|
||||
return [
|
||||
// Static pages
|
||||
{ source: '/quienes-somos', destination: '/about', permanent: true },
|
||||
{ source: '/contacto', destination: '/contact', permanent: true },
|
||||
{ source: '/terminos-y-condiciones', destination: '/terms', permanent: true },
|
||||
{ source: '/politica-de-cookies', destination: '/cookies', permanent: true },
|
||||
{ source: '/politica-de-privacidad', destination: '/privacy', permanent: true },
|
||||
{ source: '/donde-estamos', destination: '/contact', permanent: true },
|
||||
{ source: '/aviso-legal', destination: '/legal', permanent: true },
|
||||
|
||||
// OpenCart internals — block
|
||||
{ source: '/admin/:path*', destination: '/404', permanent: false },
|
||||
|
||||
// Catch-all for OpenCart query strings — these should not reach the app
|
||||
{ source: '/:path*', has: [{ type: 'query', key: 'route' }], destination: '/404', permanent: false },
|
||||
];
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 5.2 Category Redirects
|
||||
|
||||
Complete the redirect map from LEGACY_REDIRECT_MAP.md before implementing.
|
||||
|
||||
### 5.3 Product Redirects
|
||||
|
||||
Evaluate Option A vs Option B from LEGACY_REDIRECT_MAP.md before implementing.
|
||||
|
||||
## 6. Admin Branding
|
||||
|
||||
### 6.1 Logo
|
||||
|
||||
Use the same logo file as storefront. Simplified/smaller version acceptable.
|
||||
|
||||
In `apps/admin/src/app/(dashboard)/layout.tsx`, the sidebar currently shows an inline SVG. Replace with the actual logo image.
|
||||
|
||||
### 6.2 Token Alignment
|
||||
|
||||
Admin should use the same `--color-primary` token as storefront. Verify the admin `globals.css` tokens match storefront. Currently they do (both use `#2D6A4F`).
|
||||
|
||||
### 6.3 NOT Changed
|
||||
|
||||
- Admin table styling (operational, not brand-focused)
|
||||
- Admin form components
|
||||
- Admin typography (keep Inter for data-dense UIs)
|
||||
|
||||
## 7. Header Component
|
||||
|
||||
Review `frontend/src/components/layout/Header.tsx`:
|
||||
|
||||
- Logo: use `BUSINESS_CONFIG.shortName` for text fallback
|
||||
- Nav links: About, Contact, Categories, etc.
|
||||
- Ensure no hardcoded company name/address
|
||||
|
||||
## 8. Footer Component
|
||||
|
||||
Review `frontend/src/components/layout/Footer.tsx`:
|
||||
|
||||
- Use `BUSINESS_CONFIG.name` for brand name
|
||||
- Use `BUSINESS_CONFIG.address` for address
|
||||
- Use `BUSINESS_CONFIG.phone`, `BUSINESS_CONFIG.email`
|
||||
- Use `BUSINESS_CONFIG.hours`
|
||||
- Social links from `BUSINESS_CONFIG.social`
|
||||
- Legal links: Terms, Privacy, Cookies
|
||||
- Copyright year dynamic: `{new Date().getFullYear()}`
|
||||
Reference in New Issue
Block a user