mirror of
https://github.com/LucasKalil-Programador/world-2026-hub.git
synced 2026-07-04 17:41:28 -03:00
docs: add project specification documents
This commit is contained in:
commit
5ee42abb48
2 changed files with 734 additions and 0 deletions
209
complement-spec-worldcup2026-en.md
Normal file
209
complement-spec-worldcup2026-en.md
Normal file
|
|
@ -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"`) + `<a download>`; **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
|
||||||
|
```
|
||||||
525
world-cup-2026-hub-spec-en.md
Normal file
525
world-cup-2026-hub-spec-en.md
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue