Skip to content

Court Claimer

Design system — components, tokens, layout, spacing, and motion.

Foundations

Spacing System

8px base grid. Spacing tokens control gaps between components, sections, and page-level rhythm.

--card-gap16pxCard gap — between cards in a grid
--heading-gap-sm24pxHeading gap sm — sub-heading to content
--heading-gap32pxHeading gap — section heading to content
--section-gap48pxSection gap — between page sections
--section-gap-lg64pxSection gap lg — major section breaks
Shell constraints
--shell-max1120px — max content width
--shell-gutter24px — horizontal page padding
Foundations

Grid & Layout

Responsive grid with automatic column collapse. Uses --card-gap (16px) between items.

mobile="stack" (default) — single column on mobile
3 cols → 2 at sm → 1 at base
col 1
col 2
col 3
mobile="2-col" — stays 2-col on mobile (stat cards, pricing)
3 cols → 2 at base (never stacks)
Claims
Rate
Speed
mobile="none" — never collapses (compact items)
4 cols → 4 at all breakpoints
Mon
Tue
Wed
Thu
Mobile behavior reference
mobilebase (0-639)sm (640+)lg (1024+)Use for
stack1 col2 colfullContent cards, how-it-works, feeds
2-col2 col2 colfullStat cards, pricing, compact pairs
nonefullfullfullDay pickers, icon rows, tiny items
Foundations

Responsive Breakpoints

Mobile-first. Components stack on small screens and expand as viewport grows.

BreakpointWidthBehavior
base0–639pxSingle column. Stacked hero. Hamburger nav.
sm640px2-column grids. Side-by-side stats.
md768pxFull nav visible. Hero grid 2-col.
lg1024px3-column grids. Full dashboard layout.
xl1280pxMax shell width (1120px) centered. Extra gutter.
Foundations

Motion

Subtle, functional transitions. No bounce, no delight animations. This is a precision tool.

--duration-fast
100ms
Hover states, focus rings, badge dots
--duration-normal
200ms
Button presses, card transitions, toggle switches
--duration-slow
350ms
Toast enter/exit, page transitions, panel reveals
Easing curves
--easing-defaultcubic-bezier(0.25, 0.1, 0.25, 1) — smooth deceleration
--easing-springcubic-bezier(0.34, 1.56, 0.64, 1) — slight overshoot, toggles only
Respects prefers-reduced-motion. All transitions collapse to 0.01ms when user has motion sensitivity enabled.
Foundations

Elevation & Depth

Four elevation levels. Higher elevation = more shadow = closer to the user.

Surface
z-base: 0
Page background, inline elements
Raised
z-raised: 10
Cards, feeds, inputs
Overlay
z-overlay: 40
Toasts, dropdowns, popovers
Modal
z-modal: 50
Modals, dialogs, drawers
Components

Buttons

Components

Badges

CLAIMEDWATCHING1 LEFTQUEUEDFAILED
DefaultSecondaryOutline
Components

Cards

Claims This Week
12
+3 vs last week
Success Rate
94%
Last 30 days
Avg Speed
1.2s
-0.3s faster
Bot Status
Watching 4 venues across London
Next check in00:12
x
Components

Feed

Live Claims
Archbishops Park — Ct 1Sat 10:00CLAIMED
Kennington Park — Ct 2Sat 11:00WATCHING
Finsbury Park — Ct 1Sun 09:00CLAIMED
Victoria Park — Ct 3Sun 10:001 LEFT
Components

Inputs

Components

Additional Primitives

Core form and interaction primitives for flows beyond the base dashboard set.

Textarea + field controls
Tabs + accordion
Track target venues, preferred courts, and expected release windows.

Overlay patterns
Dropdown menu
Phase 2

Component States

Every interactive component must handle default, hover, focus, active, disabled, and loading states.

Button states
Default
Hover
Focus
Active
Disabled
Loading (click)
Input states
Default
Focus (click to see ring)
Disabled
Error (blur empty to trigger)
Switch states
Default
Checked
Disabled
Small
Phase 2

Skeleton Loading

Skeleton placeholders match the shape of real content. Use instead of spinners for predictable layouts.

