- HTML 64%
- CSS 27.8%
- JavaScript 8.2%
| assets/images | ||
| shared | ||
| .current-issue | ||
| about.html | ||
| admin-players.html | ||
| admin-teams.html | ||
| admin.html | ||
| billing.html | ||
| checkout-cancel.html | ||
| checkout-success.html | ||
| checkout.html | ||
| coach-profile.html | ||
| coach.html | ||
| forgot-password.html | ||
| gear.html | ||
| index.html | ||
| jersey-success.html | ||
| jersey.html | ||
| login.html | ||
| parent.html | ||
| player-profile.html | ||
| README.md | ||
| register.html | ||
| reset-password.html | ||
| schedule.html | ||
| sponsors.html | ||
| staff.html | ||
| success.html | ||
| team.html | ||
| teams.html | ||
| tryouts.html | ||
Westside Kings & Queens — Design Source of Truth
This repo IS the app, rendered as static HTML/CSS. Every HTML file maps 1:1 to a SvelteKit route in westside-app. The CSS and markup here are copied directly into production — agents add {data.xxx} bindings, auth guards, and form actions. Nothing else changes.
Rule: Vanilla HTML, CSS, JavaScript only. No frameworks. No build steps. What you see on your phone is what ships.
Route Map
| File | Production Route | Role | Purpose |
|---|---|---|---|
index.html |
/ |
Public | Landing page — coaches, about, tryout banner, FAQ, partners |
tryouts.html |
/tryouts |
Public | Shareable tryout page — date, details, register CTA |
register.html |
/register |
Public | Registration — player-first form, age gate, cash payment option, confirmation with credentials |
signin.html |
/signin |
Public | Login page (Keycloak in production) |
parent.html |
/my-players |
Member | Account holder dashboard — player(s) profile, team, payment status |
player-profile.html |
/players/:id |
All (role-based edit) | Full player profile — info cards, edit form, billing link, team link |
billing.html |
/players/:id/billing |
Player | Card on file, update card (Stripe Elements), invoices, manage subscription |
team.html |
/teams/:id |
Player/Coach | Team detail — roster, coaches, playbooks, schedule |
coach.html |
/coach |
Coach | Coach dashboard — tabs (Team roster / Plays), player cards with parent contact |
coach-profile.html |
/coaches/:id |
All (authenticated) | Coach bio page — photo, title, contact, teams |
admin.html |
/admin |
Admin | CRM pipeline dashboard — stat cards (Registered, Active, Teams, Overdue), each links to CRM or Teams |
admin-players.html |
/admin/players |
Admin | Player CRM — filter by pipeline stage, search, card-based player list |
admin-teams.html |
/admin/teams |
Admin | Team management — collapsible teams, inline player assignment, coaches per team, save/reset draft |
Not in playground (built directly in westside-app):
/admin/users— Keycloak user management/admin/payments— Subscription management (create/cancel)/signin,/signout— Auth routes (Keycloak OIDC)
User Stories
US-1: Parent Dashboard
As a parent, when I sign in I see my child's profile — team, coach, and payment status at a glance.
- Player card: name, position, height, school, grad class
- Team assignment: team name, division, coach
- Payment status badge + next payment date
- "View Billing" → billing page
US-2: Self-Service Billing
As a parent, I can update my credit card and view payment history without calling anyone. Subscription changes (cancel, hold, plan questions) require meeting with Coach Marcus first.
- Card on file: brand, last 4, expiry
- Update card: Stripe Elements embedded form (PCI compliant)
- Invoice history: date, amount, status, download link
- Manage subscription: Call/Email Marcus buttons
US-3: Coach Roster
As a coach, I see my team's players with parent contact info for emergencies and practices.
- Player cards: photo, name, position, height, school
- Parent contact: name, phone (tap to call)
- Click player name → full profile (read-only)
- Tabs: Team roster / Plays
US-4: Admin Dashboard
As Marcus, I open the app and immediately see the player pipeline — Registered, Active, Teams, Overdue. Each stat card links to the CRM or Teams page for drill-down.
- Pipeline stat cards: Registered, Active, Teams, Overdue — each clickable
- Registered → CRM (all registered players)
- Active → CRM (filtered to active)
- Teams → /admin/teams
- Overdue → CRM (filtered to overdue)
- Quick actions: Manage Players, Manage Teams
US-5: Player Profiles
As any authenticated user, I can view a player's full profile. Players and admins can edit. Coaches see read-only.
- Profile header: avatar, name, position, division
- Info cards: player details, team & coach, payment, stats placeholder
- Edit form: height, position, school, grad class, target schools, hometown, photo
- "Not assigned yet" state for new players before team placement
- Team name is clickable → team detail page
- Stats & Recruitment section: placeholder for future phase
US-6: Team Detail
As a player or coach, I can view my team's full roster and coaches.
- Team header: name, division, player count, coach count
- Coaches section: photo, name, title, phone
- Roster: clickable teammate list → player profiles
- Playbooks: TBD — separate service (own repo, shared auth)
- Schedule: TBD — separate service (own repo, shared auth)
US-7: Tryout Registration
As a parent, I can register my child for tryouts — player-first form with age gate.
- Player info: name, division, photo (required), height, position, grad class, school, hometown
- Age gate: 18+ players sign for themselves, under 18 = parent/guardian signs
- Parent info: name, email, phone
- Waiver: scrollable agreement with digital signature
- Payment: $30 tryout fee via Stripe or cash (admin marks cash payments manually)
- After registration: confirmation screen with account credentials, can log in immediately
US-8: Coach Playbooks — DEFERRED
Playbooks are a separate service with its own repo and shared Keycloak auth. Not part of the core app.
US-9: Player CRM
As Marcus, I can see all players organized by pipeline stage — search, filter, and manage from a single page.
- Card-based player list with photo, name, team, division
- Filter tabs: All, Registered, Active, Overdue
- Search: instant filter by name
- Each card links to full player profile
US-10: Team Management
As Marcus, I can manage team rosters — create/delete teams, assign players, assign coaches, save or reset draft changes.
- Collapsible team sections with player count
- Inline player assignment (drag or tap-tap)
- Coach assignment per team (multiple coaches allowed)
- Save draft / reset to last saved state
- Create new team / delete empty team
- Division names only (e.g., "16U Boys", not team nicknames)
US-11: Coach Profiles
As any authenticated user, I can view a coach's bio — photo, title, teams, contact info.
- Coach photo, name, title
- Teams coached
- Contact: phone, email
- Visible to all authenticated users
US-12: Age Gate Registration
As a player who is 18+, I can register and sign for myself. Under 18 = parent/guardian must complete the form.
- Player-first form: player details entered first
- Age check: date of birth determines who signs
- Under 18: parent/guardian info required, parent signs waiver
- 18+: player signs for themselves, parent info optional
- Digital signature field (touch/mouse)
- Cash payment option (admin marks paid manually)
Architecture
Landing Page (/) → Keycloak OIDC → Role Redirect
├── admin → /admin (pipeline dashboard)
│ ├── /admin/players (CRM)
│ └── /admin/teams (team management)
├── coach → /coach (roster + plays)
│ └── /coaches/:id (bio)
└── member → /my-players (account holder dashboard)
└── /players/:id (profile)
└── /players/:id/billing
/teams/:id — accessible to all authenticated users
/coaches/:id — accessible to all authenticated users
Backend: basketball-api (FastAPI + Postgres + Stripe) Auth: Keycloak OIDC (realm: westside-basketball, roles: admin/coach/member) Frontend: westside-app (SvelteKit SPA — adapter-static + keycloak-js for Capacitor/iOS readiness)
Future separate services (own repos, shared Keycloak auth):
- Playbooks service
- Schedule service
- Stats/recruitment service
Design System
Shared assets in shared/:
| File | Lines | Purpose |
|---|---|---|
app.css |
2,406 | Single source of truth for all styling |
app.js |
382 | All interactions (tabs, filters, modals, toggles) |
style.css |
804 | Legacy landing page CSS (review for merge or deletion) |
logo.jpeg |
— | Brand logo |
Rules:
- Zero inline CSS in HTML files. Every style lives in
app.css. - Zero inline JS in HTML files. Every interaction lives in
app.js. - All colors as CSS custom properties — zero hardcoded hex in markup.
- Dark theme:
#0a0a0abackground,#d42026red brand. - Mobile-first: 390px target, breakpoints at 400px, 600px, 640px.
- Components: nav, stat-cards, player-cards, info-cards, badges, buttons, list-rows, team-cards, filter-tabs, card-rows, invoice tables.
Decisions
- SPA + keycloak-js. SvelteKit with adapter-static for Capacitor/iOS readiness. Validated by mcd-tracker.
- Player is primary entity. CRM organizes by player, not family. Parent is a contact column on the player.
- Registration is player-first. Player info entered first, then age gate determines who signs.
- Age gate. 18+ players sign for themselves. Under 18 = parent/guardian signs.
- Digital signature. Waiver includes touch/mouse signature field.
- Cash payment option. Admin marks cash payments manually via "mark paid" endpoint.
- CRM pipeline. Admin dashboard shows pipeline stat cards (Registered, Active, Teams, Overdue), each links to CRM or Teams.
- Division names only. Teams use division names (e.g., "16U Boys"), not nicknames like "Kings."
- Separate services for playbooks, schedule, stats. Each gets own repo with shared Keycloak auth.
- Team assignment from Teams page or player profile only. No separate draft board page.
- Coaches can have multiple teams. Coach-team is many-to-many.
- Admin can create/delete teams dynamically. No hardcoded team list.
- Card updates are self-service. Parents update their own card via embedded Stripe Elements.
- Subscription changes go through Marcus. Cancel, hold, plan questions → Call/Email Marcus.
- Stripe portal is restricted. API config disables cancellation. Only card update + invoice history.
- No redirect to Stripe. Enterprise UX — parents never leave the app.
- Profile is the hub. Stats, recruiter integration, billing all attach to the player profile.
- Playground = production truth. CSS and HTML here are literally copied to SvelteKit. Agents add data bindings, not design opinions.
- Account holder model. Keycloak role is "member" (not "player"). One account (email) can manage 1+ players. Siblings share a parent login. 18+ players = account IS the player. Under 18 = account is the parent linked to child player(s). Three roles: admin, coach, member.
- Player is data, not a user. Players don't log in. The account holder (parent or 18+ athlete) logs in and manages their player(s). CRM organizes by player; auth organizes by account.