Files
mercadodevida/project/specs/brand-migration/DESIGN.md
2026-08-17 22:23:10 +02:00

243 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 57 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()}`