Skip to content

Commit 5a3f067

Browse files
adamintCopilot
andcommitted
Add vibrant jewel-tone color accents across UI
- WorldCard: colored icon backgrounds and hover glows per world order - Sidebar: colored dots for Playground (teal), Concept Map (emerald), Gallery (amber), Weekly Challenge (rose) - GalleryPage: category filter pills use per-category accent colors - LeaderboardPage: gold/silver/bronze borders and shadows for top 3 - AchievementsPage: rarity-colored top border and hover glow on cards - HomePage footer CTA: subtle multi-color gradient background Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e228ff6 commit 5a3f067

6 files changed

Lines changed: 30 additions & 22 deletions

File tree

AspireAcademy.Web/src/components/curriculum/WorldCard.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export default function WorldCard({ world }: WorldCardProps) {
1919
const navigate = useNavigate();
2020

2121
const progress = world.totalLessons > 0 ? world.completionPercentage : 0;
22+
const worldAccents = ['#2DD4BF', '#FBBF24', '#FB7185', '#34D399', '#38BDF8', '#FB923C', '#A78BFA', '#F472B6'];
23+
const accent = worldAccents[(world.sortOrder - 1) % worldAccents.length];
2224

2325
const handleClick = () => {
2426
if (!world.isLocked) {
@@ -35,7 +37,7 @@ export default function WorldCard({ world }: WorldCardProps) {
3537
opacity={world.isLocked ? 0.6 : 1}
3638
filter={world.isLocked ? 'grayscale(100%)' : 'none'}
3739
transition="transform 0.15s ease, box-shadow 0.15s ease"
38-
_hover={world.isLocked ? {} : { transform: 'translateY(-2px)' }}
40+
_hover={world.isLocked ? {} : { transform: 'translateY(-2px)', borderColor: accent, boxShadow: `0 4px 16px ${accent}33, 4px 4px 0 var(--chakra-colors-game-pixel-shadow, #2B1260)` }}
3941
onClick={handleClick}
4042
title={world.isLocked ? `${world.name} - Locked` : `Open ${world.name} world`}
4143
aria-label={world.isLocked ? `${world.name} world - Locked` : `Open ${world.name} world`}
@@ -56,17 +58,18 @@ export default function WorldCard({ world }: WorldCardProps) {
5658
w="11"
5759
h="11"
5860
borderRadius="sm"
59-
bg={world.isLocked ? 'game.locked' : 'game.pixelBorder'}
61+
bg={world.isLocked ? 'game.locked' : `${accent}22`}
6062
color="dark.text"
6163
fontSize="xl"
64+
border={world.isLocked ? undefined : `1px solid ${accent}44`}
6265
>
6366
{world.isLocked ? <FiLock /> : world.icon}
6467
</Flex>
6568
<Box flex="1" minW="0">
6669
<Text fontWeight="semibold" fontSize="md" truncate>
6770
{world.name}
6871
</Text>
69-
<Text {...pixelFontProps} fontSize="2xs" color="aspire.accent">
72+
<Text {...pixelFontProps} fontSize="2xs" color={world.isLocked ? 'dark.muted' : accent}>
7073
World {world.sortOrder}
7174
</Text>
7275
</Box>

AspireAcademy.Web/src/components/layout/Sidebar.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,16 @@ export function Sidebar({ open, onClose }: SidebarProps) {
276276
>
277277
Explore
278278
</Text>
279-
<SideNavLink to="/playground" icon={<FiCpu size={16} />} onClose={onClose}>
279+
<SideNavLink to="/playground" icon={<Flex align="center" gap="0"><Box w="6px" h="6px" borderRadius="full" bg="#2DD4BF" mr="2" flexShrink={0} /><FiCpu size={16} /></Flex>} onClose={onClose}>
280280
Playground
281281
</SideNavLink>
282-
<SideNavLink to="/concept-map" icon={<FiMap size={16} />} onClose={onClose}>
282+
<SideNavLink to="/concept-map" icon={<Flex align="center" gap="0"><Box w="6px" h="6px" borderRadius="full" bg="#34D399" mr="2" flexShrink={0} /><FiMap size={16} /></Flex>} onClose={onClose}>
283283
Concept Map
284284
</SideNavLink>
285-
<SideNavLink to="/gallery" icon={<FiImage size={16} />} onClose={onClose}>
285+
<SideNavLink to="/gallery" icon={<Flex align="center" gap="0"><Box w="6px" h="6px" borderRadius="full" bg="#FBBF24" mr="2" flexShrink={0} /><FiImage size={16} /></Flex>} onClose={onClose}>
286286
Gallery
287287
</SideNavLink>
288-
<SideNavLink to="/weekly-challenge" icon={<FiTarget size={16} />} onClose={onClose}>
288+
<SideNavLink to="/weekly-challenge" icon={<Flex align="center" gap="0"><Box w="6px" h="6px" borderRadius="full" bg="#FB7185" mr="2" flexShrink={0} /><FiTarget size={16} /></Flex>} onClose={onClose}>
289289
Weekly Challenge
290290
</SideNavLink>
291291
<SideNavLink to="/whats-new" icon={<FiStar size={16} />} onClose={onClose}>

AspireAcademy.Web/src/pages/AchievementsPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,14 @@ export default function AchievementsPage() {
132132
textAlign="center"
133133
cursor={ach.isUnlocked ? 'pointer' : 'default'}
134134
transition="transform 0.15s ease"
135-
_hover={ach.isUnlocked ? { transform: 'translateY(-2px)' } : undefined}
135+
_hover={ach.isUnlocked ? { transform: 'translateY(-2px)', boxShadow: `0 4px 16px ${rarityColors[ach.rarity]}44, 4px 4px 0 var(--chakra-colors-game-pixel-shadow, #2B1260)` } : undefined}
136136
position="relative"
137137
borderColor={rarityColors[ach.rarity]}
138138
filter={ach.isUnlocked ? undefined : 'grayscale(100%)'}
139139
opacity={ach.isUnlocked ? 1 : 0.6}
140140
onClick={() => ach.isUnlocked && setSelected(ach)}
141+
bg={ach.isUnlocked ? undefined : 'dark.card'}
142+
css={ach.isUnlocked ? { borderTopWidth: '3px', borderTopColor: rarityColors[ach.rarity] } : undefined}
141143
>
142144
{/* Lock overlay for locked achievements */}
143145
{!ach.isUnlocked && (

AspireAcademy.Web/src/pages/GalleryPage.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ interface GalleryEntry {
108108
}
109109

110110
const CATEGORIES = [
111-
{ label: 'All', value: 'all', icon: '🏛️' },
112-
{ label: 'Web & Commerce', value: 'Web & Commerce', icon: '🌐' },
113-
{ label: 'AI & Intelligence', value: 'AI & Intelligence', icon: '🤖' },
114-
{ label: 'Data & Streaming', value: 'Data & Streaming', icon: '📊' },
115-
{ label: 'Event-Driven', value: 'Event-Driven', icon: '⚡' },
116-
{ label: 'Enterprise', value: 'Enterprise', icon: '🏢' },
111+
{ label: 'All', value: 'all', icon: '🏛️', accent: '#A78BFA' },
112+
{ label: 'Web & Commerce', value: 'Web & Commerce', icon: '🌐', accent: '#2DD4BF' },
113+
{ label: 'AI & Intelligence', value: 'AI & Intelligence', icon: '🤖', accent: '#38BDF8' },
114+
{ label: 'Data & Streaming', value: 'Data & Streaming', icon: '📊', accent: '#FBBF24' },
115+
{ label: 'Event-Driven', value: 'Event-Driven', icon: '⚡', accent: '#FB923C' },
116+
{ label: 'Enterprise', value: 'Enterprise', icon: '🏢', accent: '#34D399' },
117117
];
118118

119119
const difficultyConfig = {
@@ -1434,9 +1434,9 @@ export default function GalleryPage() {
14341434
size="xs"
14351435
variant="ghost"
14361436
onClick={() => setActiveCategory(cat.value)}
1437-
bg={isActive ? 'aspire.200' : 'transparent'}
1438-
color={isActive ? 'aspire.accent' : 'dark.muted'}
1439-
_hover={{ bg: isActive ? 'aspire.200' : 'dark.card' }}
1437+
bg={isActive ? `${cat.accent}22` : 'transparent'}
1438+
color={isActive ? cat.accent : 'dark.muted'}
1439+
_hover={{ bg: isActive ? `${cat.accent}22` : 'dark.card' }}
14401440
{...pixelFontProps}
14411441
fontSize="9px"
14421442
px="3"
@@ -1448,8 +1448,8 @@ export default function GalleryPage() {
14481448
<Badge
14491449
ml="1.5"
14501450
fontSize="2xs"
1451-
bg={isActive ? 'aspire.300' : 'dark.border'}
1452-
color={isActive ? 'aspire.500' : 'dark.muted'}
1451+
bg={isActive ? `${cat.accent}33` : 'dark.border'}
1452+
color={isActive ? cat.accent : 'dark.muted'}
14531453
px="1.5"
14541454
borderRadius="full"
14551455
minW="18px"

AspireAcademy.Web/src/pages/HomePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ export default function HomePage() {
10341034
data-testid="footer-cta"
10351035
py={{ base: '16', md: '20' }}
10361036
px="4"
1037-
bg="dark.surface"
1037+
background="linear-gradient(135deg, var(--chakra-colors-dark-surface) 0%, rgba(45,212,191,0.06) 40%, rgba(107,79,187,0.08) 70%, var(--chakra-colors-dark-surface) 100%)"
10381038
textAlign="center"
10391039
>
10401040
<Text {...pixelFontProps} fontSize={{ base: '14px', md: '20px' }} color="aspire.accent" mb="4">

AspireAcademy.Web/src/pages/LeaderboardPage.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,18 @@ export default function LeaderboardPage() {
138138
{entries.map((entry) => {
139139
const isCurrentUser = entry.userId === currentUser?.id;
140140
const isTop3 = entry.rank <= 3;
141+
const podiumColors: Record<number, string> = { 1: '#FFD700', 2: '#C0C0C0', 3: '#CD7F32' };
142+
const podiumBg: Record<number, string> = { 1: 'rgba(255,215,0,0.08)', 2: 'rgba(192,192,192,0.06)', 3: 'rgba(205,127,50,0.06)' };
141143
return (
142144
<Flex
143145
key={entry.userId}
144146
{...retroCardProps}
145147
p={3}
146148
alignItems="center"
147149
gap={4}
148-
bg={isCurrentUser ? 'aspire.50' : isTop3 ? 'rgba(255, 215, 0, 0.05)' : undefined}
149-
borderColor={isCurrentUser ? 'aspire.600' : isTop3 ? 'rgba(255, 215, 0, 0.3)' : 'game.pixelBorder'}
150+
bg={isCurrentUser ? 'aspire.50' : isTop3 ? podiumBg[entry.rank] : undefined}
151+
borderColor={isCurrentUser ? 'aspire.600' : isTop3 ? podiumColors[entry.rank] : 'game.pixelBorder'}
152+
boxShadow={isTop3 ? `4px 4px 0 ${podiumColors[entry.rank]}33` : undefined}
150153
>
151154
{/* Rank */}
152155
<Box w="48px" textAlign="center" flexShrink={0}>

0 commit comments

Comments
 (0)