veza/apps/web/docs/BRANDING.md
senke 33fcd7d1bd feat(branding): scaffold Logo component + Sumi icons + brand assets pipeline (Sprint 3)
Sprint 3 = production assets (logo, icons, hero, textures). Most deliverables
are physical artistic work (artist Renaud + Nikola scans). This commit lays
the CODE scaffold so assets drop in without friction when delivered.

New : apps/web/src/components/branding/
- Logo.tsx — single source of truth for Talas / Veza brand rendering.
  Replaces ad-hoc inline wordmarks (Sidebar/Navbar/Footer/landing each had
  their own VEZA <h2>). Variants: wordmark / symbol / lockup. Sizes xs..xl.
  Colors auto/ink/cyan/inverse. Optional tagline. Horizontal/vertical orient.
- assets/SymbolPlaceholder.tsx — geometric ink stroke + arc + dot, monochrome,
  currentColor inheritance, scalable. Mirrors charte §3.1 brief. Replaced by
  artist's hand-drawn mark in P0.1 of BRIEF_ARTISTE.
- Logo.stories.tsx — full Storybook coverage: variants, sizes, colors,
  orientation, Talas vs Veza, all-sizes ladder.
- index.ts — barrel exports.

New : apps/web/src/components/icons/sumi/
- Play.tsx — first calligraphic icon stub (programmatic approximation per
  charte §6.3). 9 more to come (Pause, Search, Profile, Chat, Upload,
  Settings, Home, Close, Volume).
- index.ts — barrel + commented TODO list per priority.
- Used via existing components/icons/SumiIcon.tsx wrapper which falls back to
  Lucide when no Sumi version exists.

