Branding Structure Upgrade
Section titled “Branding Structure Upgrade”Upgrade Implementation Plan (v3)
Overview
Section titled “Overview”Implement the formal brand system architecture where brands are infrastructure (owned at monorepo level) and sites are consumers. Logos are created as semantic, theme-agnostic SVG files using currentColor and semantic classes. Brand-specific colors are applied via CSS variables in wrapper components.
KEY UPDATE (v3): The S ↔ $D animation applies to ALL SD logo variants (circle, leaf-dot, leaf-square, leaf-rect), not just the circle variant. Every SD SVG must contain S, $, and D character paths.
Key Architecture Principles
Section titled “Key Architecture Principles”-
Brands are infrastructure - Live at monorepo root, not in sites
-
Logos are semantic - Use
currentColorwith semantic classes (.logo-bg,.logo-primary,.logo-secondary) -
Colors are external - Applied via brand-specific CSS variables in wrapper components
-
Animation for ALL SD variants - Every SD logo (all backgrounds) supports S ↔ $D animation
-
Template demonstrates - Never owns or defines brand assets
Logo Animation Architecture
Section titled “Logo Animation Architecture”Universal Animation Support
Section titled “Universal Animation Support”ALL SmartDebt logo variants must support the S ↔ $D animation:
sd-circle.svg- Animated ✓sd-leaf-dot.svg- Animated ✓sd-leaf-square.svg- Animated ✓sd-leaf-rect.svg- Animated ✓
Why: User wants animation available for every background variation. The background shape changes between variants, but the character structure (S, $, D) remains identical.
SVG Structure for Animation
Section titled “SVG Structure for Animation”Every SD logo SVG must contain:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <!-- Background varies: circle, leaf, square, rect --> <path class="logo-bg" d="..." fill="currentColor"/> <!-- Characters are IDENTICAL across all variants --> <path class="logo-primary logo-s" d="..." fill="currentColor"/> <path class="logo-primary logo-dollar" d="..." fill="currentColor"/> <path class="logo-primary logo-d" d="..." fill="currentColor"/> <!-- Optional secondary accent (varies by type) --> <path class="logo-secondary" d="..." fill="currentColor"/> </svg>
Inkscape workflow: Create the S, $, D character paths once, then copy them identically into all four background variations. Only the background shape and optional accents change.
Current State vs Target State
Section titled “Current State vs Target State”Current Problems
Section titled “Current Problems”-
Logo defined inline in
BrandLogo.astrocomponent (no asset files) -
Existing logo SVGs have hardcoded colors and wrong viewBox (256x256)
-
Color system at Template level
-
No formal brand separation (SD vs TS)
-
No brand contract
Target Architecture
Section titled “Target Architecture”provides baseprovides baseimportsMonorepo RootBrand Layersrc/brand/sd/SmartDebt Brandts/TalbotStevens Brandlogos/svg-paths-base/sd-circle.svgsd-leaf-dot.svgsd-leaf-square.svgsd-leaf-rect.svgALL with S,$,D pathscolors.oklch.jsonBrand palettestokens.cssGenerated CSSindex.tsBrand Contractlogos/svg-paths-base/ts-circle.svgcolors.oklch.jsontokens.cssindex.tsShared Tokenssrc/design-tokens/stone, gray palettesTemplate SiteDemonstrates all SD variantswith animation
Logo Color System Explained
Section titled “Logo Color System Explained”SVG Structure (Semantic & Theme-Agnostic)
Section titled “SVG Structure (Semantic & Theme-Agnostic)”Each SVG file contains paths with semantic classes and currentColor:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"> <!-- Background shape (circle, leaf, square, etc.) --> <path class="logo-bg" d="..." fill="currentColor"/> <!-- Primary marks (S, D characters) --> <path class="logo-primary logo-s" d="..." fill="currentColor"/> <path class="logo-primary logo-d" d="..." fill="currentColor"/> <!-- Dollar sign for animation (all SD variants) --> <path class="logo-primary logo-dollar" d="..." fill="currentColor"/> <!-- Secondary accent (leaf, dot, highlights) --> <path class="logo-secondary" d="..." fill="currentColor"/> </svg>
Key principles:
-
NO hardcoded colors
-
NO brand-specific names in SVG
-
NO CSS inside SVG
-
Uses
currentColorto inherit from wrapper -
Semantic classes describe role, not brand
Component Wrapper (Applies Brand Colors)
Section titled “Component Wrapper (Applies Brand Colors)”The wrapper component maps brand tokens to semantic classes:
/* SD brand wrapper */ .sd-logo { /* Base color for .logo-bg and .logo-primary */ color: var(--sd-logo-primary); /* Secondary color as CSS variable */ --logo-secondary-color: var(--sd-logo-secondary); } /* Target secondary elements */ .sd-logo .logo-secondary { color: var(--logo-secondary-color); }
Brand Tokens (Define Actual Colors)
Section titled “Brand Tokens (Define Actual Colors)”Design tokens define brand-specific colors that adapt to theme:
/* Light theme */ [data-theme="light"] { --sd-logo-primary: hsl(var(--primary-8)); /* Treasury Emerald */ --sd-logo-secondary: hsl(var(--secondary-7)); /* Wealth Gold */ } /* Dark theme */ [data-theme="dark"] { --sd-logo-primary: hsl(var(--primary-2)); /* Light tint */ --sd-logo-secondary: hsl(var(--secondary-3)); }
Result: Same SVG works for all themes, all brands, infinite color variations.
Implementation Phases
Section titled “Implementation Phases”Phase 1: Create Brand Infrastructure
Section titled “Phase 1: Create Brand Infrastructure”1.1 Create Brand Directory Structure
Section titled “1.1 Create Brand Directory Structure”Create the following directories:
src/ brand/ sd/ logos/ svg-paths-base/ (logo SVG files go here) favicons/ ts/ logos/ svg-paths-base/ (logo SVG files go here) favicons/ design-tokens/ (shared tokens move here)
1.2 Move Shared Design Tokens
Section titled “1.2 Move Shared Design Tokens”Move shared color palettes (stone, gray) from sites/Template/src/design-tokens/ to src/design-tokens/:
-
Create
src/design-tokens/colors.oklch.jsonwith only stone and gray palettes -
These become shared infrastructure, not Template-owned
-
Generator script will merge these with brand-specific colors
Phase 2: Create Logo SVG Files (Inkscape → SVG)
Section titled “Phase 2: Create Logo SVG Files (Inkscape → SVG)”2.1 Inkscape Workflow
Section titled “2.1 Inkscape Workflow”For each logo variant, in Inkscape:
- Design with visual distinction:
-
Primary shapes (characters, main elements) → black fill
-
Secondary shapes (accents, highlights) → mid-gray fill
-
Background shapes → light gray fill
-
Convert all text and objects to paths
-
Set document to 100×100 units
-
Normalize viewBox to
viewBox="0 0 100 100" -
Export as Plain SVG
2.2 Post-Export SVG Editing
Section titled “2.2 Post-Export SVG Editing”For each exported SVG, manually edit to apply semantic structure:
Before (Inkscape output):
<path d="..." fill="#000000"/> <path d="..." fill="#808080"/> <circle cx="50" cy="50" r="50" fill="#cccccc"/>
After (semantic version):
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"> <circle class="logo-bg" cx="50" cy="50" r="50" fill="currentColor"/> <path class="logo-primary logo-s" d="..." fill="currentColor"/> <path class="logo-primary logo-dollar" d="..." fill="currentColor"/> <path class="logo-primary logo-d" d="..." fill="currentColor"/> <path class="logo-secondary" d="..." fill="currentColor"/> </svg>
2.3 Create SD Logo Variants
Section titled “2.3 Create SD Logo Variants”Create these files in src/brand/sd/logos/svg-paths-base/:
-
sd-circle.svg - SD logo with circular background
-
sd-leaf-dot.svg - SD logo with leaf shape and dot accent
-
sd-leaf-square.svg - SD logo with leaf shape and square background
-
sd-leaf-rect.svg - SD logo with leaf shape and rectangular background
CRITICAL: Animation Support for ALL SD Variants
Every SD logo variant must contain ALL three character paths (S, $, D) to support the S ↔ $D animation:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <!-- Background shape (varies by variant: circle, leaf, square, rect) --> <path class="logo-bg" d="..." fill="currentColor"/> <!-- OR --> <circle class="logo-bg" cx="50" cy="50" r="50" fill="currentColor"/> <!-- Base S character (visible by default, opacity animated) --> <path class="logo-primary logo-s" d="..." fill="currentColor"/> <!-- Dollar sign (hidden by default, fades in/out for animation) --> <path class="logo-primary logo-dollar" d="..." fill="currentColor"/> <!-- D character (always visible) --> <path class="logo-primary logo-d" d="..." fill="currentColor"/> <!-- Optional: Secondary accent (dot, highlight, etc.) --> <path class="logo-secondary" d="..." fill="currentColor"/> </svg>
Why all variants need all three characters:
-
User wants S ↔ $D animation available for every background variation
-
Each logo type (circle, leaf-dot, etc.) must be animation-ready
-
Component decides whether to activate animation via
animateprop -
Background shape changes, but character structure stays consistent
Design implication: When creating variants in Inkscape, the S, $, D character paths should be copied identically across all four background variations. Only the background shape and optional secondary accents change between variants.
2.4 Create TS Logo Variant
Section titled “2.4 Create TS Logo Variant”Create in src/brand/ts/logos/svg-paths-base/:
- ts-circle.svg - TS logo with circular background
-
Circle background:
.logo-bg -
T character:
.logo-primary -
S character:
.logo-primary -
No animation needed (TS doesn’t have dollar variant)
2.5 Clean Up Old Logo Files
Section titled “2.5 Clean Up Old Logo Files”Delete obsolete files in src/assets/brand/logos/:
-
logo_$D-paths.svg -
logo_$D-text.svg -
logo_SD-paths.svg -
logo_SD-text.svg -
logo_TS-paths.svg -
logo_TS-text.svg
Phase 3: Design Token Restructure
Section titled “Phase 3: Design Token Restructure”3.1 Create Shared Token File
Section titled “3.1 Create Shared Token File”Create src/design-tokens/colors.oklch.json:
{ "meta": { "name": "Shared Design Tokens", "version": "1.0.0", "description": "Neutral palettes shared across all brands" }, "palettes": { "stone": { "name": "Warm Stone", "anchor": "#4E4640", "anchorPosition": 7, "semanticMappings": { /* ... */ } }, "gray": { "name": "Pure Gray", "anchor": "#484848", "anchorPosition": 7, "semanticMappings": { /* ... */ } } } }
3.2 Create SD Color File
Section titled “3.2 Create SD Color File”Create src/brand/sd/colors.oklch.json:
{ "meta": { "name": "SmartDebt", "version": "1.0.0", "brandId": "sd", "inkscapePaletteName": "SmartDebt" }, "palettes": { "primary": { "name": "Treasury Emerald", "anchor": "#004425", "anchorPosition": 8, "semanticMappings": { "8": ["light:primary", "dark:primary"], "2": ["light:logo-primary-on-dark"], "8": ["dark:logo-primary-on-light"] } }, "secondary": { "name": "Wealth Gold", "anchor": "#D5B038", "anchorPosition": 7, "semanticMappings": { "7": ["light:secondary"], "3": ["light:logo-secondary-on-dark"] } }, "tertiary": { "name": "Financial Red", "anchor": "#DD2729", "anchorPosition": 6, "semanticMappings": { /* ... */ } } } }
3.3 Create TS Color File
Section titled “3.3 Create TS Color File”Create src/brand/ts/colors.oklch.json:
{ "meta": { "name": "TalbotStevens", "version": "1.0.0", "brandId": "ts" }, "palettes": { "primary": { "name": "Professional Blue", "anchor": "#0053B3", "anchorPosition": 8, "semanticMappings": { "8": ["light:primary", "dark:primary"] } } // Inherits secondary/tertiary from SmartDebt or defines own } }
3.4 Update Color Generation Script
Section titled “3.4 Update Color Generation Script”Modify sites/Template/scripts/generate-color-system.mjs:
Add brand flag support:
// Parse command line args const brandFlag = process.argv.indexOf('--brand'); const brand = brandFlag > -1 ? process.argv[brandFlag + 1] : 'sd'; // Read brand-specific colors const brandColorPath = resolve(ROOT, '..', '..', 'src', 'brand', brand, 'colors.oklch.json'); const sharedColorPath = resolve(ROOT, '..', '..', 'src', 'design-tokens', 'colors.oklch.json'); const brandColors = JSON.parse(readFileSync(brandColorPath, 'utf-8')); const sharedColors = JSON.parse(readFileSync(sharedColorPath, 'utf-8')); // Merge: brand colors override shared const colorConfig = { meta: brandColors.meta, palettes: { ...sharedColors.palettes, ...brandColors.palettes } };
Output to brand folder:
const outputPaths = { tokensCSS: resolve(ROOT, '..', '..', 'src', 'brand', brand, 'tokens.css'), // Keep theme files at Template level for now baseCSS: resolve(ROOT, 'src', 'styles', 'themes', 'base.css'), // ... };
Update package.json scripts:
{ "scripts": { "colors": "node ./scripts/generate-color-system.mjs --brand sd", "colors:sd": "node ./scripts/generate-color-system.mjs --brand sd", "colors:ts": "node ./scripts/generate-color-system.mjs --brand ts" } }
3.5 Generate Initial Brand Tokens
Section titled “3.5 Generate Initial Brand Tokens”Run the generator for both brands:
pnpm run colors:sd pnpm run colors:ts
This creates:
src/brand/sd/tokens.csssrc/brand/ts/tokens.css
Phase 4: Create Brand Contracts
Section titled “Phase 4: Create Brand Contracts”4.1 Create SD Brand Contract
Section titled “4.1 Create SD Brand Contract”Create src/brand/sd/index.ts:
export const brand = { id: 'sd', name: 'SMART DEBT', displayName: 'SmartDebt', // Lazy-loaded tokens tokens: () => import('./tokens.css'), // Logo variants (all support S ↔ $D animation) logos: { circle: () => import('./logos/svg-paths-base/sd-circle.svg?raw'), leafDot: () => import('./logos/svg-paths-base/sd-leaf-dot.svg?raw'), leafSquare: () => import('./logos/svg-paths-base/sd-leaf-square.svg?raw'), leafRect: () => import('./logos/svg-paths-base/sd-leaf-rect.svg?raw'), }, // Color anchors (for reference/documentation) colors: { primary: '#004425', // Treasury Emerald secondary: '#D5B038', // Wealth Gold tertiary: '#DD2729', // Financial Red }, // Logo CSS variable mappings logoVars: { light: { primary: 'var(--primary-8)', secondary: 'var(--secondary-7)', }, dark: { primary: 'var(--primary-2)', secondary: 'var(--secondary-3)', }, }, } as const; export type Brand = typeof brand;
4.2 Create TS Brand Contract
Section titled “4.2 Create TS Brand Contract”Create src/brand/ts/index.ts:
export const brand = { id: 'ts', name: 'Talbot Stevens', displayName: 'TalbotStevens', tokens: () => import('./tokens.css'), logos: { circle: () => import('./logos/svg-paths-base/ts-circle.svg?raw'), }, colors: { primary: '#0053B3', // Professional Blue secondary: '#D5B038', // Inherited Wealth Gold }, logoVars: { light: { primary: 'var(--primary-8)', secondary: 'var(--secondary-7)', }, dark: { primary: 'var(--primary-2)', secondary: 'var(--secondary-3)', }, }, } as const; export type Brand = typeof brand;
4.3 Update TypeScript Configuration
Section titled “4.3 Update TypeScript Configuration”Update tsconfig.json:
{ "compilerOptions": { "baseUrl": ".", "paths": { "@brand/*": ["src/brand/*"], "@components/*": ["packages/components/*"], "@design-tokens/*": ["packages/design-tokens/*"], "@utils/*": ["packages/utils/*"] } } }
Update sites/Template/tsconfig.json to reference monorepo root config and add local alias:
{ "extends": "../../tsconfig.json", "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"], "@brand/*": ["../../src/brand/*"] } } }
Phase 5: Update Favicon Generation
Section titled “Phase 5: Update Favicon Generation”5.1 Create Favicon Source SVGs
Section titled “5.1 Create Favicon Source SVGs”Create simplified favicon sources:
-
src/brand/sd/favicons/sd-favicon-source.svg- Simplified SD at 600 weight -
src/brand/ts/favicons/ts-favicon-source.svg- Simplified TS at 600 weight
These should be based on the circle logos but optimized for 16×16 and 32×32 sizes (possibly with slightly bolder strokes).
5.2 Modify Favicon Generator
Section titled “5.2 Modify Favicon Generator”Update sites/Template/scripts/generate-favicon.mjs:
// Read brand from site.config.json const brandId = config.brand?.id || 'sd'; // Read favicon source from brand folder const faviconSourcePath = resolve( ROOT, '..', '..', 'src', 'brand', brandId, 'favicons', `${brandId}-favicon-source.svg` ); const faviconSvg = readFileSync(faviconSourcePath, 'utf-8'); // Apply colors from config const primaryColor = config.brand.favicon.textColor || '#004425'; // Process SVG to apply colors... // Write to public/ writeFileSync(resolve(ROOT, 'public', 'favicon.svg'), processedSvg);
5.3 Update Site Config
Section titled “5.3 Update Site Config”Update sites/Template/site.config.json:
{ "brand": { "id": "sd", "favicon": { "textColor": "#004425" } } }
Phase 6: Refactor BrandLogo Component (CRITICAL - Preserve Animation)
Section titled “Phase 6: Refactor BrandLogo Component (CRITICAL - Preserve Animation)”6.1 Understand Current Animation
Section titled “6.1 Understand Current Animation”The existing animation in sites/Template/src/components/brand/BrandLogo.astro:
-
Has inline SVG paths for S, $, and D
-
Uses CSS
@keyframes show-dollarto animate opacity of $ character -
S and D are always visible
-
$ fades in/out on 4-second cycle
-
Animation pauses on hover
-
Respects
prefers-reduced-motion
This functionality MUST be preserved for ALL SD logo variants.
6.2 New Component Architecture
Section titled “6.2 New Component Architecture”Strategy: Import SVG as raw string, inject into DOM, apply CSS classes for animation.
Create new sites/Template/src/components/brand/BrandLogo.astro:
--- interface Props { variant?: 'smart-debt' | 'talbot-stevens'; logoType?: 'circle' | 'leaf-dot' | 'leaf-square' | 'leaf-rect'; animate?: boolean; class?: string; } const { variant = 'smart-debt', logoType = 'circle', animate = false, class: className = '' } = Astro.props; // Import brand contracts const { brand: sdBrand } = await import('@brand/sd'); const { brand: tsBrand } = await import('@brand/ts'); // Select brand const currentBrand = variant === 'smart-debt' ? sdBrand : tsBrand; // Select logo variant (dynamically) const logoImporter = currentBrand.logos[logoType]; if (!logoImporter) { throw new Error(`Logo type "${logoType}" not found for brand "${currentBrand.id}"`); } // Import SVG as raw string const logoSvg = await logoImporter(); // Generate unique ID for this instance (for CSS scoping) const instanceId = `logo-${currentBrand.id}-${Math.random().toString(36).slice(2, 9)}`; const ariaLabels = { 'smart-debt': 'Smart Debt Logo', 'talbot-stevens': 'Talbot Stevens Logo' } as const; // Animation applies to ALL SD logos when animate=true const canAnimate = variant === 'smart-debt'; --- <div id={instanceId} class:list={[ "brand-logo-wrapper", `${currentBrand.id}-logo`, animate && canAnimate && "brand-logo--animate", className ]} role="img" aria-label={ariaLabels[variant]} set:html={logoSvg} /> <style> .brand-logo-wrapper { width: 100%; height: auto; display: block; } .brand-logo-wrapper :global(svg) { width: 100%; height: auto; display: block; } /* SD brand color mapping */ .sd-logo { /* Primary color for background and main characters */ color: var(--sd-logo-primary, hsl(var(--primary-8))); } .sd-logo :global(.logo-secondary) { color: var(--sd-logo-secondary, hsl(var(--secondary-7))); } /* TS brand color mapping */ .ts-logo { color: var(--ts-logo-primary, hsl(var(--primary-8))); } .ts-logo :global(.logo-secondary) { color: var(--ts-logo-secondary, hsl(var(--secondary-7))); } /* Animation for SD logo (S ↔ $D) - applies to ALL SD variants */ .sd-logo :global(.logo-s) { opacity: 1; } .sd-logo :global(.logo-dollar) { opacity: 0; } @keyframes show-dollar { 0% { opacity: 0; } 37.5% { opacity: 0; } 50% { opacity: 1; } 87.5% { opacity: 1; } 100% { opacity: 0; } } /* Animation activates for ANY SD logo when animate prop is true */ .brand-logo--animate.sd-logo :global(.logo-dollar) { animation: show-dollar 4s ease-in-out infinite; } .brand-logo--animate.sd-logo:hover :global(.logo-dollar) { animation-play-state: paused; } @media (prefers-reduced-motion: reduce) { .brand-logo--animate.sd-logo :global(.logo-dollar) { animation: none !important; opacity: 0; } } @media print { .sd-logo :global(.logo-dollar) { opacity: 0 !important; } } </style>
6.3 Critical Animation Requirements
Section titled “6.3 Critical Animation Requirements”IMPORTANT: Animation applies to ALL SD logo variants, not just circle.
Ensure every SD SVG (sd-circle.svg, sd-leaf-dot.svg, sd-leaf-square.svg, sd-leaf-rect.svg) has:
- Three character path groups:
-
.logo-s- S character -
.logo-dollar- $ character (hidden by default) -
.logo-d- D character
-
All use same base class
.logo-primary(for color inheritance) -
Consistent structure across all variants:
<svg viewBox="0 0 100 100"> <!-- Background varies by type: circle, leaf, square, rect --> <path class="logo-bg" d="..." fill="currentColor"/> <!-- Characters are IDENTICAL across all variants --> <path class="logo-primary logo-s" d="..." fill="currentColor"/> <path class="logo-primary logo-dollar" d="..." fill="currentColor"/> <path class="logo-primary logo-d" d="..." fill="currentColor"/> <!-- Optional secondary varies by type --> <path class="logo-secondary" d="..." fill="currentColor"/> </svg>
Design implication: When creating variants in Inkscape, the S, $, D character paths should be copied identically across all four background variations. Only the background shape changes between variants.
6.4 Update Component Imports
Section titled “6.4 Update Component Imports”Update all files that import BrandLogo:
<BrandLogo variant="smart-debt" logoType="circle" animate={true} class="w-12 h-12" />
- Logo Test Page: sites/Template/src/pages/logo-test.astro
- Update to test all logo variants (circle, leaf-dot, leaf-square, leaf-rect)
- Test animation explicitly for EACH variant (all should animate)
- Logo Showcase: sites/Template/src/components/showcase/LogoShowcase.astro
-
Show all SD variants: circle, leaf-dot, leaf-square, leaf-rect
-
Show TS circle variant
-
Demonstrate light/dark theme switching
-
Demonstrate animation for ALL SD variants
Phase 7: Update Documentation
Section titled “Phase 7: Update Documentation”7.1 Update Logo Documentation
Section titled “7.1 Update Logo Documentation”Update docs/design/logo.md:Major changes:
-
Document semantic class approach (
.logo-bg,.logo-primary,.logo-secondary) -
Update paths to
src/brand/sd/logos/svg-paths-base/ -
Document all SD variants (circle, leaf-dot, leaf-square, leaf-rect)
-
Emphasize that ALL SD variants support animation
-
Update viewBox from 512×512 to 100×100
-
Document color application via
currentColor -
Add section on “Creating New Logo Variants” with Inkscape workflow
-
Document animation structure (S, $, D paths in ALL SD variants)
Add section:
## Animation Support ### Universal Animation for SmartDebt **ALL SmartDebt logo variants** support the S ↔ $D animation: - sd-circle.svg ✓ - sd-leaf-dot.svg ✓ - sd-leaf-square.svg ✓ - sd-leaf-rect.svg ✓ Each variant contains identical S, $, D character paths. The background shape changes, but the animation structure remains consistent. ### How It Works The animation uses CSS opacity keyframes: - S character: Always visible (opacity: 1) - $ character: Fades in/out (opacity: 0 → 1 → 0) - D character: Always visible (opacity: 1) The component activates animation via the `animate` prop: \`\`\`astro <BrandLogo variant="smart-debt" logoType="leaf-dot" animate={true} /> \`\`\` ## Color System Integration Logos use semantic classes with `currentColor`: | Class | Purpose | Color Source | |-------|---------|--------------| | `.logo-bg` | Background shape | `color` property on wrapper | | `.logo-primary` | Main characters/marks | `color` property on wrapper | | `.logo-secondary` | Accent elements | `--logo-secondary-color` CSS variable | ### Theme Adaptation Colors automatically adapt to theme via brand tokens: ```css [data-theme="light"] .sd-logo { color: hsl(var(--primary-8)); /* Dark green for light bg */ } [data-theme="dark"] .sd-logo { color: hsl(var(--primary-2)); /* Light tint for dark bg */ }
Same SVG, infinite themes.
### 7.2 Update Color Documentation Update [docs/design/colors.md](docs/design/colors.md): **Add sections**: - Document shared vs brand-specific tokens - Explain token merge strategy (shared + brand) - Update file paths - Document logo color tokens (`--sd-logo-primary`, etc.) - Add example of brand-scoped tokens ### 7.3 Update Favicon Documentation Update [docs/design/favicon.md](docs/design/favicon.md): **Changes**: - Document new generation approach (from brand source SVGs) - Update source file locations - Document brand configuration in `site.config.json` - Explain simplified favicon design (600 weight) ### 7.4 Create Brand Contract Documentation **Create** `docs/design/brand-contract.md`: ```markdown # Brand Contract ## Overview The brand contract defines the stable interface that sites use to consume brand assets. Each brand exposes a minimal, versioned API that sites import. ## Philosophy > **Sites consume brands via contract, never via direct file paths.** This ensures: - Clear ownership boundaries - Easy refactoring of brand internals - Ability to version brands independently - Future package extraction capability ## Contract Structure Each brand (`sd`, `ts`) exposes: \`\`\`typescript { id: string; // Short identifier name: string; // Full brand name displayName: string; // Display-friendly name tokens: () => Promise; // CSS tokens (lazy-loaded) logos: { // Logo variants (lazy-loaded) [key: string]: () => Promise<string> }; colors: { // Color anchors (reference) [key: string]: string }; logoVars: { // Logo color mappings light: { primary: string, secondary: string }, dark: { primary: string, secondary: string } }; } \`\`\` ## Usage \`\`\`typescript import { brand } from '@brand/sd'; // Load tokens await brand.tokens(); // Load logo const logoSvg = await brand.logos.circle(); \`\`\` ## Naming Conventions ### Folder Names - Lowercase, short codes - `sd` - SmartDebt - `ts` - TalbotStevens ### File Names - Brand-prefixed, kebab-case - `sd-circle.svg`, `sd-leaf-dot.svg` - `ts-circle.svg` ### CSS Tokens - Brand-namespaced - `--sd-logo-primary`, `--sd-logo-secondary` - `--ts-logo-primary`, `--ts-logo-secondary` ## Logo Variants ### SmartDebt (SD) All variants support S ↔ $D animation: - `circle` - Circular background - `leafDot` - Leaf shape with dot accent - `leafSquare` - Leaf shape with square background - `leafRect` - Leaf shape with rectangular background ### TalbotStevens (TS) - `circle` - Circular background ## Template's Role Template demonstrates brand consumption: \`\`\`astro import { brand } from '@brand/sd'; import BrandLogo from '@/components/brand/BrandLogo.astro'; <BrandLogo variant="smart-debt" logoType="circle" animate={true} /> \`\`\` Template: - ✅ Imports via brand contract - ✅ Demonstrates all variants - ✅ Validates contract completeness - ❌ Never owns brand assets - ❌ Never hardcodes brand paths
7.5 Update Design README
Section titled “7.5 Update Design README”Update docs/design/README.md:Add section:
## Brand System The monorepo implements a formal brand system where: 1. **Brands are infrastructure** - Live at `src/brand/{sd,ts}/` 2. **Sites are consumers** - Import via `@brand/*` contracts 3. **Logos are semantic** - Use `currentColor` with semantic classes 4. **Colors are external** - Applied via brand-specific CSS variables 5. **Animation universal** - All SD logo variants support S ↔ $D animation See [Brand Contract](./brand-contract.md) for details. ### Brand Structure
src/brand/
sd/ # SmartDebt brand
logos/
svg-paths-base/ # Semantic SVG files (all with S,$,D paths)
favicons/
colors.oklch.json # Brand color definitions
tokens.css # Generated CSS tokens
index.ts # Brand contract
ts/ # TalbotStevens brand
(same structure)
Phase 8: Create Template Showcase Components
Section titled “Phase 8: Create Template Showcase Components”8.1 Create Logo Showcase Component
Section titled “8.1 Create Logo Showcase Component”Create sites/Template/src/components/showcase/BrandLogoShowcase.astro:
--- import BrandLogo from '@/components/brand/BrandLogo.astro'; import { brand as sdBrand } from '@brand/sd'; const sdLogoTypes = Object.keys(sdBrand.logos); --- <section class="logo-showcase"> <h2>SmartDebt Logo Variants</h2> <p class="text-muted">All variants support S ↔ $D animation</p> <div class="logo-grid"> {sdLogoTypes.map(logoType => ( <div class="logo-card"> <h3>{logoType}</h3> <div class="logo-demo"> <div class="demo-item"> <p>Static</p> <BrandLogo variant="smart-debt" logoType={logoType} class="w-32 h-32" /> </div> <!-- ALL SD logos can animate, not just circle --> <div class="demo-item"> <p>Animated (S ↔ $D)</p> <BrandLogo variant="smart-debt" logoType={logoType} animate={true} class="w-32 h-32" /> </div> </div> <div class="theme-demo"> <div data-theme="light" class="theme-box"> <p>Light Theme</p> <BrandLogo variant="smart-debt" logoType={logoType} class="w-24 h-24" /> </div> <div data-theme="dark" class="theme-box dark-bg"> <p>Dark Theme</p> <BrandLogo variant="smart-debt" logoType={logoType} class="w-24 h-24" /> </div> </div> </div> ))} </div> <h2>TalbotStevens Logo</h2> <BrandLogo variant="talbot-stevens" logoType="circle" class="w-32 h-32" /> </section>
8.2 Update Template Documentation
Section titled “8.2 Update Template Documentation”Update sites/Template/docs/README.md:
Clarify Template’s role:
## Template's Role The Template site serves as: 1. **Reference Implementation** - Demonstrates correct brand consumption 2. **Testing Sandbox** - Validates all components and patterns 3. **Living Documentation** - Shows brand assets in use ### Key Principle > **Template demonstrates, never defines.** Template: - ✅ Imports brands via `@brand/*` contracts - ✅ Showcases all logo variants (all SD variants animate) - ✅ Tests theme switching - ✅ Validates animations - ❌ Never owns brand assets - ❌ Never hardcodes brand paths - ❌ Never defines brand tokens This ensures Template reflects the same consumption pattern that production sites use.
Phase 9: Validation & Testing
Section titled “Phase 9: Validation & Testing”9.1 Build Validation
Section titled “9.1 Build Validation”Run builds to ensure everything compiles:
cd sites/Template pnpm run build
9.2 Visual Validation
Section titled “9.2 Visual Validation”Test in browser:
-
All SD logo variants render correctly
-
Logo animation works for ALL SD variants (circle, leaf-dot, leaf-square, leaf-rect)
-
Animation pauses on hover for all variants
-
Colors adapt to light/dark theme
-
Both SD and TS logos display
-
Favicons generate correctly
9.3 Code Validation
Section titled “9.3 Code Validation”Verify:
-
No hardcoded brand colors in SVG files
-
All SVGs use semantic classes
-
All SVGs use
currentColor -
All SD SVGs contain S, $, D paths
-
BrandLogo component imports via brand contract
-
No direct file path imports to brand assets
-
TypeScript compilation succeeds
-
All documentation updated
Implementation Checklist
Section titled “Implementation Checklist”Phase 1: Infrastructure
Section titled “Phase 1: Infrastructure”-
Create
src/brand/sd/directory structure -
Create
src/brand/ts/directory structure -
Create
src/design-tokens/directory -
Move shared tokens to new location
Phase 2: Logos (CRITICAL - All SD variants need S,$,D paths)
Section titled “Phase 2: Logos (CRITICAL - All SD variants need S,$,D paths)”-
Create sd-circle.svg (with S, $, D paths for animation)
-
Create sd-leaf-dot.svg (with S, $, D paths for animation)
-
Create sd-leaf-square.svg (with S, $, D paths for animation)
-
Create sd-leaf-rect.svg (with S, $, D paths for animation)
-
Create ts-circle.svg (no animation needed)
-
Delete old logo files from src/assets/brand/logos/
Phase 3: Tokens
Section titled “Phase 3: Tokens”-
Create src/design-tokens/colors.oklch.json (shared)
-
Create src/brand/sd/colors.oklch.json
-
Create src/brand/ts/colors.oklch.json
-
Update generate-color-system.mjs for brand flag
-
Generate SD tokens (pnpm run colors:sd)
-
Generate TS tokens (pnpm run colors:ts)
Phase 4: Contracts
Section titled “Phase 4: Contracts”-
Create src/brand/sd/index.ts
-
Create src/brand/ts/index.ts
-
Update tsconfig.json with @brand/* alias
-
Update sites/Template/tsconfig.json
Phase 5: Favicons
Section titled “Phase 5: Favicons”-
Create src/brand/sd/favicons/sd-favicon-source.svg
-
Create src/brand/ts/favicons/ts-favicon-source.svg
-
Update generate-favicon.mjs to use brand sources
-
Update site.config.json
Phase 6: Component (CRITICAL - Preserve animation for ALL SD variants)
Section titled “Phase 6: Component (CRITICAL - Preserve animation for ALL SD variants)”-
Rewrite BrandLogo.astro to use SVG imports
-
Verify animation works for ALL SD variants (S ↔ $D)
-
Update Header.astro
-
Update logo-test.astro (test all SD variants animate)
-
Update LogoShowcase.astro (show all SD variants animate)
Phase 7: Documentation
Section titled “Phase 7: Documentation”-
Update docs/design/logo.md (emphasize universal animation)
-
Update docs/design/colors.md
-
Update docs/design/favicon.md
-
Create docs/design/brand-contract.md
-
Update docs/design/README.md
Phase 8: Showcase
Section titled “Phase 8: Showcase”- Create BrandLogoShowcase.astro component (show all variants animate)
- Update sites/Template/docs/README.md
Phase 9: Validation
Section titled “Phase 9: Validation”-
Build succeeds (pnpm run build)
-
Visual testing: ALL SD variants animate
-
Code review checklist complete
Key Files to Create/Modify
Section titled “Key Files to Create/Modify”Create New Files
Section titled “Create New Files”| File | Purpose | Animation Support |
|------|---------|-------------------|
| src/brand/sd/logos/svg-paths-base/sd-circle.svg | SD circle logo | ✓ S,$,D paths |
| src/brand/sd/logos/svg-paths-base/sd-leaf-dot.svg | SD leaf-dot variant | ✓ S,$,D paths |
| src/brand/sd/logos/svg-paths-base/sd-leaf-square.svg | SD leaf-square variant | ✓ S,$,D paths |
| src/brand/sd/logos/svg-paths-base/sd-leaf-rect.svg | SD leaf-rect variant | ✓ S,$,D paths |
| src/brand/ts/logos/svg-paths-base/ts-circle.svg | TS circle logo | N/A |
| src/brand/sd/colors.oklch.json | SD color definitions | - |
| src/brand/ts/colors.oklch.json | TS color definitions | - |
| src/design-tokens/colors.oklch.json | Shared tokens (stone, gray) | - |
| src/brand/sd/index.ts | SD brand contract | - |
| src/brand/ts/index.ts | TS brand contract | - |
| docs/design/brand-contract.md | Brand contract documentation | - |
| sites/Template/src/components/showcase/BrandLogoShowcase.astro | Logo showcase (all variants animate) | - |
Modify Existing Files
Section titled “Modify Existing Files”| File | Changes |
|------|---------|
| sites/Template/src/components/brand/BrandLogo.astro | Complete rewrite: import SVGs, preserve animation for ALL SD variants |
| sites/Template/scripts/generate-color-system.mjs | Add brand flag, merge shared + brand tokens |
| sites/Template/scripts/generate-favicon.mjs | Use brand source SVGs |
| tsconfig.json | Add @brand/* alias |
| sites/Template/tsconfig.json | Add @brand/* alias |
| docs/design/logo.md | Document semantic classes, currentColor, universal animation |
| docs/design/colors.md | Document shared + brand token structure |
| docs/design/favicon.md | Document brand-based generation |
| docs/design/README.md | Add brand system overview |
| sites/Template/docs/README.md | Clarify Template’s consumer role |---
Final Architecture Summary
Section titled “Final Architecture Summary”Brands are infrastructure (monorepo root) ↓ Sites are consumers (via @brand/* imports) ↓ Logos are semantic (currentColor + classes) ↓ ALL SD variants support animation (S,$,D paths) ↓ Colors are external (CSS variables) ↓ Template demonstrates (never owns)
This establishes:
-
✅ Single source of truth for brand assets
-
✅ Zero duplication across sites
-
✅ Theme-agnostic, reusable logos
-
✅ Clear ownership boundaries
-
✅ Animation for ALL SD variants (S ↔ $D)
-
✅ Scalability to multiple SD sites