commit 5ee42abb48cff4bf3c88f2a526fae504ef4fae4f Author: Lucas Kalil Date: Fri Jun 12 16:11:49 2026 -0300 docs: add project specification documents diff --git a/complement-spec-worldcup2026-en.md b/complement-spec-worldcup2026-en.md new file mode 100644 index 0000000..9d42ae8 --- /dev/null +++ b/complement-spec-worldcup2026-en.md @@ -0,0 +1,209 @@ +# World Cup 2026 Hub — Spec Complement (Claude Code Prompt) + +> This document complements `World-Cup-2026-Hub-Spec.md` and takes precedence over it in case of conflict. Read both before starting implementation. Stack: HTML5/CSS3/JS ES2022+ (ES Modules), no backend, no frameworks, no bundler, no linting/automated tests. + +--- + +## 1. Data Schemas (`data/`) + +### `teams.json` +```json +[ + { "id": "MEX", "name": "Mexico", "flag": "mexico.svg" } +] +``` + +### `groups.json` +```json +{ + "A": ["MEX", "CAN", "USA", "PAN"] +} +``` +12 groups (A–L), 4 teams each — 48 teams total. + +### `matches.json` +Keeps the original spec's format. For knockout matches, use `bracketRef` instead of fixed `homeTeam`/`awayTeam`: + +```json +{ + "id": 73, + "phase": "Round of 32", + "date": "2026-06-29", + "time": "16:00", + "stadium": "Azteca", + "city": "Mexico City", + "bracketRef": "R32-1" +} +``` +`homeTeam`/`awayTeam` for these matches are resolved at runtime via `resolveBracketTeams()`. + +### `results.json` +Adds support for penalties (knockout stage): +```json +{ + "matchId": 73, + "homeScore": 1, + "awayScore": 1, + "penalties": { "home": 4, "away": 3 }, + "status": "finished" +} +``` +`penalties` is optional — only present if a knockout match ended in a draw. + +### `bracket-config.json` (new file) +Defines the generic bracket structure. **The only file to edit once the 8 best third-place teams are known.** + +```json +{ + "round32": [ + { "id": "R32-1", "home": { "type": "group", "ref": "A", "pos": 1 }, "away": { "type": "group", "ref": "B", "pos": 2 } }, + { "id": "R32-2", "home": { "type": "group", "ref": "C", "pos": 1 }, "away": { "type": "third", "slot": 1 } } + ], + "thirdPlaceAssignment": { + "1": null, + "2": null + } +} +``` +- `round32` must have 16 entries, in the actual bracket order (array position defines bracket position). +- `thirdPlaceAssignment` maps slot → group letter (e.g., `"1": "C"`); still `null` until defined. +- Subsequent rounds (R16, QF, SF, 3rd place, Final) **have no config of their own** — they're generated by sequential pairing of winners (indices 0-1 → next 0, 2-3 → next 1, etc.). + +### `stadiums.json` (update) +Adds `timezone` (IANA), used by the timezone selector (section 7): +```json +{ + "id": 1, + "name": "Estadio Azteca", + "city": "Mexico City", + "capacity": 87000, + "image": "azteca.jpg", + "timezone": "America/Mexico_City" +} +``` +**General note**: all times in `matches.json` must be in **UTC** — `formatMatchTime()` (section 7) and the `.ics` export (section 10) depend on this. + +### localStorage — keys +Keys prefixed with `wc2026_`, managed via `storage.js` (thin wrapper: `get(key, fallback)` / `set(key, value)`, automatic JSON): + +| Key | Content | +|---|---| +| `wc2026_simulation` | `{ "R32-1": { "winner": "MEX", "score": "2-1" }, ... }` | +| `wc2026_favorites` | `["MEX", "BRA"]` | +| `wc2026_prefs` | `{ "timeMode": "local" \| "stadium", "lastTab": "bracket", "theme": "dark" \| "light" }` | + +--- + +## 2. Bracket Logic (`bracket.js`) + +1. **Group standings**: from `groups.json` + `results.json`, compute points (3/1/0), goal difference, and goals for; sort each group. +2. **Resolve Round of 32** via `bracket-config.json`: + - `type: "group"` → `standings[ref][pos - 1]` + - `type: "third"` → `standings[thirdPlaceAssignment[slot]][2]` + - If the group stage isn't finished or the slot isn't defined, show a placeholder ("Group A Winner", "Best 3rd #1"). +3. **Subsequent rounds**: winner = higher score, or penalty winner on a draw. Match not played yet → "TBD". +4. **`resolveBracketTeams(matchId)`**: function exported from `bracket.js`, reused by `schedule.js` to display the correct teams for knockout matches in the schedule. +5. **Generated ID convention**: `{ROUND}-{N}` (`R16-1`, `QF-1`, `SF-1`, `FINAL`, `THIRD-PLACE`), via sequential pairing — used as keys in `wc2026_simulation` (sections 8 and 9). + +--- + +## 3. Mock Data + +Generate `data/*.json` with fictional/placeholder data (to be replaced with real data later): +- 48 fictional teams, 12 groups (A–L) +- 72 group-stage matches + 32 knockout matches = 104 matches (official 2026 format) +- ~30 stadiums (Mexico/USA/Canada) +- Mix of `"finished"`/`"scheduled"` statuses in `results.json` to test both bracket states +- `thirdPlaceAssignment` with all values set to `null` + +--- + +## 4. Execution Plan (sequential phases) + +1. File structure + mock data +2. Base layout: header, hero, dashboard +3. Match schedule: listing, filters, search, sorting +4. Group table (computed standings) +5. Stadiums page +6. Match detail modal +7. Bracket: static structure +8. Bracket: hover/highlight, animations, zoom, drag +9. Simulation mode + `localStorage` +10. Responsiveness + accessibility + entry animations +11. README + acceptance criteria checklist +12. Extra features: `storage.js`, favorites, timezone, .ics, bracket challenge, export/import prediction (sections 6–10) + +At the end of each phase, summarize what was done before moving on. + +--- + +## 5. Constraints +- Vanilla JS, ES Modules (`type="module"`), no bundler/transpiler/CDN +- No automated tests, no linter +- CSS mobile-first, variables per the original spec's palette + +--- + +## 6. Favorites + "My Matches" + +- Star icon next to each team (group table, schedule, modal) → `toggleFavorite(teamId)` in `storage.js`. +- Matches involving favorites get a visual highlight (border/badge) in the schedule, groups, and bracket. +- "My Matches" filter in the schedule (`schedule.js`): shows only matches where `homeTeam` or `awayTeam` is in `wc2026_favorites`. +- `getFavoriteMatches(matches, favorites)` shared between `schedule.js` and `bracket.js`. + +--- + +## 7. Automatic Timezone + +- Global toggle "Local time / Stadium time" → saved in `wc2026_prefs.timeMode`. +- `formatMatchTime(match, stadium, mode)` in `app.js`: + - `mode: "local"` → `Intl.DateTimeFormat` without `timeZone` (uses the browser's timezone) + - `mode: "stadium"` → `Intl.DateTimeFormat` with `timeZone: stadium.timezone` +- Applied in `schedule.js`, `modal.js`, and `bracket.js` cards. + +--- + +## 8. Bracket Challenge (simulation score) + +- `calculateChallengeScore(simulation, results, bracketTree)` in `bracket.js`: + - For each knockout match with `status: "finished"`, compares the actual winner with `wc2026_simulation[matchId].winner`. + - Returns `{ correct, total, byPhase: { "Round of 32": "3/8", ... } }` using the IDs/phases from the resolved `bracketTree` (section 2). +- Displayed as a card near the bracket: "X out of Y correct". +- No persistence of its own — recalculated on every load from `wc2026_simulation` + `results.json`. + +--- + +## 9. Export/Import Prediction (shareable link) + +- "Share prediction" → `getShareableLink()`: `base64(JSON.stringify(wc2026_simulation))` in `?prediction=...` on the current URL. +- On page load, `loadPredictionFromURL()`: + - decodes and validates (same keys as the current `bracketTree`) + - if valid, confirms with the user before overwriting the local `wc2026_simulation` + - if invalid/incompatible, ignores silently +- Functions in `bracket.js`. + +--- + +## 10. Export Match to Calendar (.ics) + +New `calendar.js` module, imported by `modal.js`. "Add to calendar" button in the detail modal. + +- iCalendar format (RFC 5545) — `VCALENDAR` with one `VEVENT`. +- `DTSTART`/`DTEND` in UTC (`...Z`) from `match.date` + `match.time`; fixed 2h duration. +- Knockout matches: `home`/`away` via `resolveBracketTeams(match)`. +- `Blob` (`type: "text/calendar"`) + ``; **CRLF (`\r\n`) required** between lines. + +```text +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//WorldCup2026Hub//EN +BEGIN:VEVENT +UID:match-{id}@worldcup2026hub +DTSTAMP:{start} +DTSTART:{start} +DTEND:{end} +SUMMARY:{home} x {away} — {phase} +LOCATION:{stadium.name}, {stadium.city} +END:VEVENT +END:VCALENDAR +``` diff --git a/world-cup-2026-hub-spec-en.md b/world-cup-2026-hub-spec-en.md new file mode 100644 index 0000000..50ddf54 --- /dev/null +++ b/world-cup-2026-hub-spec-en.md @@ -0,0 +1,525 @@ +# World Cup 2026 Hub + +## 1. Overview + +Develop a static web application for hosting on GitHub Pages that displays complete information about the FIFA World Cup 2026. + +The system should consume JSON files to load match, results, and standings information, with no backend required. + +The main focus is: + +* Modern interface +* Excellent visual experience +* Responsiveness +* Interactive bracket +* Easy maintenance via JSON + +--- + +# 2. Objectives + +Create a portal that allows: + +* Browsing all World Cup matches +* Viewing the group stage +* Viewing the complete knockout stage +* Tracking results +* Viewing stadiums and match information +* Simulating knockout stage winners (optional mode) +* Working fully offline after loading + +--- + +# 3. Technologies + +## Required + +* HTML5 +* CSS3 +* JavaScript ES2022+ + +## Allowed + +* CSS Variables +* CSS Grid +* Flexbox +* Web Components (Optional) + +## Not allowed + +* Backend +* Database +* Heavy frameworks + +--- + +# 4. File Structure + +```text +/ +├── index.html +├── assets/ +│ ├── css/ +│ │ ├── style.css +│ │ ├── bracket.css +│ │ └── animations.css +│ │ +│ ├── js/ +│ │ ├── app.js +│ │ ├── bracket.js +│ │ ├── groups.js +│ │ ├── schedule.js +│ │ └── modal.js +│ │ +│ └── images/ +│ +├── data/ +│ ├── matches.json +│ ├── results.json +│ ├── stadiums.json +│ ├── teams.json +│ └── groups.json +│ +└── README.md +``` + +--- + +# 5. Visual Theme + +## Style + +Visual inspired by: + +* FIFA World Cup +* UEFA Champions League +* Apple Design Language + +## Characteristics + +* Glassmorphism +* Soft shadows +* Rounded corners +* Smooth transitions +* Gradient backgrounds + +## Palette + +```css +--bg-primary: #081421; +--bg-secondary: #10243b; + +--accent-gold: #d4af37; +--accent-blue: #1e88e5; + +--text-primary: #ffffff; +--text-secondary: #cfd8dc; +``` + +--- + +# 6. Main Layout + +## Header + +Display: + +* World Cup 2026 logo +* Navigation + +Menu: + +* Home +* Matches +* Groups +* Knockout Stage +* Stadiums + +--- + +## Hero Section + +Display: + +* Next match +* Countdown +* Highlights + +--- + +## Dashboard + +Cards: + +* Total matches +* Completed matches +* Upcoming matches +* Participating teams + +--- + +# 7. Match System + +## Data Source + +matches.json + +Example: + +```json +{ + "id": 1, + "phase": "Group A", + "date": "2026-06-11", + "time": "17:00", + "stadium": "Azteca", + "city": "Mexico City", + "homeTeam": "Mexico", + "awayTeam": "Canada" +} +``` + +--- + +## Features + +### Filters + +Filter by: + +* Date +* Group +* Phase +* Team +* Stadium + +### Search + +Search by: + +* Country +* City +* Stadium + +### Sorting + +* Date ascending +* Date descending + +--- + +# 8. Results System + +File: + +results.json + +Example: + +```json +{ + "matchId": 1, + "homeScore": 2, + "awayScore": 1, + "status": "finished" +} +``` + +Possible statuses: + +```text +scheduled +live +finished +``` + +--- + +# 9. Knockout Bracket + +## Goal + +Create a highly interactive visualization. + +--- + +## Rounds + +* Round of 32 +* Round of 16 +* Round of 16 +* Quarterfinals +* Semifinals +* Third Place +* Final + +--- + +## Layout + +Horizontal format. + +Example: + +```text +Round of 16 -> Quarterfinals -> Semifinals -> Final -> Champion +``` + +--- + +## Features + +### Hover + +On mouse hover: + +* Highlight the full path + +### Animations + +* Fade-in +* Slide-in +* Glow + +### Zoom + +Allow: + +* Mouse wheel +* Pinch on mobile devices + +### Drag + +Freely move the bracket. + +--- + +## Simulation Mode + +User can: + +* Choose winner +* Enter score +* Update next rounds + +Without modifying the original JSON. + +State saved in: + +```javascript +localStorage +``` + +--- + +# 10. Match Info Modal + +When clicking on a match. + +Open a modal containing: + +## Information + +* Teams +* Date +* Time +* Stadium +* City +* Capacity +* Result + +## Future statistics + +Prepare space for: + +* Possession +* Shots +* Cards + +--- + +# 11. Stadiums Page + +Data from: + +stadiums.json + +Example: + +```json +{ + "id": 1, + "name": "Estadio Azteca", + "city": "Mexico City", + "capacity": 87000, + "image": "azteca.jpg" +} +``` + +--- + +## Display + +Responsive cards containing: + +* Photo +* Name +* City +* Capacity +* Matches held + +--- + +# 12. Responsiveness + +## Desktop + +1440px+ + +Full layout. + +--- + +## Tablet + +768px–1439px + +Reduced menu. + +--- + +## Mobile + +Up to 767px + +Bracket with: + +* Horizontal scroll +* Zoom +* Drag + +--- + +# 13. Performance + +Goals: + +* Lighthouse > 90 +* First render < 2s +* JS bundle < 300KB + +--- + +# 14. Accessibility + +Implement: + +* ARIA labels +* Keyboard navigation +* Adequate contrast +* Visible focus states + +--- + +# 15. Animations + +## Entry + +```css +fade-in +slide-up +slide-left +``` + +## Interaction + +```css +hover-scale +hover-glow +pulse +``` + +## Bracket + +```css +line-draw +winner-highlight +path-highlight +``` + +--- + +# 16. Local Persistence + +Save: + +* Simulations +* Visual preferences +* Last opened tab + +Use: + +```javascript +localStorage +``` + +--- + +# 17. Code Requirements + +## JavaScript + +* Modular +* No duplicated code +* Pure functions when possible + +## CSS + +* Organized by component +* Global variables +* Mobile First + +--- + +# 18. Acceptance Criteria + +The project will be considered complete when: + +* All matches are loaded via JSON +* All results are loaded via JSON +* The bracket is generated dynamically +* It works on GitHub Pages +* It works on desktop and mobile +* It allows knockout stage simulation +* It has smooth animations +* It does not depend on a backend + +--- + +# 19. Future Improvements + +* PWA +* Dark/light mode +* Real-time statistics +* Results API +* FIFA ranking +* World Cup history +* Team comparison +* Push notifications + +--- + +# 20. Deliverables + +The final system must provide: + +1. Single page (SPA) +2. Complete dynamic bracket +3. Group standings tables +4. Match schedule +5. Stadiums page +6. Detailed match modal +7. Simulation system +8. Architecture ready for expansion +9. Compatibility with GitHub Pages +10. Clean, documented code