Files
gridpilot.gg/apps/website/ui/FeatureGrid.tsx
2026-01-15 17:12:24 +01:00

102 lines
4.7 KiB
TypeScript

'use client';
import { useRef, useState, useEffect } from 'react';
import { Section } from '@/ui/Section';
import { Container } from '@/ui/Container';
import { Heading } from '@/ui/Heading';
import { MockupStack } from '@/ui/MockupStack';
import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { LeagueHomeMockup } from '@/components/mockups/LeagueHomeMockup';
import { StandingsTableMockup } from '@/components/mockups/StandingsTableMockup';
import { TeamCompetitionMockup } from '@/components/mockups/TeamCompetitionMockup';
import { ProtestWorkflowMockup } from '@/components/mockups/ProtestWorkflowMockup';
import { LeagueDiscoveryMockup } from '@/components/mockups/LeagueDiscoveryMockup';
import { DriverProfileMockup } from '@/components/mockups/DriverProfileMockup';
const features = [
{
title: "A Real Home for Your League",
description: "Stop juggling Discord, spreadsheets, and iRacing admin panels. GridPilot brings everything into one dedicated platform built specifically for league racing.",
MockupComponent: LeagueHomeMockup
},
{
title: "Automatic Results & Standings",
description: "Race happens. Results appear. Standings update. No manual data entry, no spreadsheet formulas, no waiting for someone to publish.",
MockupComponent: StandingsTableMockup
},
{
title: "Real Team Racing",
description: "Constructors' championships that actually matter. Driver lineups. Team strategies. Multi-class racing done right.",
MockupComponent: TeamCompetitionMockup
},
{
title: "Clean Protests & Penalties",
description: "Structured incident reporting with video clip references. Steward review workflows. Transparent penalty application. Professional race control.",
MockupComponent: ProtestWorkflowMockup
},
{
title: "Find Your Perfect League",
description: "Search and discover leagues by game, region, and skill level. Browse featured competitions, check driver counts, and join communities that match your racing style.",
MockupComponent: LeagueDiscoveryMockup
},
{
title: "Your Racing Identity",
description: "Cross-league driver profiles with career stats, achievements, and racing history. Build your reputation across multiple championships and showcase your progression.",
MockupComponent: DriverProfileMockup
}
];
function FeatureCard({ feature, index }: { feature: typeof features[0], index: number }) {
return (
<Box
display="flex"
flexDirection="column"
gap={6}
group
>
<Box aspectRatio="video" fullWidth position="relative">
<Box position="absolute" inset="-0.5" bg="linear-gradient(to right, rgba(239, 68, 68, 0.2), rgba(59, 130, 246, 0.2), rgba(239, 68, 68, 0.2))" rounded="lg" opacity={0} groupHoverOpacity={1} transition blur="sm" />
<Box position="relative">
<MockupStack index={index}>
<feature.MockupComponent />
</MockupStack>
</Box>
</Box>
<Stack gap={3}>
<Box display="flex" alignItems="center" gap={2}>
<Heading level={3} weight="medium" style={{ background: 'linear-gradient(to right, #dc2626, #ffffff, #2563eb)', backgroundClip: 'text', WebkitBackgroundClip: 'text', color: 'transparent', filter: 'drop-shadow(0 0 15px rgba(220,0,0,0.4))', WebkitTextStroke: '0.5px rgba(220,0,0,0.2)' }}>
{feature.title}
</Heading>
</Box>
<Text size={{ base: 'sm', sm: 'base' }} color="text-gray-400" weight="light" leading="relaxed">
{feature.description}
</Text>
</Stack>
</Box>
);
}
export function FeatureGrid() {
return (
<Section variant="default">
<Container position="relative" zIndex={10}>
<Container size="sm" center>
<Box>
<Heading level={2} weight="semibold" style={{ background: 'linear-gradient(to right, #dc2626, #ffffff, #2563eb)', backgroundClip: 'text', WebkitBackgroundClip: 'text', color: 'transparent', filter: 'drop-shadow(0 0 20px rgba(220,0,0,0.5))', WebkitTextStroke: '1px rgba(220,0,0,0.2)' }}>
Building for League Racing
</Heading>
<Text size={{ base: 'base', sm: 'lg' }} color="text-gray-400" block mt={{ base: 4, sm: 6 }}>
These features are in development. Join the community to help shape what gets built first
</Text>
</Box>
</Container>
<Box mx="auto" mt={{ base: 8, sm: 12, md: 16 }} display="grid" gridCols={{ base: 1, lg: 2, xl: 3 }} gap={{ base: 10, sm: 12, md: 16 }} maxWidth={{ base: '2xl', lg: 'none' }}>
{features.map((feature, index) => (
<FeatureCard key={feature.title} feature={feature} index={index} />
))}
</Box>
</Container>
</Section>
);
}