diff --git a/COLOR_MIGRATION_GUIDE.md b/COLOR_MIGRATION_GUIDE.md new file mode 100644 index 000000000..9afea7998 --- /dev/null +++ b/COLOR_MIGRATION_GUIDE.md @@ -0,0 +1,180 @@ +# Color Migration Guide + +## Overview +This guide maps old (deprecated) colors to new brand-approved colors based on the VetsWhoCode Brand Style Guide. + +--- + +## Color Mappings + +### Primary Colors + +| Old Color | New Color | Usage | +|-----------|-----------|-------| +| `primary` (was red) | `primary` or `red` | Primary CTAs, accents | +| `secondary` (was blue) | `secondary` or `navy` | Primary brand color | + +### Semantic Colors + +| Old Color | New Color | Reason | +|-----------|-----------|--------| +| `success` (#4CAF50) | `success` or `gold` | Now uses Amber Gold (#FDB330) | +| `warning` (#FFC107) | `warning` or `gold-bright` | Now uses Bright Gold (#FAD643) | +| `danger` (#F44336) | `danger` or `red` | Now uses Brand Red (#c5203e) | +| `info` (#17A2B8) | `info` or `navy-ocean` | Now uses Ocean Blue (#006DAA) | + +### Removed Colors (Map to Brand Colors) + +| Removed Color | Map To | Notes | +|---------------|--------|-------| +| `orange` | `red` or `gold` | Context-dependent | +| `yellow` | `gold` | Amber Gold is brand gold | +| `blue-100` | `navy-sky` or `navy-ocean` | Use navy scale | +| `spring` (#F5F1ED) | `cream` (#EEEDE9) | Use brand cream | +| `desert` | `red` | Was using red anyway | +| `pearl` (#EAE1D6) | `cream` | Similar tone | +| `putty` (#e5c791) | `gold` or `gold-light` | Gold tone | +| `brunt` (#ee7455) | `red` or `red-signal` | Red tone | +| `jagged` (#BCE6DF) | `navy-sky` | Light blue tone | +| `azure` (#00adff) | `navy-ocean` | Blue tone | +| `alto` (#dedede) | `gray-100` (Silver) | Borders/dividers | +| `teracotta` | `red` or `gold` | Context-dependent | +| `scooter` | `navy-ocean` | Blue tone | +| `ebb` (#e9e6e3) | `gray-50` or `cream` | Light neutral | +| `pampas` (#ece8e4) | `cream` | Light background | +| `gore` (#1f1f52) | `navy` or `navy-midnight` | Dark blue | +| `porsche` (#ebb860) | `gold` | Gold tone | +| `mandy` (#df5b6c) | `red` | Red tone | +| `tan` (#d2a98e) | `gold` or `cream` | Warm neutral | +| `mishcka` (#e2e2e8) | `gray-100` | Light gray | + +### Gray Scale Migration + +| Old Gray | New Gray | Color | Usage | +|----------|----------|-------|-------| +| `gray-50` | `gray-50` | #F8F9FA | Off White - light cards | +| `gray-100` | `gray-100` | #DEE2E6 | Silver - borders, dividers | +| `gray-200` | `gray-200` | #6C757D | Slate - secondary text | +| `gray-300` | `gray-300` | #495057 | Charcoal - muted labels | +| `gray-350` | `gray-100` | - | Use Silver | +| `gray-400` | `gray-400` | #343A40 | Dark Gray - text blocks | +| `gray-450` | `gray-50` | - | Use Off White | +| `gray-500` | `gray-50` | - | Use Off White | +| `gray-550` | `gray-50` | - | Use Off White | +| `gray-600` | `gray-300` | - | Use Charcoal | +| `gray-650` | `gray-100` | - | Use Silver | +| `gray-700` | `gray-200` | - | Use Slate | +| `gray-750` | `gray-50` | - | Use Off White | +| `gray-800` | `gray-400` | - | Use Dark Gray | +| `gray-850` | `gray-300` | - | Use Charcoal | + +--- + +## New Brand Colors Available + +### Navy Blue Scale +``` +navy (default): #091f40 +navy-midnight: #061A40 +navy-deep: #003559 +navy-royal: #0353A4 +navy-ocean: #006DAA +navy-sky: #B9D6F2 +``` + +### Red Scale +``` +red (default): #c5203e +red-signal: #C52233 +red-crimson: #A51C30 +red-dark: #74121D +red-maroon: #580C1F +``` + +### Gold Scale +``` +gold (default): #FDB330 +gold-light: #FFE169 +gold-bright: #FAD643 +gold-rich: #DBB42C +gold-deep: #C9A227 +``` + +### Base Colors +``` +cream: #EEEDE9 (backgrounds) +ink: #1A1823 (body text) +white: #FFFFFF +black: #000000 +``` + +### Dark Mode Colors +``` +dark (default): #1A1823 +dark-surface: #212529 +dark-elevated: #343A40 +dark-text: #F8F9FA +dark-text-muted: #DEE2E6 +dark-text-disabled: #6C757D +dark-accent: #84C1FF +dark-accent-hover: #B9D6F2 +dark-error: #F38375 +dark-success: #FFE169 +dark-badge: #FAD643 +``` + +--- + +## Migration Strategy + +### Phase 1: High-Impact Components +1. Navigation/Header +2. Hero sections +3. CTAs (Call-to-action buttons) +4. Forms + +### Phase 2: Content Areas +1. Blog components +2. Course components +3. Team/testimonials +4. Services + +### Phase 3: Utility Components +1. Alerts +2. Badges +3. Cards +4. Modals + +### Phase 4: Admin/Dashboard +1. Admin panels +2. Dashboard components +3. Data tables + +--- + +## Testing Checklist + +- [ ] Header/navigation displays correctly +- [ ] CTAs are prominent with brand red +- [ ] Text has proper contrast (WCAG AA: 4.5:1 minimum) +- [ ] Success states use gold (not green) +- [ ] Info boxes use navy-sky +- [ ] Links use navy-ocean +- [ ] Dark mode colors work properly +- [ ] No console errors about missing colors + +--- + +## Quick Reference Commands + +### Find files using deprecated colors +```bash +grep -r "tw-bg-orange\|tw-text-orange\|tw-border-orange" src/ +grep -r "tw-bg-yellow\|tw-text-yellow\|tw-border-yellow" src/ +grep -r "tw-bg-spring\|tw-text-spring\|tw-border-spring" src/ +``` + +### Find old gray scale usage +```bash +grep -r "gray-350\|gray-450\|gray-550\|gray-650\|gray-750\|gray-800\|gray-850" src/ +``` diff --git a/scripts/replace-deprecated-colors.js b/scripts/replace-deprecated-colors.js new file mode 100755 index 000000000..a9bab6d82 --- /dev/null +++ b/scripts/replace-deprecated-colors.js @@ -0,0 +1,181 @@ +#!/usr/bin/env node +/** + * Replace deprecated colors with brand-approved colors + * Run with: node scripts/replace-deprecated-colors.js + */ + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +// Color replacement mappings +const colorReplacements = [ + // Orange → Red or Gold (context-dependent, defaulting to red for CTAs) + { from: /tw-bg-orange(?!-)/g, to: 'tw-bg-red' }, + { from: /tw-text-orange(?!-)/g, to: 'tw-text-red' }, + { from: /tw-border-orange(?!-)/g, to: 'tw-border-red' }, + { from: /tw-bg-orange-light/g, to: 'tw-bg-red-signal/10' }, + { from: /tw-bg-orange-100/g, to: 'tw-bg-red-signal' }, + { from: /tw-bg-orange-200/g, to: 'tw-bg-red-signal' }, + { from: /tw-bg-orange-300/g, to: 'tw-bg-red' }, + { from: /tw-text-orange-100/g, to: 'tw-text-red-signal' }, + { from: /tw-text-orange-200/g, to: 'tw-text-red-signal' }, + { from: /tw-text-orange-300/g, to: 'tw-text-red' }, + + // Yellow → Gold + { from: /tw-bg-yellow(?!-)/g, to: 'tw-bg-gold' }, + { from: /tw-text-yellow(?!-)/g, to: 'tw-text-gold' }, + { from: /tw-border-yellow(?!-)/g, to: 'tw-border-gold' }, + { from: /tw-bg-yellow-100/g, to: 'tw-bg-gold-bright' }, + { from: /tw-text-yellow-100/g, to: 'tw-text-gold-bright' }, + + // Blue-100 → Navy ocean or sky + { from: /tw-bg-blue-100/g, to: 'tw-bg-navy-sky' }, + { from: /tw-text-blue-100/g, to: 'tw-text-navy-ocean' }, + { from: /tw-border-blue-100/g, to: 'tw-border-navy-ocean' }, + + // Spring → Cream + { from: /tw-bg-spring/g, to: 'tw-bg-cream' }, + { from: /tw-text-spring/g, to: 'tw-text-cream' }, + + // Desert → Red (it was using red anyway) + { from: /tw-bg-desert(?!-)/g, to: 'tw-bg-red' }, + { from: /tw-text-desert(?!-)/g, to: 'tw-text-red' }, + { from: /tw-border-desert(?!-)/g, to: 'tw-border-red' }, + { from: /tw-bg-desert-100/g, to: 'tw-bg-cream' }, + + // Pearl → Cream + { from: /tw-bg-pearl/g, to: 'tw-bg-cream' }, + { from: /tw-text-pearl/g, to: 'tw-text-cream' }, + + // Putty → Gold + { from: /tw-bg-putty/g, to: 'tw-bg-gold' }, + { from: /tw-text-putty/g, to: 'tw-text-gold' }, + + // Brunt → Red + { from: /tw-bg-brunt/g, to: 'tw-bg-red' }, + { from: /tw-text-brunt/g, to: 'tw-text-red' }, + + // Jagged → Navy sky + { from: /tw-bg-jagged/g, to: 'tw-bg-navy-sky' }, + { from: /tw-text-jagged/g, to: 'tw-text-navy-sky' }, + + // Azure → Navy ocean + { from: /tw-bg-azure/g, to: 'tw-bg-navy-ocean' }, + { from: /tw-text-azure/g, to: 'tw-text-navy-ocean' }, + { from: /tw-border-azure/g, to: 'tw-border-navy-ocean' }, + + // Alto → Gray-100 (Silver) + { from: /tw-bg-alto/g, to: 'tw-bg-gray-100' }, + { from: /tw-border-alto/g, to: 'tw-border-gray-100' }, + + // Teracotta → Red or Gold (defaulting to red) + { from: /tw-bg-teracotta(?!-)/g, to: 'tw-bg-red' }, + { from: /tw-text-teracotta(?!-)/g, to: 'tw-text-red' }, + { from: /tw-bg-teracotta-light/g, to: 'tw-bg-red-signal/10' }, + + // Scooter → Navy ocean + { from: /tw-bg-scooter(?!-)/g, to: 'tw-bg-navy-ocean' }, + { from: /tw-text-scooter(?!-)/g, to: 'tw-text-navy-ocean' }, + { from: /tw-bg-scooter-light/g, to: 'tw-bg-navy-sky' }, + + // Ebb → Cream or Gray-50 + { from: /tw-bg-ebb/g, to: 'tw-bg-gray-50' }, + + // Pampas → Cream + { from: /tw-bg-pampas/g, to: 'tw-bg-cream' }, + + // Gore → Navy + { from: /tw-bg-gore/g, to: 'tw-bg-navy' }, + { from: /tw-text-gore/g, to: 'tw-text-navy' }, + + // Porsche → Gold + { from: /tw-bg-porsche/g, to: 'tw-bg-gold' }, + { from: /tw-text-porsche/g, to: 'tw-text-gold' }, + + // Mandy → Red + { from: /tw-bg-mandy/g, to: 'tw-bg-red' }, + { from: /tw-text-mandy/g, to: 'tw-text-red' }, + + // Tan → Gold or Cream + { from: /tw-bg-tan/g, to: 'tw-bg-gold-light' }, + { from: /tw-text-tan/g, to: 'tw-text-gold' }, + + // Mishcka → Gray-100 + { from: /tw-bg-mishcka/g, to: 'tw-bg-gray-100' }, + { from: /tw-text-mishcka/g, to: 'tw-text-gray-200' }, + + // Old gray scale replacements + { from: /tw-bg-gray-350/g, to: 'tw-bg-gray-100' }, + { from: /tw-border-gray-350/g, to: 'tw-border-gray-100' }, + { from: /tw-bg-gray-450/g, to: 'tw-bg-gray-50' }, + { from: /tw-bg-gray-500/g, to: 'tw-bg-gray-50' }, + { from: /tw-bg-gray-550/g, to: 'tw-bg-gray-50' }, + { from: /tw-bg-gray-600/g, to: 'tw-bg-gray-300' }, + { from: /tw-text-gray-600/g, to: 'tw-text-gray-300' }, + { from: /tw-bg-gray-650/g, to: 'tw-bg-gray-100' }, + { from: /tw-border-gray-650/g, to: 'tw-border-gray-100' }, + { from: /tw-bg-gray-700/g, to: 'tw-bg-gray-200' }, + { from: /tw-text-gray-700/g, to: 'tw-text-gray-200' }, + { from: /tw-bg-gray-750/g, to: 'tw-bg-gray-50' }, + { from: /tw-bg-gray-800/g, to: 'tw-bg-gray-400' }, + { from: /tw-text-gray-800/g, to: 'tw-text-gray-400' }, + { from: /tw-bg-gray-850/g, to: 'tw-bg-gray-300' }, + { from: /tw-text-gray-850/g, to: 'tw-text-gray-300' }, +]; + +function processFile(filePath) { + let content = fs.readFileSync(filePath, 'utf8'); + let modified = false; + + colorReplacements.forEach(({ from, to }) => { + if (from.test(content)) { + content = content.replace(from, to); + modified = true; + } + }); + + if (modified) { + fs.writeFileSync(filePath, content, 'utf8'); + return true; + } + + return false; +} + +function findAndReplaceInDirectory(dir) { + const files = execSync(`find ${dir} -type f \\( -name "*.tsx" -o -name "*.ts" -o -name "*.jsx" -o -name "*.js" \\) ! -path "*/node_modules/*" ! -path "*/.next/*"`, { + encoding: 'utf8', + }).trim().split('\n').filter(Boolean); + + let modifiedCount = 0; + const modifiedFiles = []; + + files.forEach(file => { + if (processFile(file)) { + modifiedCount++; + modifiedFiles.push(file); + } + }); + + return { modifiedCount, modifiedFiles }; +} + +// Main execution +console.log('🎨 Starting color replacement...\n'); + +const srcDir = path.join(process.cwd(), 'src'); +const { modifiedCount, modifiedFiles } = findAndReplaceInDirectory(srcDir); + +console.log(`\n✅ Replaced deprecated colors in ${modifiedCount} files\n`); + +if (modifiedFiles.length > 0 && modifiedFiles.length <= 20) { + console.log('Modified files:'); + modifiedFiles.forEach(file => { + console.log(` - ${file.replace(process.cwd() + '/', '')}`); + }); +} else if (modifiedFiles.length > 20) { + console.log(`Modified ${modifiedFiles.length} files (too many to list)`); +} + +console.log('\n✨ Color replacement complete!\n'); diff --git a/scripts/replace-tailwind-default-colors.js b/scripts/replace-tailwind-default-colors.js new file mode 100644 index 000000000..871f26d38 --- /dev/null +++ b/scripts/replace-tailwind-default-colors.js @@ -0,0 +1,159 @@ +#!/usr/bin/env node +/** + * Replace standard Tailwind colors with brand-approved colors + * This handles orange-*, yellow-*, and other default Tailwind colors + */ + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +// Map standard Tailwind colors to brand colors +const replacements = [ + // Orange shades → Red shades + { from: /tw-bg-orange-50/g, to: 'tw-bg-red-signal/10' }, + { from: /tw-border-orange-50/g, to: 'tw-border-red-signal/10' }, + { from: /tw-bg-orange-100/g, to: 'tw-bg-red-signal/20' }, + { from: /tw-bg-orange-200/g, to: 'tw-bg-red-signal/30' }, + { from: /tw-border-orange-200/g, to: 'tw-border-red-signal/30' }, + { from: /tw-bg-orange-300/g, to: 'tw-bg-red-signal' }, + { from: /tw-bg-orange-400/g, to: 'tw-bg-red' }, + { from: /tw-bg-orange-500/g, to: 'tw-bg-red' }, + { from: /tw-bg-orange-600/g, to: 'tw-bg-red' }, + { from: /tw-bg-orange-700/g, to: 'tw-bg-red-crimson' }, + { from: /tw-bg-orange-800/g, to: 'tw-bg-red-dark' }, + { from: /tw-bg-orange-900/g, to: 'tw-bg-red-maroon' }, + + { from: /tw-text-orange-50/g, to: 'tw-text-red-signal/10' }, + { from: /tw-text-orange-100/g, to: 'tw-text-red-signal/20' }, + { from: /tw-text-orange-200/g, to: 'tw-text-red-signal/30' }, + { from: /tw-text-orange-300/g, to: 'tw-text-red-signal' }, + { from: /tw-text-orange-400/g, to: 'tw-text-red' }, + { from: /tw-text-orange-500/g, to: 'tw-text-red' }, + { from: /tw-text-orange-600/g, to: 'tw-text-red' }, + { from: /tw-text-orange-700/g, to: 'tw-text-red-crimson' }, + { from: /tw-text-orange-800/g, to: 'tw-text-red-dark' }, + { from: /tw-text-orange-900/g, to: 'tw-text-red-maroon' }, + + { from: /hover:tw-bg-orange-700/g, to: 'hover:tw-bg-red-crimson' }, + { from: /hover:tw-text-orange-800/g, to: 'hover:tw-text-red-dark' }, + + // Yellow shades → Gold shades + { from: /tw-bg-yellow-50/g, to: 'tw-bg-gold-light/20' }, + { from: /tw-bg-yellow-100/g, to: 'tw-bg-gold-light/30' }, + { from: /tw-bg-yellow-200/g, to: 'tw-bg-gold-light' }, + { from: /tw-bg-yellow-300/g, to: 'tw-bg-gold-bright' }, + { from: /tw-bg-yellow-400/g, to: 'tw-bg-gold' }, + { from: /tw-bg-yellow-500/g, to: 'tw-bg-gold' }, + { from: /tw-bg-yellow-600/g, to: 'tw-bg-gold-rich' }, + { from: /tw-bg-yellow-700/g, to: 'tw-bg-gold-deep' }, + { from: /tw-bg-yellow-800/g, to: 'tw-bg-gold-deep' }, + + { from: /tw-text-yellow-50/g, to: 'tw-text-gold-light/20' }, + { from: /tw-text-yellow-100/g, to: 'tw-text-gold-light/30' }, + { from: /tw-text-yellow-200/g, to: 'tw-text-gold-light' }, + { from: /tw-text-yellow-300/g, to: 'tw-text-gold-bright' }, + { from: /tw-text-yellow-400/g, to: 'tw-text-gold' }, + { from: /tw-text-yellow-500/g, to: 'tw-text-gold' }, + { from: /tw-text-yellow-600/g, to: 'tw-text-gold-rich' }, + { from: /tw-text-yellow-700/g, to: 'tw-text-gold-deep' }, + { from: /tw-text-yellow-800/g, to: 'tw-text-gold-deep' }, + + { from: /tw-border-yellow-500/g, to: 'tw-border-gold' }, + + // Green shades → Gold shades (for success states) + { from: /tw-bg-green-50/g, to: 'tw-bg-gold-light/20' }, + { from: /tw-bg-green-100/g, to: 'tw-bg-gold-light/30' }, + { from: /tw-bg-green-500/g, to: 'tw-bg-gold' }, + { from: /tw-bg-green-600/g, to: 'tw-bg-gold-rich' }, + { from: /tw-text-green-600/g, to: 'tw-text-gold' }, + { from: /tw-text-green-700/g, to: 'tw-text-gold-rich' }, + { from: /tw-text-green-800/g, to: 'tw-text-gold-deep' }, + + // Blue shades → Navy shades + { from: /tw-bg-blue-50/g, to: 'tw-bg-navy-sky/20' }, + { from: /tw-bg-blue-100/g, to: 'tw-bg-navy-sky/30' }, + { from: /tw-bg-blue-500/g, to: 'tw-bg-navy-ocean' }, + { from: /tw-bg-blue-600/g, to: 'tw-bg-navy-royal' }, + { from: /tw-bg-blue-700/g, to: 'tw-bg-navy' }, + + { from: /tw-text-blue-50/g, to: 'tw-text-navy-sky/20' }, + { from: /tw-text-blue-100/g, to: 'tw-text-navy-sky' }, + { from: /tw-text-blue-500/g, to: 'tw-text-navy-ocean' }, + { from: /tw-text-blue-600/g, to: 'tw-text-navy-royal' }, + { from: /tw-text-blue-700/g, to: 'tw-text-navy' }, + + { from: /tw-border-blue-500/g, to: 'tw-border-navy-ocean' }, + { from: /tw-border-blue-600/g, to: 'tw-border-navy-royal' }, + + // Purple/Indigo → Navy shades + { from: /tw-bg-purple-50/g, to: 'tw-bg-navy-sky/20' }, + { from: /tw-bg-purple-500/g, to: 'tw-bg-navy-royal' }, + { from: /tw-bg-purple-600/g, to: 'tw-bg-navy' }, + { from: /tw-text-purple-600/g, to: 'tw-text-navy' }, + + { from: /tw-bg-indigo-50/g, to: 'tw-bg-navy-sky/20' }, + { from: /tw-bg-indigo-500/g, to: 'tw-bg-navy-royal' }, + { from: /tw-bg-indigo-600/g, to: 'tw-bg-navy' }, + { from: /tw-text-indigo-600/g, to: 'tw-text-navy' }, +]; + +function processFile(filePath) { + let content = fs.readFileSync(filePath, 'utf8'); + let modified = false; + + replacements.forEach(({ from, to }) => { + if (from.test(content)) { + content = content.replace(from, to); + modified = true; + } + }); + + if (modified) { + fs.writeFileSync(filePath, content, 'utf8'); + return true; + } + + return false; +} + +function findAndReplaceInDirectory(dir) { + const files = execSync( + `find ${dir} -type f \\( -name "*.tsx" -o -name "*.ts" -o -name "*.jsx" -o -name "*.js" \\) ! -path "*/node_modules/*" ! -path "*/.next/*"`, + { encoding: 'utf8' } + ) + .trim() + .split('\n') + .filter(Boolean); + + let modifiedCount = 0; + const modifiedFiles = []; + + files.forEach((file) => { + if (processFile(file)) { + modifiedCount++; + modifiedFiles.push(file); + } + }); + + return { modifiedCount, modifiedFiles }; +} + +// Main execution +console.log('🎨 Replacing standard Tailwind colors with brand colors...\n'); + +const srcDir = path.join(process.cwd(), 'src'); +const { modifiedCount, modifiedFiles } = findAndReplaceInDirectory(srcDir); + +console.log(`\n✅ Updated ${modifiedCount} files\n`); + +if (modifiedFiles.length > 0 && modifiedFiles.length <= 20) { + console.log('Modified files:'); + modifiedFiles.forEach((file) => { + console.log(` - ${file.replace(process.cwd() + '/', '')}`); + }); +} else if (modifiedFiles.length > 20) { + console.log(`Modified ${modifiedFiles.length} files (too many to list)`); +} + +console.log('\n✨ Complete!\n'); diff --git a/src/components/admin-dashboard-components.tsx b/src/components/admin-dashboard-components.tsx index 81660d676..8c050e1b9 100644 --- a/src/components/admin-dashboard-components.tsx +++ b/src/components/admin-dashboard-components.tsx @@ -23,7 +23,7 @@ const ProgressBar = ({ progress }: { progress: number }) => { }; return ( -
{stat.value}
-+
{stat.change} from last month