Base Skeleton
SkeletonCard — stat cards
SkeletonFeedItem — activity feed
SkeletonTableRow — data tables
Phase 2

Empty States

Every data-driven section needs an empty state. Three variants for different scenarios.

🎾

No courts yet

Add your first venue to start watching for available courts.

🔍

No matches

No courts match your current filters. Try adjusting your search.

Couldn't load venues

Something went wrong fetching your venues. Please try again.

Phase 2

Error Patterns

Page-level errors, inline errors, and field validation — all three patterns for comprehensive error handling.

ErrorState — page-level / section-level

Failed to load bookings

We couldn't reach the booking service. Check your connection and try again.

ErrorState inline — inside a card or section
Payment failed
Your card was declined. Please update your payment method.
FieldError — form field validation
Please enter a valid email address
Budget is required
Phase 3 — Blocks

Navigation

Sticky nav with logo, links, and CTA. Collapses to hamburger on mobile.

Phase 3 — Blocks

Hero

Landing page hero with scarcity badge, headline, subhead, and dual CTAs.

3 SLOTS CLAIMED IN THE LAST HOUR

Stop refreshing. Start playing.

Court Claimer watches London's busiest venues and books your preferred slot the instant it opens — in under 2 seconds.

Phase 3 — Blocks

Stats Row

Configurable stat cards. Uses Grid with mobile="2-col" so stats never fully stack.

Claims This Week
12
+3 vs last week
Success Rate
94%
Last 30 days
Avg Speed
1.2s
-0.3s faster
Active Venues
4
London
Phase 3 — Blocks

Booking Table

Data table for booking history with venue, time, cost, and status badges.

VenueCourtDateTimeCostStatus
Archbishops ParkCt 1Sat 19 Apr10:00–11:00£8.00CLAIMED
Kennington ParkCt 2Sat 19 Apr11:00–12:00£8.00WATCHING
Finsbury ParkCt 1Sun 20 Apr09:00–10:00£9.50CLAIMED
Victoria ParkCt 3Sun 20 Apr10:00–11:00£8.00QUEUED
Battersea ParkCt 2Mon 21 Apr18:00–19:00£12.00FAILED
Phase 3 — Blocks

Settings Panel

Toggle rows, input fields, and save action — the standard settings card pattern.

Bot Settings
Configure how Court Claimer watches and books courts.
Automatically claim courts when they appear
Get notified on claim success or failure
Highlight slots with limited availability
Maximum amount to spend on bookings per week
Phase 3 — Blocks

Pricing

Three-tier pricing cards with feature lists. Popular tier gets elevated border and badge.

Free
Watch courts manually. No auto-booking.
£0/mo
  • 1 venue
  • Manual refresh
  • Email alerts
MOST POPULAR
Pro
Auto-book your preferred slots instantly.
£9/mo
  • 5 venues
  • Auto-booking
  • Telegram alerts
  • 1.2s avg claim speed
  • Booking history
Team
For clubs and groups who play together.
£29/mo
  • Unlimited venues
  • Auto-booking
  • Priority queue
  • Team scheduling
  • Usage analytics
  • Dedicated support
Phase 3 — Blocks

How It Works

Numbered step cards for feature explanation sections.

📍
Step 1

Add your venues

Tell us which parks and courts you want. We support 50+ London venues.

Step 2

Set your preferences

Pick your ideal days, times, and budget. We handle the rest.

Step 3

We watch & claim

Court Claimer monitors availability and books the instant a slot opens — in under 2 seconds.

Phase 3

Icon Set

Curated Lucide icons for the Court Claimer domain. Consistent 24px size, 1.5px stroke.

Search
Venue
Time
Speed
Alert
Settings
Calendar
Trend
Secure
Payment
Watch
Refresh
Success
Error
Warning
Arrow
Add
Delete
Logout
Account
Icon guidelines
Size20px (h-5 w-5) default · 16px for inline · 24px for empty states
Stroke1.5px (Lucide default) — never change stroke width
ColorInherit from parent text color · use text-clay for primary actions
Librarylucide-react only — no mixing icon libraries
Phase 3

Microcopy Guidelines

Voice: Confident, Precise, Dry. These patterns keep UI text consistent across the product.