Brand alignment of platform metadata :
- public/favicon.svg — Mizu cyan placeholder (#0098B5) replacing default
  vite.svg. Mirrors SymbolPlaceholder geometry.
- public/manifest.json — theme_color #1a1a1a -> #0098B5 (SUMI accent),
  background_color #ffffff -> #0D0D0F (charte §4.4 rule 1: no pure white).
- index.html — theme-color meta + msapplication-TileColor aligned to SUMI.
  Favicon link points to /favicon.svg.

New doc : apps/web/docs/BRANDING.md
- Architecture map of brand assets in apps/web.
- Logo component API + usage examples.
- Asset deliverables status table (P0/P1/P2 from brief artiste, all 🟡 placeholders).
- Naming convention for raw scans + processed SVGs.
- Step-by-step "how to integrate a delivered asset" for wordmark and Sumi icon.
- Brand color guard (ESLint rule pointer).

Build OK (vite 12.6s). Typecheck clean. No visual regression — Sidebar/Navbar
inline wordmarks intentionally NOT migrated yet (they use fontWeight 300 which
contradicts charte's Bold requirement; a per-screen migration call later).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:08:17 +02:00

149 lines
6.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.

# Branding & assets pipeline — apps/web
Single source of truth for how Talas / Veza brand assets enter the codebase.
Reference brand spec : [`CHARTE_GRAPHIQUE_TALAS.md`](../../../../Documents/TG__Talas_Group/05_EXPERIENCE_UTILISATEUR/CHARTE_GRAPHIQUE_TALAS.md).
---
## Architecture
```
apps/web/
├── public/
│ ├── favicon.svg # SVG favicon (Mizu cyan placeholder)
│ ├── icons/ # PWA icons (PNG, 72x72 to 512x512)
│ ├── fonts/ # Self-hosted woff2 (Space Grotesk, Inter, JetBrains Mono)
│ └── manifest.json # PWA manifest (theme_color = #0098B5 SUMI accent)
└── src/
├── components/
│ ├── branding/
│ │ ├── Logo.tsx # SOLE entry point for Talas / Veza wordmark + symbol
│ │ ├── Logo.stories.tsx
│ │ ├── assets/
│ │ │ ├── SymbolPlaceholder.tsx # Geometric placeholder, swap for hand-drawn
│ │ │ ├── TalasWordmark.tsx # (P0.1 artist deliverable — 3 variants)
│ │ │ └── VezaWordmark.tsx # (P1.1 artist deliverable — 1 variant)
│ │ └── index.ts
│ └── icons/
│ ├── SumiIcon.tsx # Wrapper : prefers hand-drawn, falls back to Lucide
│ └── sumi/ # Hand-drawn calligraphic icons (10 prioritaires)
│ ├── Play.tsx
│ ├── Pause.tsx (TODO)
│ └── ...
```
---
## Logo component
**Always use `<Logo />`** instead of inline `<h2>VEZA</h2>` style markup.
```tsx
import { Logo } from '@/components/branding';
// Default (wordmark, md, theme-aware color)
<Logo brand="veza" />
// Lockup with tagline
<Logo brand="veza" variant="lockup" size="lg" tagline="STREAMING" />
// Symbol only (favicon-style usage)
<Logo brand="talas" variant="symbol" size="sm" />
// Cyan accent
<Logo brand="veza" variant="lockup" color="cyan" />
```
API : see [Logo.stories.tsx](../src/components/branding/Logo.stories.tsx) for all variants in Storybook.
---
## Asset deliverables — current status
Per `BRIEF_ARTISTE_IDENTITE_VISUELLE.md` (artist Renaud, 15 avril 2026) and Sprint 3 :
| Asset | Priority | Status | Location |
|-------|----------|--------|----------|
| TALAS wordmark × 3 (propre, sauvage, vertical) | P0.1 | ⏳ awaiting artist | `branding/assets/TalasWordmark.tsx` (pending) |
| Hero image post-apo | P0.2 | ⏳ awaiting artist | `public/hero/` (pending) |
| VEZA wordmark × 1 (tag fluide) | P1.1 | ⏳ awaiting artist | `branding/assets/VezaWordmark.tsx` (pending) |
| 3-5 textures de liaison | P1.2 | ⏳ awaiting artist | `public/textures/` (pending) |
| 3 symboles iconiques (enso, onde, libre) | P1.3 | ⏳ awaiting artist | `branding/assets/Symbol.tsx` (pending) |
| Talas symbole (calligraphique) | — | 🟡 placeholder | `branding/assets/SymbolPlaceholder.tsx` |
| Favicon SVG | — | 🟡 placeholder | `public/favicon.svg` |
| 10 Sumi icons (play/pause/search/...) | — | 🟡 1/10 stubbed | `components/icons/sumi/` |
| washi.png texture | — | ✅ inline SVG (feTurbulence) | `src/index.css:456` (no external file) |
| Fonts (Space Grotesk + Inter + JetBrains Mono) | — | ✅ self-hosted | `public/fonts/*.woff2` |
| PWA icons (PNG, 9 sizes) | — | 🟡 generic placeholders | `public/icons/icon-*.png` |
### Naming convention
- Wordmarks : `{brand}_wordmark_{variant}.svg` then exported as React component
- Example : `talas_wordmark_propre.svg``TalasWordmarkPropre.tsx`
- Symbols : `{brand}_symbol_{type}.svg`
- Hero / textures : `{kind}_{number}.png` (raw scans), processed to `webp` for prod
- Always store source SVGs (vectorized) ; processed bitmaps in build
### Format requirements (per BRIEF_ARTISTE §5)
- **Scan minimum 600 DPI** (1200 if available). PNG/TIFF only — no JPG (bleeding edges on ink).
- **One artwork per file**. Naming : `talas_wordmark_sauvage_01.png` etc.
- **No retouching** before delivery — clean fond, niveaux, détourage handled in apps/web preprocessing.
- **Paper white** (not cream) ; **encre de Chine** (not brown-tinted black) ; aquarelle limited to terreuse palette.
---
## How to integrate a delivered asset
### Wordmark (e.g. TALAS propre)
1. Receive `talas_wordmark_propre_01.png` (scan 600+ DPI).
2. Clean fond + isolate ink in Inkscape : `File → Import → Select-by-color (white) → Delete → Trace bitmap`.
3. Export SVG with `currentColor` fills + transparent background.
4. Save as `apps/web/src/components/branding/assets/TalasWordmark.tsx` :
```tsx
import type { SVGProps } from 'react';
export default function TalasWordmark(props: SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg" {...props}>
{/* Pasted SVG paths here, fills set to currentColor */}
</svg>
);
}
```
5. Update `Logo.tsx` to use `<TalasWordmark />` for `brand='talas'` instead of the
text fallback. (Detect via prop or via fallback chain.)
6. Storybook will show it automatically.
### Sumi icon (e.g. Pause)
1. Receive `pause_01.png` from artist.
2. Vectorize manually in Inkscape (no auto-trace — preserves irregularity).
3. Save as `apps/web/src/components/icons/sumi/Pause.tsx`.
4. Add export to `components/icons/sumi/index.ts`.
5. At call site :
```tsx
import { SumiIcon } from '@/components/icons/SumiIcon';
import { PauseIcon } from '@/components/icons/sumi';
import { Pause } from 'lucide-react';
<SumiIcon sumi={PauseIcon} fallback={Pause} size={24} />
```
The `SumiIcon` wrapper handles the "use hand-drawn if available, else Lucide
fallback" logic, so you can drop hand-drawn icons in progressively.
---
## Brand color guard
ESLint rule (`eslint.config.js` `no-restricted-syntax` for hex literals) blocks
new hardcoded colors. To fix a warning :
- CSS context (JSX style/className/template literal) : use `var(--sumi-*)`.
- TS / canvas context : `import { ColorVizIndigo } from '@veza/design-system/tokens-generated';`.
Source of truth for all colors : `packages/design-system/tokens/primitive/color.json`.