diff --git a/apps/website/components/home/LeagueSummaryPanel.tsx b/apps/website/components/home/LeagueSummaryPanel.tsx
index 57cd40b3e..54a483fa8 100644
--- a/apps/website/components/home/LeagueSummaryPanel.tsx
+++ b/apps/website/components/home/LeagueSummaryPanel.tsx
@@ -1,6 +1,6 @@
'use client';
-import { LeagueCard } from '@/components/leagues/LeagueCard';
+import { LeagueCard } from '@/components/leagues/LeagueCardWrapper';
import { routes } from '@/lib/routing/RouteConfig';
import { Heading } from '@/ui/Heading';
import { Link } from '@/ui/Link';
@@ -46,15 +46,7 @@ export function LeagueSummaryPanel({ leagues }: LeagueSummaryPanelProps) {
{leagues.slice(0, 2).map((league) => (
))}
diff --git a/apps/website/components/landing/DiscoverySection.tsx b/apps/website/components/landing/DiscoverySection.tsx
index 0f5d36e1c..050c485f6 100644
--- a/apps/website/components/landing/DiscoverySection.tsx
+++ b/apps/website/components/landing/DiscoverySection.tsx
@@ -8,7 +8,7 @@ import { Grid } from '@/ui/Grid';
import { Heading } from '@/ui/Heading';
import { Link } from '@/ui/Link';
import { Text } from '@/ui/Text';
-import { LeagueCard } from '@/components/leagues/LeagueCard';
+import { LeagueCard } from '@/components/leagues/LeagueCardWrapper';
import { TeamCard } from '@/components/teams/TeamCard';
import { UpcomingRaceItem } from '@/components/races/UpcomingRaceItem';
import { HomeViewData } from '@/templates/HomeTemplate';
@@ -49,15 +49,7 @@ export function DiscoverySection({ viewData }: DiscoverySectionProps) {
{viewData.topLeagues.slice(0, 2).map((league) => (
))}
diff --git a/apps/website/components/leagues/LeagueCard.tsx b/apps/website/components/leagues/LeagueCard.tsx
deleted file mode 100644
index 067956764..000000000
--- a/apps/website/components/leagues/LeagueCard.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-'use client';
-
-import { Heading } from '@/ui/Heading';
-import { Icon } from '@/ui/Icon';
-import { Image } from '@/ui/Image';
-import { PlaceholderImage } from '@/ui/PlaceholderImage';
-import { Text } from '@/ui/Text';
-import { Box } from '@/ui/Box';
-import { Group } from '@/ui/Group';
-import { Surface } from '@/ui/Surface';
-import { Stack } from '@/ui/Stack';
-import { LeagueCard as UILeagueCard, LeagueCardStats, LeagueCardFooter } from '@/ui/LeagueCard';
-import { Calendar, Users, Activity } from 'lucide-react';
-import React, { ReactNode } from 'react';
-
-interface LeagueCardProps {
- name: string;
- description?: string;
- coverUrl: string;
- logoUrl?: string;
- badges?: ReactNode;
- championshipBadge?: ReactNode;
- slotLabel: string;
- usedSlots: number;
- maxSlots: number | string;
- fillPercentage: number;
- hasOpenSlots: boolean;
- openSlotsCount: number;
- isTeamLeague?: boolean;
- usedDriverSlots?: number;
- maxDrivers?: number | string;
- timingSummary?: string;
- onClick?: () => void;
-}
-
-export function LeagueCard({
- name,
- description,
- coverUrl,
- logoUrl,
- badges,
- championshipBadge,
- slotLabel,
- usedSlots,
- maxSlots,
- fillPercentage,
- hasOpenSlots,
- openSlotsCount,
- timingSummary,
- onClick,
-}: LeagueCardProps) {
- return (
-
- {logoUrl ? (
-
- ) : (
-
- )}
-
- }
- badges={
-
- {badges}
- {championshipBadge}
-
- }
- >
-
-
-
-
- {name}
-
-
- {description || 'No infrastructure description provided.'}
-
-
-
-
- = 90 ? 'warning' : fillPercentage >= 70 ? 'primary' : 'success'}
- />
-
- {hasOpenSlots && (
-
-
-
- {openSlotsCount} slots available
-
-
- )}
-
-
-
-
- {timingSummary && (
-
-
-
- {timingSummary.split('•')[1]?.trim() || timingSummary}
-
-
- )}
-
-
-
- {usedSlots} active participants
-
-
-
-
-
-
- );
-}
diff --git a/apps/website/components/leagues/LeagueCardWrapper.tsx b/apps/website/components/leagues/LeagueCardWrapper.tsx
index a2d435b0a..e60a57acf 100644
--- a/apps/website/components/leagues/LeagueCardWrapper.tsx
+++ b/apps/website/components/leagues/LeagueCardWrapper.tsx
@@ -11,7 +11,7 @@ import {
import type { LeagueSummaryViewModel } from '@/lib/view-models/LeagueSummaryViewModel';
import { getMediaUrl } from '@/lib/utilities/media';
import { Badge } from '@/ui/Badge';
-import { LeagueCard as UiLeagueCard } from './LeagueCard';
+import { LeagueCard as UiLeagueCard } from '@/ui/LeagueCard';
interface LeagueCardProps {
league: LeagueSummaryViewModel;
diff --git a/apps/website/components/teams/TeamCard.tsx b/apps/website/components/teams/TeamCard.tsx
index e6f576641..1721de13b 100644
--- a/apps/website/components/teams/TeamCard.tsx
+++ b/apps/website/components/teams/TeamCard.tsx
@@ -2,7 +2,7 @@
import React from 'react';
import { ChevronRight, Users, Zap } from 'lucide-react';
-import { Card } from '@/ui/Card';
+import { ProfileCard } from '@/ui/ProfileCard';
import { CountryFlag } from '@/ui/CountryFlag';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
@@ -11,7 +11,6 @@ import { Text } from '@/ui/Text';
import { Badge } from '@/ui/Badge';
import { Stack } from '@/ui/Stack';
import { Grid } from '@/ui/Grid';
-import { Box } from '@/ui/Box';
import { TeamSummaryData } from '@/lib/view-data/TeamsViewData';
interface TeamCardProps {
@@ -60,24 +59,10 @@ export function TeamCard({
};
return (
- onClick?.(data.teamId)}
- transition
- fullHeight
- position="relative"
- >
- {data.isRecruiting && (
-
-
- RECRUITING
-
-
- )}
-
-
- {/* Header: Logo and Identity */}
+ identity={
{data.teamName}
-
- {data.performanceLevel && (
-
-
- {data.performanceLevel}
-
- )}
-
-
-
-
- {/* Technical Stats Grid - Engineered Look */}
-
-
- Rating
- {data.ratingLabel}
-
-
- Wins
- {data.winsLabel}
-
-
- Races
- {data.racesLabel}
-
-
-
- {data.description && (
-
- {data.description}
-
- )}
-
- {/* Spacer to push footer down */}
-
-
- {/* Footer: Metadata */}
-
-
-
-
- {data.memberCount}
-
- {data.countryCode && (
-
-
- {data.countryCode}
+ {data.performanceLevel && (
+
+
+ {data.performanceLevel}
)}
-
-
- Details
-
+
+ }
+ actions={
+ data.isRecruiting ? (
+
+ RECRUITING
+
+ ) : undefined
+ }
+ stats={
+
+
+
+ Rating
+ {data.ratingLabel}
+
+
+ Wins
+ {data.winsLabel}
+
+
+ Races
+ {data.racesLabel}
+
+
+
+
+
+
+
+ {data.memberCount}
+
+ {data.countryCode && (
+
+
+ {data.countryCode}
+
+ )}
+
+
-
-
+ }
+ />
);
}
diff --git a/apps/website/ui/LeagueCard.tsx b/apps/website/ui/LeagueCard.tsx
index 6bf6bb5de..174dcce8f 100644
--- a/apps/website/ui/LeagueCard.tsx
+++ b/apps/website/ui/LeagueCard.tsx
@@ -1,4 +1,4 @@
-import { ChevronRight } from 'lucide-react';
+import { ChevronRight, Users, Clock } from 'lucide-react';
import { ReactNode } from 'react';
import { Box } from './Box';
import { Card } from './Card';
@@ -7,16 +7,47 @@ import { Image } from './Image';
import { Text } from './Text';
import { Stack } from './Stack';
import { Group } from './Group';
+import { Heading } from './Heading';
export interface LeagueCardProps {
- children: ReactNode;
- onClick?: () => void;
+ name: string;
+ description?: string;
coverUrl: string;
- logo?: ReactNode;
+ logoUrl?: string;
+ slotLabel: string;
+ usedSlots: number;
+ maxSlots: number | string;
+ fillPercentage: number;
+ hasOpenSlots: boolean;
+ openSlotsCount: number;
+ isTeamLeague: boolean;
+ usedDriverSlots?: number;
+ maxDrivers?: number;
+ timingSummary?: string;
+ onClick?: () => void;
badges?: ReactNode;
+ championshipBadge?: ReactNode;
}
-export const LeagueCard = ({ children, onClick, coverUrl, logo, badges }: LeagueCardProps) => {
+export const LeagueCard = ({
+ name,
+ description,
+ coverUrl,
+ logoUrl,
+ slotLabel,
+ usedSlots,
+ maxSlots,
+ fillPercentage,
+ hasOpenSlots,
+ openSlotsCount,
+ isTeamLeague,
+ usedDriverSlots,
+ maxDrivers,
+ timingSummary,
+ onClick,
+ badges,
+ championshipBadge
+}: LeagueCardProps) => {
return (
-
+
-
+
{badges}
- {logo && (
-
- {logo}
+
+
+
+
+
+ {logoUrl ? (
+
+ ) : (
+
+ )}
+
+
+ {name}
+
+ {championshipBadge}
+
+
+
+ {description && (
+
+ {description}
+
)}
-
-
- {children}
-
+
+
+
+
+
+
+ {slotLabel}
+ {usedSlots} / {maxSlots}
+
+
+
+
+
+
+
+
+
+
+ {timingSummary || 'Schedule TBD'}
+
+
+
+
+
+
);
};
diff --git a/apps/website/ui/ProfileCard.tsx b/apps/website/ui/ProfileCard.tsx
index fbb64d7e3..7c917af34 100644
--- a/apps/website/ui/ProfileCard.tsx
+++ b/apps/website/ui/ProfileCard.tsx
@@ -6,7 +6,7 @@ export interface ProfileCardProps {
identity: ReactNode;
stats?: ReactNode;
actions?: ReactNode;
- variant?: 'default' | 'muted' | 'outline' | 'glass';
+ variant?: 'default' | 'muted' | 'outline' | 'glass' | 'precision';
onClick?: () => void;
}