Button labels
UseClaim court · Add venue · Save changes · Retry
AvoidSubmit · Click here · Go · Process
Empty states
Use"No courts yet" · "No matches found" · "Nothing to show"
Avoid"Oops!" · "Uh oh!" · "Looks like there's nothing here!"
Error messages
Use"Couldn't load bookings" · "Payment failed" · "Email is required"
Avoid"Error 500" · "Something went wrong lol" · "Invalid input"
Confirmation dialogs
Use"Remove venue?" · "Cancel booking?" — verb matches the action
Avoid"Are you sure?" · "Yes / No" — be specific about the consequence
Brand word choice
ContextUseAvoid
Brand moments (badges, alerts)claimed, securedgrabbed, snagged
Transactional (confirmations)booked, reservedpurchased, bought
Availabilityslot, openingtime, appointment
System actionwatching, monitoringtracking, stalking
Foundations

Typography

display-xl · Space Grotesk 52px

Stop refreshing.

display-lg · Space Grotesk 26px

Booking History

display-md · Space Grotesk 20px

Bot Status

body-lg · Sora 17px

Prime-time tennis courts sell out in seconds. Court Claimer watches, races, and books your preferred slot automatically.

body · Sora 14px

Book automatically when a watched slot opens. Telegram alerts ping on claim success or failure.

mono · JetBrains Mono 13px

94% · 1.2s · £8.00 · 10:00–11:00

label · Sora 11px uppercase

Claims This Week

Phase 4

Elevation System (Refined)

Multi-layer shadows with secondary ambient layer. Stronger shadows in dark mode for depth on dark surfaces.

Card
shadow-card
Base cards, inputs, feeds
Raised
shadow-raised
Hover states, focused cards, nav
Toast
shadow-toast
Toasts, dropdowns, popovers
Overlay
shadow-overlay
Modals, drawers, command palette
Button
shadow-btn
Primary CTA press feedback
Input
shadow-input
Subtle depth for form fields
Dark mode behavior

Shadows use higher opacity in dark mode (0.2–0.5 vs 0.04–0.12) because dark surfaces absorb light. Toggle dark mode above to compare.

Phase 4

Accessibility

WCAG 2.1 AA compliance. Focus management, contrast, keyboard navigation, and reduced motion.

Keyboard navigation
All interactive elements are focusable with Tab. Press Tab now to see focus rings move through the page.
Skip to content
Hidden skip link appears on first Tab press — jumps past nav directly to main content. Try it: reload and press Tab.
Color contrast
All text meets WCAG AA (4.5:1 body, 3:1 large text). Muted-foreground adjusted to #9B9BA8 in dark mode for compliance.
Focus visible demo

Focus ring: 2px clay with offset. Keyboard-only — no ring on mouse click.

Reduced motion

When prefers-reduced-motion: reduce is set:

  • All transitions → 0.01ms
  • Skeleton pulse animation stops
  • Scroll behavior → instant
Phase 4

Dark Mode

Full dark theme with adjusted brand colors, elevated shadows, and AA-compliant contrast. Toggle with the moon icon in the header.

Token adjustments (dark)
--color-clay#C4622D → #D4763F (lightened for contrast)
--color-court-green#2D4A3E → #5A9B8A (lightened)
--muted-foreground#888888 → #9B9BA8 (AA compliant)
--destructive#DC2626 → #EF4444 (brighter)
--amber-brand#F0A500 → #F5B942 (warmer)
Brand colors in current theme
clay
court-green
chalk
dusk
tape
amber
Semantic colors
bg
card
primary
secondary
muted
destructive
Phase 4

Data Visualization

Charts built with Recharts using Court Claimer tokens for color, typography, and elevation.

Weekly Claims
Successful and failed claims this week
Success Rate by Venue
Claim success percentage — last 30 days
Chart guidelines
Colorscourt-green for positive metrics, clay for warnings, destructive for failures
GridDashed horizontal lines only (no vertical gridlines) — border color
TooltipsCard bg, border, rounded-lg, shadow-toast — matches component system
TypographyAxis labels 11-12px muted-foreground, values in mono font
ContainerAlways inside a Card with title + description — 240px default height

Court Claimer Design System · Scale B · Editorial Athletic