feat(brand): implement procedural paint daube SVG icon system#71
Conversation
📝 WalkthroughWalkthroughThis PR adds a procedural PaintDaube SVG icon system and replaces emoji/string glyphs across the app with typed icon components (size, color, turbulence), updating many screens and shared UI primitives to use the new icons and adjusting affected public component props where applicable. Changes
Sequence Diagram(s)(Skipped — changes are UI/icon replacements and API surface updates rather than new multi-component control flows requiring sequential visualization.) Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🚀 Expo preview is ready!
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/components/chat/ApprovalCard.tsx (3)
59-61: React Native does not support CSS string values forborderRadius.The style
borderRadius: '16px 12px 16px 14px'uses CSS string syntax, which is invalid in React Native. React Native requires individual numeric corner radius properties.🐛 Proposed fix
style={{ - borderRadius: '16px 12px 16px 14px', + borderTopLeftRadius: 16, + borderTopRightRadius: 12, + borderBottomRightRadius: 16, + borderBottomLeftRadius: 14, borderLeftWidth: 4,
77-79: SameborderRadiusissue with CSS string syntax.This also uses invalid React Native syntax.
🐛 Proposed fix
<View className={`px-2 py-0.5 ${wasApproved ? 'bg-teal-600' : 'bg-coral-500'}`} - style={{ borderRadius: '6px 8px 6px 8px' }} + style={{ + borderTopLeftRadius: 6, + borderTopRightRadius: 8, + borderBottomRightRadius: 6, + borderBottomLeftRadius: 8, + }} >
97-99: Same issue on action button styles.These also use string syntax for
borderRadius.🐛 Proposed fix
<Pressable onPress={onReject} className="px-4 py-2 bg-neutral-700 active:bg-neutral-600" - style={{ borderRadius: '8px 10px 8px 12px' }} + style={{ + borderTopLeftRadius: 8, + borderTopRightRadius: 10, + borderBottomRightRadius: 8, + borderBottomLeftRadius: 12, + }} accessibilityRole="button"<Pressable onPress={onApprove} className="px-4 py-2 bg-teal-600 active:bg-teal-700 ml-2" - style={{ borderRadius: '8px 10px 8px 12px' }} + style={{ + borderTopLeftRadius: 8, + borderTopRightRadius: 10, + borderBottomRightRadius: 8, + borderBottomLeftRadius: 12, + }} accessibilityRole="button"Also applies to: 105-108
src/components/display/Badge.tsx (1)
67-100: Apply variant text color totextIcon.
Right now text-based icons render without the variant’s color, so status dots can appear inconsistent.✅ Proposed fix
- {textIcon && !Icon && <Text className={`mr-1 ${sizing.text}`}>{textIcon}</Text>} + {textIcon && !Icon && ( + <Text className={`mr-1 ${sizing.text} ${colors.text}`}>{textIcon}</Text> + )}
🧹 Nitpick comments (4)
src/components/icons/PaintDaubeIcon.tsx (1)
798-975: Consider extracting a shared base path for file variants.*
file,fileCode,fileData,fileDoc,fileStyle,fileWeb,fileMedia,fileConfigrepeat the same outline. A helper (base file path + overlay) would cut duplication and keep tweaks consistent.src/components/code/FileTree.tsx (1)
67-91: Hoist the icon map to avoid per-call allocation.
iconMapis recreated on every call; moving it to module scope avoids repeated allocations when rendering large trees.♻️ Proposed refactor
+const FILE_ICON_MAP: Record<string, FileIconInfo> = { + ts: { Icon: FileCodeIcon, color: 'teal' }, + tsx: { Icon: FileCodeIcon, color: 'teal' }, + js: { Icon: FileCodeIcon, color: 'gold' }, + jsx: { Icon: FileCodeIcon, color: 'gold' }, + json: { Icon: FileDataIcon, color: 'gold' }, + md: { Icon: FileDocIcon, color: 'warmGray' }, + css: { Icon: FileStyleIcon, color: 'coral' }, + scss: { Icon: FileStyleIcon, color: 'coral' }, + html: { Icon: FileWebIcon, color: 'teal' }, + png: { Icon: FileMediaIcon, color: 'coral' }, + jpg: { Icon: FileMediaIcon, color: 'coral' }, + jpeg: { Icon: FileMediaIcon, color: 'coral' }, + svg: { Icon: FileMediaIcon, color: 'coral' }, + gif: { Icon: FileMediaIcon, color: 'coral' }, + git: { Icon: FileConfigIcon, color: 'warmGray' }, + env: { Icon: FileConfigIcon, color: 'warmGray' }, + lock: { Icon: FileConfigIcon, color: 'warmGray' }, + yaml: { Icon: FileConfigIcon, color: 'warmGray' }, + yml: { Icon: FileConfigIcon, color: 'warmGray' }, +}; + function getFileIconInfo(name: string): FileIconInfo { const ext = name.split('.').pop()?.toLowerCase(); - const iconMap: Record<string, FileIconInfo> = { - ts: { Icon: FileCodeIcon, color: 'teal' }, - tsx: { Icon: FileCodeIcon, color: 'teal' }, - js: { Icon: FileCodeIcon, color: 'gold' }, - jsx: { Icon: FileCodeIcon, color: 'gold' }, - json: { Icon: FileDataIcon, color: 'gold' }, - md: { Icon: FileDocIcon, color: 'warmGray' }, - css: { Icon: FileStyleIcon, color: 'coral' }, - scss: { Icon: FileStyleIcon, color: 'coral' }, - html: { Icon: FileWebIcon, color: 'teal' }, - png: { Icon: FileMediaIcon, color: 'coral' }, - jpg: { Icon: FileMediaIcon, color: 'coral' }, - jpeg: { Icon: FileMediaIcon, color: 'coral' }, - svg: { Icon: FileMediaIcon, color: 'coral' }, - gif: { Icon: FileMediaIcon, color: 'coral' }, - git: { Icon: FileConfigIcon, color: 'warmGray' }, - env: { Icon: FileConfigIcon, color: 'warmGray' }, - lock: { Icon: FileConfigIcon, color: 'warmGray' }, - yaml: { Icon: FileConfigIcon, color: 'warmGray' }, - yml: { Icon: FileConfigIcon, color: 'warmGray' }, - }; - return iconMap[ext || ''] || { Icon: FileIcon, color: 'warmGray' }; + return FILE_ICON_MAP[ext || ''] || { Icon: FileIcon, color: 'warmGray' }; }app/agent/[id].tsx (1)
25-26: Avoid relying on globalReactnamespace forReact.FC.
IfallowUmdGlobalAccessisn’t enabled, this can fail type-checking. Prefer a typed import.♻️ Suggested fix
-import { useState } from 'react'; +import { useState, type FC } from 'react'; @@ -type AgentAvatarIcon = React.FC<{ size?: number; color?: IconColor; turbulence?: number }>; +type AgentAvatarIcon = FC<{ size?: number; color?: IconColor; turbulence?: number }>;app/(onboarding)/welcome.tsx (1)
14-73: NarrowFeature.iconto supported variants and avoid fallback masking.
IconVariantincludes many options, butFeatureIcononly supports four and defaults toAgentIcon, which can silently hide mismatches if a new feature is added. Consider narrowing the type and using a mapping for exhaustiveness.♻️ Suggested refactor
-import { +import { AgentIcon, MobileIcon, SecurityIcon, LightningIcon, ThumbIcon, - type IconVariant, } from '@/components/icons'; +type FeatureIconVariant = 'agent' | 'mobile' | 'security' | 'lightning'; + interface Feature { - icon: IconVariant; + icon: FeatureIconVariant; title: string; description: string; color: 'coral' | 'teal' | 'gold'; } +const FEATURE_ICONS: Record<FeatureIconVariant, typeof AgentIcon> = { + agent: AgentIcon, + mobile: MobileIcon, + security: SecurityIcon, + lightning: LightningIcon, +}; + /** Feature icon component that renders the appropriate paint daube icon */ -function FeatureIcon({ variant, color }: { variant: IconVariant; color: Feature['color'] }) { - const iconProps = { size: 28, color, turbulence: 0.25 }; - - switch (variant) { - case 'agent': - return <AgentIcon {...iconProps} />; - case 'mobile': - return <MobileIcon {...iconProps} />; - case 'security': - return <SecurityIcon {...iconProps} />; - case 'lightning': - return <LightningIcon {...iconProps} />; - default: - return <AgentIcon {...iconProps} />; - } +function FeatureIcon({ variant, color }: { variant: FeatureIconVariant; color: Feature['color'] }) { + const Icon = FEATURE_ICONS[variant]; + return <Icon size={28} color={color} turbulence={0.25} />; }
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/components/icons/PaintDaubeIcon.tsx`:
- Around line 22-32: BRAND_COLORS contains incorrect hex values for the brand
palette; update the coral, teal, and gold tokens inside the exported
BRAND_COLORS object so coral = "#FF7059", teal = "#0D9488", and gold =
"#F5D563", and ensure their corresponding dark variants (coralDark, tealDark,
goldDark) are adjusted to appropriate darker hexes consistent with the new base
colors (or regenerate them if your design system requires specific dark tokens)
while keeping the constant name BRAND_COLORS unchanged.
🧹 Nitpick comments (2)
src/components/icons/PaintDaubeIcon.tsx (2)
1044-1064: Clamp turbulence to the documented 0–1 range.
turbulenceis documented as 0–1 but passed through unchecked. A negative or large value can produce invalid or extreme filters. Consider clamping once inPaintDaubeIcon.♻️ Proposed fix
export function PaintDaubeIcon({ variant, color = 'coral', size = 24, turbulence = 0.3, seed = 42, }: PaintDaubeIconProps) { const filterId = `paint-daube-${variant}-${seed}`; + const clampedTurbulence = Math.max(0, Math.min(1, turbulence)); const strokeColor = BRAND_COLORS[color]; const pathData = ICON_PATHS[variant](seed); @@ - <PaintDaubeFilter id={filterId} turbulence={turbulence} /> + <PaintDaubeFilter id={filterId} turbulence={clampedTurbulence} />
798-975: Reduce duplication across file icon paths.*
file,fileCode,fileData,fileDoc,fileStyle,fileWeb,fileMedia,fileConfigrepeat the same outer file path. Consider extracting a shared base path builder to avoid drift and make edits cheaper.
- Add experiments.baseUrl: "/thumbcode" for GitHub Pages subdirectory - Inject no-cache meta tags into HTML files for staging environment - Fixes Expo app loading issue on GitHub Pages deployment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace all emojis with brand-aligned procedural SVG icons using feTurbulence filters for authentic paint texture effects. - Add PaintDaubeIcon component with 30+ icon variants - Create icon presets (AgentIcon, SecurityIcon, SuccessIcon, etc.) - Update onboarding screens with brand icons - Update tab navigation with consistent iconography - Replace feedback component icons (Toast, Progress, Modal) - Update form components (Checkbox, Select) with organic checkmarks - Update settings screens with brand-aligned icons - Add Icon component pattern for dynamic icon rendering Closes #70 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes linting warning about unused Circle import from react-native-svg. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused React imports (now using new JSX transform) - Fix import type annotations for type-only imports - Organize imports alphabetically per Biome rules - Remove unused function parameters or prefix with underscore - Fix formatting issues in tab layout component Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
41640f0 to
766eb9c
Compare
Updated icon color constants to match the documented brand palette: - Coral: #F28B7D → #FF7059 (Thumb Coral) - Teal: #51AFB9 → #0D9488 (Digital Teal) - Gold: #F2CF79 → #F5D563 (Soft Gold) - Charcoal: #1E1B18 → #151820 (Charcoal Navy) Dark variants updated to match light mode specifications from CLAUDE.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Fixed brand colors in commit 3145440 - Brand colors now align with CLAUDE.md P3 palette:
|
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @.github/workflows/deploy-gh-pages.yml:
- Around line 128-132: The "Inject no-cache headers for staging" step is
searching the wrong directory; change the find invocations that reference "dist"
to "docs-dist" so the sed injection and the file count (the find ... | wc -l in
the echo) operate on the built documentation; update both the find used for sed
and the find used in the echo to use "docs-dist" (preserve the existing sed
expression and step name).
In `@src/components/icons/PaintDaubeIcon.tsx`:
- Around line 21-31: BRAND_COLORS currently exposes charcoal and warmGray which
lets IconColor include neutrals; either remove those neutrals from BRAND_COLORS
and keep only coral/teal/gold, or move them into a separate NEUTRAL_COLORS
constant and update the IconColor type to only include the three brand keys.
Concretely: modify BRAND_COLORS to contain only coral, coralDark, teal,
tealDark, gold, goldDark; create a new NEUTRAL_COLORS with charcoal and
warmGray; and change the IconColor type/exports to be the union of only the
brand color keys (e.g., 'coral'|'coralDark'|'teal'|'tealDark'|'gold'|'goldDark')
so neutral colors cannot be used as IconColor.
🧹 Nitpick comments (4)
src/components/error/ErrorFallback.tsx (1)
61-61: Optional: drop redundantcolorprop.
ErrorIconalready defaults to coral; consider omittingcolor="coral"to reduce repetition unless you want the explicit override.src/components/chat/ApprovalCard.tsx (1)
40-54: Optional: hoist the action map to avoid per-call allocations.This keeps
getActionInfolightweight and avoids recreating the same object on each call.♻️ Proposed refactor
- function getActionInfo(actionType: ApprovalMessage['metadata']['actionType']): ActionInfo { - const actionMap: Record<ApprovalMessage['metadata']['actionType'], ActionInfo> = { - commit: { Icon: EditIcon, iconColor: 'teal', label: 'Commit Changes', bgColor: 'bg-teal-500' }, - push: { Icon: GitIcon, iconColor: 'coral', label: 'Push to Remote', bgColor: 'bg-coral-500' }, - merge: { Icon: BranchIcon, iconColor: 'gold', label: 'Merge Branch', bgColor: 'bg-gold-500' }, - deploy: { Icon: LightningIcon, iconColor: 'coral', label: 'Deploy', bgColor: 'bg-coral-600' }, - file_change: { - Icon: FileIcon, - iconColor: 'teal', - label: 'File Changes', - bgColor: 'bg-teal-600', - }, - }; - return actionMap[actionType] || actionMap.commit; -} +const ACTION_INFO_MAP: Record<ApprovalMessage['metadata']['actionType'], ActionInfo> = { + commit: { Icon: EditIcon, iconColor: 'teal', label: 'Commit Changes', bgColor: 'bg-teal-500' }, + push: { Icon: GitIcon, iconColor: 'coral', label: 'Push to Remote', bgColor: 'bg-coral-500' }, + merge: { Icon: BranchIcon, iconColor: 'gold', label: 'Merge Branch', bgColor: 'bg-gold-500' }, + deploy: { Icon: LightningIcon, iconColor: 'coral', label: 'Deploy', bgColor: 'bg-coral-600' }, + file_change: { + Icon: FileIcon, + iconColor: 'teal', + label: 'File Changes', + bgColor: 'bg-teal-600', + }, +}; + +function getActionInfo(actionType: ApprovalMessage['metadata']['actionType']): ActionInfo { + return ACTION_INFO_MAP[actionType] || ACTION_INFO_MAP.commit; +}app/(onboarding)/welcome.tsx (1)
56-71: Avoid silent fallback for unsupported feature iconsThe default case returns
AgentIcon, so a new or mistyped variant would render the wrong icon without any signal. Consider an explicit lookup map (or a guard) so unsupported variants fail loudly or render nothing.🔧 Example adjustment
- function FeatureIcon({ variant, color }: { variant: IconVariant; color: Feature['color'] }) { - const iconProps = { size: 28, color, turbulence: 0.25 }; - - switch (variant) { - case 'agent': - return <AgentIcon {...iconProps} />; - case 'mobile': - return <MobileIcon {...iconProps} />; - case 'security': - return <SecurityIcon {...iconProps} />; - case 'lightning': - return <LightningIcon {...iconProps} />; - default: - return <AgentIcon {...iconProps} />; - } - } +const FEATURE_ICON_MAP = { + agent: AgentIcon, + mobile: MobileIcon, + security: SecurityIcon, + lightning: LightningIcon, +} as const; + +function FeatureIcon({ variant, color }: { variant: IconVariant; color: Feature['color'] }) { + const iconProps = { size: 28, color, turbulence: 0.25 }; + const Icon = FEATURE_ICON_MAP[variant]; + return Icon ? <Icon {...iconProps} /> : null; +}app/(tabs)/agents.tsx (1)
27-28: Consider extracting theAgentAvatarIcontype to a shared location.This type definition (
React.FC<{ size?: number; color?: IconColor; turbulence?: number }>) is duplicated across multiple files (agents.tsx,chat.tsx,complete.tsx). Extracting it to@/components/iconswould reduce duplication and ensure consistency.♻️ Suggested refactor in src/components/icons/index.ts
// Add to the icons barrel export export type IconComponentProps = { size?: number; color?: IconColor; turbulence?: number; }; export type IconComponent = React.FC<IconComponentProps>;Then import and use across consumer files:
-type AgentAvatarIcon = React.FC<{ size?: number; color?: IconColor; turbulence?: number }>; +import { type IconComponent } from '@/components/icons'; +type AgentAvatarIcon = IconComponent;
| - name: Inject no-cache headers for staging | ||
| run: | | ||
| # Add no-cache meta tags to all HTML files for staging environment | ||
| find dist -name "*.html" -exec sed -i 's/<head>/<head>\n <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">\n <meta http-equiv="Pragma" content="no-cache">\n <meta http-equiv="Expires" content="0">/' {} \; | ||
| echo "Injected no-cache headers into $(find dist -name '*.html' | wc -l) HTML files" |
There was a problem hiding this comment.
Wrong directory: dist should be docs-dist.
The documentation is built to docs-dist/ (see lines 52, 140), but this step searches in dist/. The find command will either fail or find zero files, so no cache headers will be injected.
🐛 Proposed fix
- name: Inject no-cache headers for staging
run: |
# Add no-cache meta tags to all HTML files for staging environment
- find dist -name "*.html" -exec sed -i 's/<head>/<head>\n <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">\n <meta http-equiv="Pragma" content="no-cache">\n <meta http-equiv="Expires" content="0">/' {} \;
- echo "Injected no-cache headers into $(find dist -name '*.html' | wc -l) HTML files"
+ find docs-dist -name "*.html" -exec sed -i 's/<head>/<head>\n <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">\n <meta http-equiv="Pragma" content="no-cache">\n <meta http-equiv="Expires" content="0">/' {} \;
+ echo "Injected no-cache headers into $(find docs-dist -name '*.html' | wc -l) HTML files"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Inject no-cache headers for staging | |
| run: | | |
| # Add no-cache meta tags to all HTML files for staging environment | |
| find dist -name "*.html" -exec sed -i 's/<head>/<head>\n <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">\n <meta http-equiv="Pragma" content="no-cache">\n <meta http-equiv="Expires" content="0">/' {} \; | |
| echo "Injected no-cache headers into $(find dist -name '*.html' | wc -l) HTML files" | |
| - name: Inject no-cache headers for staging | |
| run: | | |
| # Add no-cache meta tags to all HTML files for staging environment | |
| find docs-dist -name "*.html" -exec sed -i 's/<head>/<head>\n <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">\n <meta http-equiv="Pragma" content="no-cache">\n <meta http-equiv="Expires" content="0">/' {} \; | |
| echo "Injected no-cache headers into $(find docs-dist -name '*.html' | wc -l) HTML files" |
🤖 Prompt for AI Agents
In @.github/workflows/deploy-gh-pages.yml around lines 128 - 132, The "Inject
no-cache headers for staging" step is searching the wrong directory; change the
find invocations that reference "dist" to "docs-dist" so the sed injection and
the file count (the find ... | wc -l in the echo) operate on the built
documentation; update both the find used for sed and the find used in the echo
to use "docs-dist" (preserve the existing sed expression and step name).
| // Brand color hex values aligned with CLAUDE.md P3 "Warm Technical" palette | ||
| export const BRAND_COLORS = { | ||
| coral: '#FF7059', // Primary - Thumb Coral | ||
| coralDark: '#E85A4F', // Light mode variant | ||
| teal: '#0D9488', // Secondary - Digital Teal | ||
| tealDark: '#0F766E', // Light mode variant | ||
| gold: '#F5D563', // Accent - Soft Gold | ||
| goldDark: '#D4A84B', // Light mode variant | ||
| charcoal: '#151820', // Base Dark - Charcoal Navy | ||
| warmGray: '#696259', | ||
| } as const; |
There was a problem hiding this comment.
Brand palette mismatch: neutrals are exposed as IconColor
The header comment and PR objectives state icons should use only coral/teal/gold, but BRAND_COLORS (and thus IconColor) includes charcoal and warmGray, enabling non‑palette icon colors across the app. Either restrict IconColor to the three brand colors or explicitly update the guidelines to allow neutrals and keep them in a separate map/type to prevent accidental use.
💡 Possible direction
export const BRAND_COLORS = {
coral: '#FF7059',
- coralDark: '#E85A4F',
teal: '#0D9488',
- tealDark: '#0F766E',
gold: '#F5D563',
- goldDark: '#D4A84B',
- charcoal: '#151820',
- warmGray: '#696259',
} as const;
export type IconColor = keyof typeof BRAND_COLORS;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Brand color hex values aligned with CLAUDE.md P3 "Warm Technical" palette | |
| export const BRAND_COLORS = { | |
| coral: '#FF7059', // Primary - Thumb Coral | |
| coralDark: '#E85A4F', // Light mode variant | |
| teal: '#0D9488', // Secondary - Digital Teal | |
| tealDark: '#0F766E', // Light mode variant | |
| gold: '#F5D563', // Accent - Soft Gold | |
| goldDark: '#D4A84B', // Light mode variant | |
| charcoal: '#151820', // Base Dark - Charcoal Navy | |
| warmGray: '#696259', | |
| } as const; | |
| // Brand color hex values aligned with CLAUDE.md P3 "Warm Technical" palette | |
| export const BRAND_COLORS = { | |
| coral: '#FF7059', // Primary - Thumb Coral | |
| teal: '#0D9488', // Secondary - Digital Teal | |
| gold: '#F5D563', // Accent - Soft Gold | |
| charcoal: '#151820', // Base Dark - Charcoal Navy | |
| warmGray: '#696259', | |
| } as const; | |
| export type IconColor = keyof typeof BRAND_COLORS; |
| // Brand color hex values aligned with CLAUDE.md P3 "Warm Technical" palette | |
| export const BRAND_COLORS = { | |
| coral: '#FF7059', // Primary - Thumb Coral | |
| coralDark: '#E85A4F', // Light mode variant | |
| teal: '#0D9488', // Secondary - Digital Teal | |
| tealDark: '#0F766E', // Light mode variant | |
| gold: '#F5D563', // Accent - Soft Gold | |
| goldDark: '#D4A84B', // Light mode variant | |
| charcoal: '#151820', // Base Dark - Charcoal Navy | |
| warmGray: '#696259', | |
| } as const; | |
| // Brand color hex values aligned with CLAUDE.md P3 "Warm Technical" palette | |
| export const BRAND_COLORS = { | |
| coral: '#FF7059', // Primary - Thumb Coral | |
| teal: '#0D9488', // Secondary - Digital Teal | |
| gold: '#F5D563', // Accent - Soft Gold | |
| } as const; | |
| export type IconColor = keyof typeof BRAND_COLORS; |
🤖 Prompt for AI Agents
In `@src/components/icons/PaintDaubeIcon.tsx` around lines 21 - 31, BRAND_COLORS
currently exposes charcoal and warmGray which lets IconColor include neutrals;
either remove those neutrals from BRAND_COLORS and keep only coral/teal/gold, or
move them into a separate NEUTRAL_COLORS constant and update the IconColor type
to only include the three brand keys. Concretely: modify BRAND_COLORS to contain
only coral, coralDark, teal, tealDark, gold, goldDark; create a new
NEUTRAL_COLORS with charcoal and warmGray; and change the IconColor type/exports
to be the union of only the brand color keys (e.g.,
'coral'|'coralDark'|'teal'|'tealDark'|'gold'|'goldDark') so neutral colors
cannot be used as IconColor.


Summary
Changes
PaintDaubeIconcomponent with seeded pseudo-random offset generationTest plan
npx tsc --noEmit)Closes #70
🤖 Generated with Claude Code
Summary by CodeRabbit
Style
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.