website refactor
This commit is contained in:
@@ -1,77 +1,45 @@
|
||||
import { AppFooter } from '@/components/app/AppFooter';
|
||||
import { Grid } from '@/ui/Grid';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { Container } from '@/ui/Container';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Link } from '@/ui/Link';
|
||||
import { BrandMark } from '@/ui/BrandMark';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { BrandMark } from '@/ui/BrandMark';
|
||||
|
||||
export interface GlobalFooterViewData {}
|
||||
|
||||
export function GlobalFooterTemplate(_props: GlobalFooterViewData) {
|
||||
return (
|
||||
<AppFooter>
|
||||
<Grid cols={{ base: 1, md: 4 }} gap={12}>
|
||||
<Stack colSpan={{ base: 1, md: 2 }} gap={6}>
|
||||
<Stack direction="row" align="center" gap={4}>
|
||||
<Surface as="footer" variant="muted" borderTop paddingY={6}>
|
||||
<Container size="full">
|
||||
<Box display="flex" flexDirection={{ base: 'col', md: 'row' }} alignItems="center" justifyContent="between" gap={4}>
|
||||
|
||||
{/* Left: Identity */}
|
||||
<Stack direction="row" align="center" gap={3}>
|
||||
<BrandMark />
|
||||
<Box display={{ base: 'none', sm: 'flex' }} alignItems="center" gap={2} borderLeft borderColor="var(--ui-color-border-default)" pl={4}>
|
||||
<Box w="4px" h="4px" rounded="full" bg="var(--ui-color-intent-primary)" animate="pulse" />
|
||||
<Text size="xs" variant="low" weight="bold" font="mono" letterSpacing="0.1em">
|
||||
INFRASTRUCTURE
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Stack maxWidth="sm">
|
||||
<Text variant="low" size="sm">
|
||||
The professional infrastructure for serious sim racing.
|
||||
Precision telemetry, automated results, and elite league management.
|
||||
<Text size="xs" variant="low" font="mono" uppercase letterSpacing="wider">
|
||||
// Infrastructure
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack gap={4}>
|
||||
<Text size="xs" weight="bold" variant="high" uppercase letterSpacing="wider">PLATFORM</Text>
|
||||
<Stack as="ul" direction="col" gap={2}>
|
||||
<Stack as="li">
|
||||
<Link href="/leagues" variant="secondary">
|
||||
Leagues
|
||||
</Link>
|
||||
</Stack>
|
||||
<Stack as="li">
|
||||
<Link href="/teams" variant="secondary">
|
||||
Teams
|
||||
</Link>
|
||||
</Stack>
|
||||
<Stack as="li">
|
||||
<Link href="/leaderboards" variant="secondary">
|
||||
Leaderboards
|
||||
</Link>
|
||||
</Stack>
|
||||
|
||||
{/* Center: Technical Links */}
|
||||
<Stack direction="row" gap={6} display={{ base: 'none', md: 'flex' }}>
|
||||
<Link href="/leagues" variant="secondary" size="xs" underline="none">LEAGUES</Link>
|
||||
<Link href="/teams" variant="secondary" size="xs" underline="none">TEAMS</Link>
|
||||
<Link href="/docs" variant="secondary" size="xs" underline="none">DOCUMENTATION</Link>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack gap={4}>
|
||||
<Text size="xs" weight="bold" variant="high" uppercase letterSpacing="wider">SUPPORT</Text>
|
||||
<Stack as="ul" direction="col" gap={2}>
|
||||
<Stack as="li">
|
||||
<Link href="/docs" variant="secondary">
|
||||
Documentation
|
||||
</Link>
|
||||
</Stack>
|
||||
<Stack as="li">
|
||||
<Link href="/status" variant="secondary">
|
||||
System Status
|
||||
</Link>
|
||||
</Stack>
|
||||
<Stack as="li">
|
||||
<Link href="/contact" variant="secondary">
|
||||
Contact
|
||||
</Link>
|
||||
</Stack>
|
||||
|
||||
{/* Right: System Status */}
|
||||
<Stack direction="row" align="center" gap={4}>
|
||||
<Box display="flex" alignItems="center" gap={2}>
|
||||
<Box w="6px" h="6px" rounded="full" bg="var(--ui-color-intent-success)" animate="pulse" />
|
||||
<Text size="xs" variant="low" font="mono">SYSTEM NOMINAL</Text>
|
||||
</Box>
|
||||
<Text size="xs" variant="low" font="mono">v1.0.0</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Grid>
|
||||
</AppFooter>
|
||||
|
||||
</Box>
|
||||
</Container>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,16 +41,17 @@ export function RootAppShellTemplate({ children }: RootAppShellViewData) {
|
||||
</TopNav>
|
||||
</ControlBar>
|
||||
|
||||
<Box display="flex" flexGrow={1}>
|
||||
<Box display="flex" flexGrow={1} width="full">
|
||||
{showSidebar && <GlobalSidebarTemplate />}
|
||||
|
||||
<Box as="main" display="flex" flexGrow={1} flexDirection="col">
|
||||
<Box as="main" display="flex" flexGrow={1} flexDirection="col" minWidth="0">
|
||||
<ContentViewport fullWidth={!showSidebar}>
|
||||
{children}
|
||||
</ContentViewport>
|
||||
<GlobalFooterTemplate />
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<GlobalFooterTemplate />
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,9 @@ export const ContentViewport = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Box flexGrow={1}>
|
||||
<Container size={fullWidth ? 'full' : 'xl'}>
|
||||
<Box paddingY={paddingMap[padding]}>
|
||||
{children}
|
||||
</Box>
|
||||
<Box flexGrow={1} width="full">
|
||||
<Container size={fullWidth ? 'full' : 'xl'} py={paddingMap[padding]}>
|
||||
{children}
|
||||
</Container>
|
||||
</Box>
|
||||
);
|
||||
|
||||
168
docs/THEME.md
168
docs/THEME.md
@@ -1,140 +1,134 @@
|
||||
🎨 GridPilot Dev Theme — “Precision Racing Minimal”
|
||||
🎨 GridPilot Theme — “Precision Racing Minimal”
|
||||
|
||||
The core idea:
|
||||
A UI that feels like a race engineer’s dashboard — not a game launcher, not corporate SaaS.
|
||||
A clean, modern racing interface that feels like a cockpit dashboard — calm, sharp, and serious.
|
||||
|
||||
⸻
|
||||
|
||||
1. Identity & Mood
|
||||
|
||||
The theme should communicate:
|
||||
• Precision (like telemetry screens)
|
||||
• Calm intensity (the feeling before a qualifying lap)
|
||||
• Authority without ego (used by serious racers)
|
||||
• Modern minimalism (dev-friendly, clean structure)
|
||||
• Soft gaming hints (subtle neon touches, not RGB vomit)
|
||||
GridPilot should feel like:
|
||||
• a real motorsport instrument, not a game launcher
|
||||
• calm and focused, like the moment before a qualifying lap
|
||||
• precise, like a telemetry screen
|
||||
• modern and minimal, without visual noise
|
||||
• slightly futuristic, but never “RGB gamer chaos”
|
||||
|
||||
It appeals equally to:
|
||||
• Devs (clean, modular, readable components)
|
||||
• Gamers (immersive, familiar atmosphere)
|
||||
• Simracers (motorsport seriousness)
|
||||
It should appeal equally to sim racers, gamers, and casual fans.
|
||||
|
||||
⸻
|
||||
|
||||
2. Visual Language
|
||||
2. Visual Style
|
||||
|
||||
Primary Look
|
||||
• Dark, matte surfaces
|
||||
• Thin, crisp separators
|
||||
• Soft glow accents in blue / cyan / purple
|
||||
• Avoid aggressive neon or gamer-overload
|
||||
• Subtle gradient tints (barely visible)
|
||||
Core Aesthetic
|
||||
• matte dark surfaces
|
||||
• thin, crisp separators
|
||||
• soft blue/cyan glows on interaction
|
||||
• no aggressive neon
|
||||
• subtle gradients for depth
|
||||
• everything feels instrument-grade, not decorative
|
||||
|
||||
Color System
|
||||
• Base: Near-black graphite (#0C0D0F)
|
||||
• Surface: Deep charcoal (#141619)
|
||||
• Outline: Soft steel grey (#23272B)
|
||||
• Primary Accent: Electric blue (#198CFF)
|
||||
• Telemetry Accent: Aqua (#4ED4E0)
|
||||
• Warning: Motorsport amber (#FFBE4D)
|
||||
• Graphite Black — base background
|
||||
• Charcoal — panel surfaces
|
||||
• Steel Grey — separators & outlines
|
||||
• Electric Blue — primary actions
|
||||
• Telemetry Aqua — interactive highlights
|
||||
• Motorsport Amber — warnings & signals
|
||||
|
||||
Everything should feel instrument-grade, not decorative.
|
||||
Colors should feel like motorsport, not corporate SaaS.
|
||||
|
||||
⸻
|
||||
|
||||
3. Component Philosophy
|
||||
3. Components & Interaction
|
||||
|
||||
Cards
|
||||
• Functional over flashy
|
||||
• Slight bevel or inset shadow (hint of cockpit panels)
|
||||
• Dense info, clean hierarchy
|
||||
Panels & Cards
|
||||
• slightly inset or raised
|
||||
• reminiscent of cockpit modules
|
||||
• structured and clean
|
||||
|
||||
Tables
|
||||
• High-density
|
||||
• Thin row dividers
|
||||
• Highlight on hover only
|
||||
• Telemetry-coded status colors
|
||||
• information-dense
|
||||
• instantly scannable
|
||||
• light hover highlights
|
||||
• telemetry-style status colors
|
||||
|
||||
Buttons
|
||||
• Flat by default
|
||||
• Glow + gradient only on hover
|
||||
• Snappy micro-animation (motorsport feedback)
|
||||
• flat by default
|
||||
• glow only on hover
|
||||
• snappy, “race-engineer” response speed
|
||||
|
||||
Modals
|
||||
• Soft frosted blur
|
||||
• Fast open/close animation
|
||||
• Dimmed pit-lane-lighting vibe
|
||||
• soft frosted blur
|
||||
• fast open/close
|
||||
• subtle pit-lane lighting vibes
|
||||
|
||||
⸻
|
||||
|
||||
4. Motion & Feedback
|
||||
|
||||
Racing-inspired, but minimal:
|
||||
• Short accelerations (fast ease-out)
|
||||
• No bounces — this isn’t a game store
|
||||
• Hover = slight lift + color pulse
|
||||
• Loading = progress line (like pit limiter light)
|
||||
• Switching tabs = sliding underline (chicane motion)
|
||||
Motion should feel racing-inspired:
|
||||
• short, crisp animations
|
||||
• no bounce or playful movement
|
||||
• hover = slight lift + color pulse
|
||||
• loading = a thin progress line (pit limiter style)
|
||||
• tab switching = sliding underline (chicane motion)
|
||||
|
||||
Devs should feel the UI is responsive, not playful.
|
||||
Responsive, not playful.
|
||||
|
||||
⸻
|
||||
|
||||
5. Layout Structure
|
||||
|
||||
Think “Telemetry Workspace”:
|
||||
• Sidebar = dashboard rail
|
||||
• Header = control bar
|
||||
• Content = track map / data table zone
|
||||
• Right panel = session or context info
|
||||
Think Telemetry Workspace:
|
||||
• Sidebar → control rail
|
||||
• Header → context + session controls
|
||||
• Main Area → race tables, session details, track maps
|
||||
• Right Panel → contextual info, drivers, actions
|
||||
|
||||
Everything modular, easily replaceable, easy to reason about.
|
||||
Everything modular, readable, and effortless to navigate.
|
||||
|
||||
⸻
|
||||
|
||||
6. Tone for Dev-Facing Text
|
||||
• Short
|
||||
• Neutral
|
||||
• Calm
|
||||
• Technical
|
||||
• Real-world language (not corporate slang)
|
||||
6. Tone & Copywriting
|
||||
|
||||
The product tone is:
|
||||
• calm
|
||||
• concise
|
||||
• direct
|
||||
• technical but human
|
||||
• zero hype
|
||||
|
||||
Examples:
|
||||
• “Add race”
|
||||
• “Review protest”
|
||||
• “Session updated”
|
||||
• “Export standings”
|
||||
• “Sponsor payout queued”
|
||||
• “Race added.”
|
||||
• “Standings updated.”
|
||||
• “Session ready.”
|
||||
• “Review protest.”
|
||||
• “Sponsor payout queued.”
|
||||
|
||||
No hype. No marketing tone inside the app.
|
||||
Never corporate. Never salesy. Never loud.
|
||||
|
||||
⸻
|
||||
|
||||
7. Emotional Target
|
||||
7. Emotional Experience
|
||||
|
||||
Users should feel:
|
||||
• In control
|
||||
• Supported
|
||||
• Efficient
|
||||
• Connected to motorsport culture
|
||||
• Trusting (nothing looks cheap or gimmicky)
|
||||
• in control
|
||||
• supported
|
||||
• efficient
|
||||
• connected to motorsport culture
|
||||
• confident in the system
|
||||
|
||||
It’s basically:
|
||||
A disciplined, trustworthy tool — not a flashy app.
|
||||
|
||||
“A premium cockpit dashboard… built by people who race and code.”
|
||||
⸻
|
||||
|
||||
8. UI Layering & Primitives
|
||||
8. Overall Vibe
|
||||
|
||||
To maintain architectural integrity and prevent "div wrapper" abuse, we enforce a strict layering boundary:
|
||||
“A premium cockpit dashboard — for people who actually race.”
|
||||
• minimal
|
||||
• precise
|
||||
• clean
|
||||
• serious
|
||||
• attractive without noise
|
||||
|
||||
### Semantic UI (`apps/website/ui/`)
|
||||
- **Building blocks for components**: `Card`, `Panel`, `Button`, `Table`, `Stack`, `Grid`.
|
||||
- **Restricted flexibility**: Semantic layout components (like `Stack`, `Grid`) are restricted to layout-only props. They do NOT allow styling props (bg, border, etc.).
|
||||
- **Public API**: These are the only UI elements that should be imported by `components/` or `pages/`.
|
||||
|
||||
### Components (`apps/website/components/`)
|
||||
- **Domain-specific**: `RecentRacesPanel`, `DriverCard`, `LeagueHeader`.
|
||||
- **No raw HTML**: Components must use semantic UI elements. Direct use of raw HTML tags is forbidden.
|
||||
|
||||
**Rule of thumb**: If you need a styled container in a component, use `Panel` or `Card`. If you need a new type of styled container, create it in `ui/` using primitives.
|
||||
A tool you’re happy to use, because it respects your time and your craft.
|
||||
Reference in New Issue
Block a user