# 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 ``** instead of inline `

VEZA

` style markup. ```tsx import { Logo } from '@/components/branding'; // Default (wordmark, md, theme-aware color) // Lockup with tagline // Symbol only (favicon-style usage) // Cyan accent ``` 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) { return ( {/* Pasted SVG paths here, fills set to currentColor */} ); } ``` 5. Update `Logo.tsx` to use `` 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'; ``` 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`.