mercy-gameweek is a Fantasy Premier League (FPL) companion application. Its product intent is to give an engaged FPL manager a single, dense, instantly legible surface for the current gameweek: live fixtures and scores, upcoming and finished matches, gameweek goal totals, the top-performing players ranked by average points, the Premier League league table, a horizontally scrolling fixture ticker, and a one-action path to sync the fixture schedule into the manager's own calendar.
The audience is the engaged FPL manager who checks live gameweek data repeatedly and needs information density and instant legibility rather than lifestyle warmth. The emotional register is competitive, analytical, and urgent — live match states, gameweek deadlines, and goal totals drive the design and the information hierarchy.
The product is delivered as a first-party web application with two pages: an anonymous Landing page that explains the companion and directs visitors to the working surface, and the Fixtures Hub, which carries all accepted gameweek behavior. Both pages are reachable without an account; no sign-in, profile, or account-management capability is part of this product.
mercy-gameweek is a React single-page application backed by a data layer that supplies three kinds of live football data:
plLive function, with a fallback to the stored Match entity sorted by kickoff when the live function returns no matches or fails.Player entity sorted by average points (descending), limited to 60 records.fetchPlStandings), returning a table array.The application renders a loading spinner while the initial data fetch is in flight, then presents the Fixtures Hub: a masthead with the current gameweek numeral and the Sync to Calendar call to action, a row of four stat modules, a Top Performers section, a Gameweek Fixtures section, a League Table section, and a Fixture Ticker section. The calendar sync dialog opens from the masthead button and receives the loaded matches.
Delivery ownership. All accepted behavior is first-party custom UI owned by the application. Live match data is supplied by the plLive function; when that function returns no matches or errors, the application falls back to the stored Match entity. Player data comes from the Player entity and standings come from the Premier League standings source. The user's own calendar is the external destination for the calendar sync flow — the application produces the fixture schedule for the user's calendar, and the calendar itself remains user-owned and outside the application.
Access ownership. Both pages are anonymously reachable. The accepted journeys — reading the current gameweek, checking live fixtures, reviewing top performers and standings, and syncing fixtures to a calendar — require no account, no private durable state, and no commitment bound to a verified identity. No application-owned identity, sign-in, or account-management capability is introduced.
Current vs. future boundary. Everything described in this document is current. No future-horizon requirements were accepted in the authoritative thread; nothing is deferred.
Exclusions. No account or profile management, no FPL squad selection or transfer management, no league creation or private mini-leagues, no notifications or alerts, and no social or sharing features are part of this product. The application does not own the user's calendar; it only supplies fixture data to the calendar sync flow.
plLive function returns no matches or throws, the application falls back to the stored Match entity sorted by kickoff; if the standings fetch fails, the table is left empty and the rest of the page still renders.FR-1 — Fixtures Hub page identity. As an FPL Manager, I should see a Fixtures Hub page headed "Fixtures Hub" with the subtitle "Live gameweek fixtures, top performers, and the Premier League table." so that I know I am on the gameweek surface. (explicit)
FR-2 — Gameweek stat card. As an FPL Manager, I should see a stat card showing the current gameweek number so that I know which gameweek I am looking at. (explicit)
FR-3 — Fixtures count stat card. As an FPL Manager, I should see a stat card showing the number of fixtures in the current gameweek so that I know how many matches make up the gameweek. (explicit)
FR-4 — Live Now stat card with pulse. As an FPL Manager, I should see a stat card showing the number of matches live now, with a pulse indicator when any are live, so that I can tell at a glance whether matches are in progress. (explicit)
FR-5 — Goals (GW) stat card. As an FPL Manager, I should see a stat card showing total goals scored in the gameweek so that I can gauge how high-scoring the gameweek has been. (explicit)
FR-6 — Top Performers section. As an FPL Manager, I should see a Top Performers section for the current gameweek based on players ranked by average points so that I can see who is performing best. (explicit)
Player entity sorted by average points descending, limited to 60 records, and the current gameweek.FR-7 — Gameweek Fixtures section. As an FPL Manager, I should see a Gameweek Fixtures section listing matches with live, scheduled, and finished statuses so that I can follow the gameweek's matches. (explicit)
Match entity data sorted by kickoff.FR-8 — League Table section. As an FPL Manager, I should see a League Table section populated from Premier League standings so that I can see current league positions. (explicit)
table array returned by the Premier League standings source.FR-9 — Fixture Ticker section. As an FPL Manager, I should see a Fixture Ticker section listing matches in a horizontally scrollable strip so that I can scan the fixture schedule quickly. (explicit)
FR-10 — Sync to Calendar button. As an FPL Manager, I should be able to press a "Sync to Calendar" button that opens a calendar sync dialog for the fixtures so that I can put the fixture schedule into my own calendar. (explicit)
FR-11 — Player data loading. As an FPL Manager, I should have player data loaded from the Player entity sorted by average points so that the Top Performers section reflects the best performers. (explicit)
Player entity sorted by -avg_points with a limit of 60.FR-12 — Match data loading with live-first fallback. As an FPL Manager, I should have match data loaded from the live plLive function with fallback to the Match entity sorted by kickoff so that I see live data when available and stored data otherwise. (explicit)
plLive function; on empty results or error, a request to the Match entity sorted by -kickoff with a limit of 50.Match entity is the recovery path for live data.FR-13 — Loading spinner. As an FPL Manager, I should see a loading spinner while data is being fetched so that I know the page is working. (explicit)
FR-14 — Live football data availability. As an FPL Manager, I should have live football data available through the plLive function or the stored Match entity fallback so that the gameweek surface always has match data to show. (required_inference)
Match entity is the fallback when the live function yields nothing.FR-15 — Player and standings data availability. As an FPL Manager, I should have player data available from the Player entity and Premier League standings available from the standings source so that the Top Performers and League Table sections can render. (required_inference)
FR-16 — Calendar availability for sync. As an FPL Manager, I should have my calendar available to the calendar synchronization flow so that the fixtures can be added to it. (required_inference)
Product context. The FPL Manager is an engaged Fantasy Premier League player who checks live gameweek data repeatedly — during matches, around deadlines, and when planning ahead. They already know the league, the clubs, and the gameweek structure, so they do not need onboarding or explanation; they need the current state of the gameweek in one dense, scannable surface.
Primary goal. Know the state of the current gameweek at a glance — which matches are live, what the scores are, how many goals have been scored, who the top performers are, where clubs sit in the table — and get the fixture schedule into their own calendar.
Distinct accepted responsibilities.
Relevant inputs and decisions. The manager reads live and stored match data, player average points, and league standings. Their decisions are about attention and timing — which matches to watch, how the gameweek is unfolding, and whether to sync the schedule now.
Interactions with other accepted participants. The FPL Manager is the only accepted human persona. The other participants in the accepted behavior are non-human: the plLive function and the stored Match entity supply match data, the Player entity supplies player data, the Premier League standings source supplies the table, and the manager's own calendar is the external destination of the sync flow.
Observable success. The manager sees the current gameweek number, the fixture count, the live count with its pulse, and the gameweek goal total; the fixtures list shows live, scheduled, and finished matches; the top performers and league table render; the ticker scrolls; and the fixture schedule is delivered to their calendar.
Player entity sorted by average points, match data loads from the plLive function (or falls back to the stored Match entity sorted by kickoff), and the standings fetch resolves.Match entity data sorted by kickoff instead, and the manager continues reading normally.Muse and headline. Josef Müller-Brockmann — Swiss rigour for the gameweek: grid-locked fixtures, pure colour as status. The visual language is an information poster: a visible modular grid, strict typographic scale, and pure geometric colour coding that turns dense data into wayfinding.
Colour tokens (dark mode).
| Role | Hex | Use |
|---|---|---|
| Background | #0B0D10 | Dark graphite ground |
| Surface | #14171C | Slightly lifted modules |
| Text | #F2F3F5 | Primary text |
| Primary | #E8B53C | Gold signal: gameweek number, section rules, active tab, Sync CTA |
| Accent | #E23B2E | Red, reserved strictly for LIVE status and negative deltas |
| Muted | #7A808A | Metadata and secondary labels |
| Hairline | #232830 | 1px module separators |
Colour appears as flat blocks and 2px rules only, in the proportion of an information poster: 85% ground, 10% gold, 5% red. No gradients, no glow.
Typography. Headings and body: Archivo. Headings use Heavy weight (800/900) for section headers and the gameweek number, set flush-left ragged-right, tight tracking (-0.02em); section labels are uppercase with wide tracking (+0.08em) at small sizes. The single display moment is the gameweek numeral set at 96–128px, weight 900, gold, aligned to the grid's left column. Scale is a 1.25 modular scale on a 16px base: 128 / 64 / 40 / 28 / 20 / 16 / 13. Section headers 28px, stat values 40px, labels 13px uppercase, body 16px. Line-height 1.15 for headings, 1.5 for body. No italic, no decorative weights.
Shape language. Hard edges everywhere — 0px radius on cards, buttons, and inputs. Modules are separated by 1px hairlines (#232830) and 2px gold rules above section headers. Status is a solid 4px vertical bar on the left edge of each fixture row (gold = scheduled, red = live with pulse, muted = finished). No pills, no soft shadows, no rounded corners. The only circular elements are the loading spinner and the live pulse dot.
Layout. A strict 12-column modular grid with a 24px gutter at 1280px, collapsing to 8 columns at 768px and 4 columns at 375px. The page opens with a full-width masthead: gameweek numeral in the left 4 columns, title and subtitle stacked in columns 5–9, and the Sync CTA pinned flush-right in columns 10–12, separated by a 2px gold rule spanning the full width. Stat cards form a 4-up row of equal modules with hairline dividers between them (no card gaps). Below, fixtures occupy columns 1–8 and the sidebar (league table + ticker) occupies columns 9–12. Every section is labelled with an uppercase 13px gold eyebrow above a 2px rule, then the content. Nothing floats; everything aligns to the grid.
Imagery. No photography, no illustration. The visual language is diagrammatic: club crests as small monochrome or full-colour marks inside 32px square cells, geometric status bars, and a league table rendered as a ruled tabular system with position numbers in the first column. The fixture ticker is a horizontal strip of evenly-sized cells divided by 1px rules, each cell containing kickoff time, two crests, and score — a wayfinding strip, not a carousel of cards.
Readable text and controls. Headlines, wordmarks, labels, numbers, and card text and controls stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling (for example font-size: clamp(...) with its mobile size) to fit. No other element covers any part of them. Moving and scrollable content — the fixture ticker — may cross the container edge by design; every item becomes fully readable as it passes.
The public entry is a full-width masthead, not a card. A 2px gold rule runs edge-to-edge at the top of the Landing page. Below it, a 12-column grid carries the product wordmark and a single line stating what the companion covers — live gameweek fixtures, top performers, and the Premier League table — set flush-left ragged-right in Archivo, with the entry control as a hard-edged gold rectangle aligned to the grid's right edge. The composition is a transit map, not a hero: the eye moves left to right along the grid, and the only colour is the gold rule, the gold control, and the muted grey of the supporting line. On the Fixtures Hub, the same masthead logic scales up: the current gameweek numeral sits oversized at 96px mobile / 128px desktop, weight 900, gold, in the left columns as a section marker rather than a headline; "FIXTURES HUB" in 40px Archivo 900 uppercase and the subtitle in 16px muted grey sit to its right; and the Sync to Calendar control is pinned flush to the grid's right edge, sharing a baseline with the numeral. Beneath the masthead, a single row of four stat modules separated by hairlines — Gameweek, Fixtures, Live Now (with a red pulse dot when > 0), Goals (GW) — completes the first screen. No gradient, no blob, no centred composition.
Interaction Model: Static Motion Tempo: restrained Hero Dimensionality: flat
Landing Hero Motion Brief. The focal subject is the masthead itself: the 2px gold rule, the flush-left wordmark and supporting line, and the hard-edged gold entry control aligned to the grid's right edge. The input→transformation→outcome thesis is: on load, the gold rule draws across the full width and the wordmark and supporting line fade in at their final grid positions, so the visitor's first frame resolves into a ruled, grid-locked composition and the entry control is immediately legible as the single next action. Motion vocabulary: a 120ms opacity fade for the text block, staggered by 40ms, and a single IntersectionObserver fade for the section below; hover on the entry control is an instant colour inversion (gold fill, dark text) with a 100ms linear transition — no scale, no lift, no bounce. The composed first frame is the full-width gold rule with the wordmark, supporting line, and entry control already in their final grid positions. Under prefers-reduced-motion, all animation stops and the page renders in its final state.
Fixtures Hub motion. Fixture rows reveal with a 120ms opacity fade staggered by 40ms on mount. Live status bars pulse with a 2s ease-in-out opacity loop. The gameweek numeral counts up once on load over 600ms. Hover states are instant colour inversions with a 100ms linear transition. Section reveals use a single IntersectionObserver fade. The fixture ticker scrolls continuously and pauses on hover; under prefers-reduced-motion it becomes a static wrapped grid of whole cells, or a horizontally scrollable row (overflow-x: auto) whose further items are reached by scrolling. Under prefers-reduced-motion, all animation stops and content renders in its final state.
NFR-1 — Live-first data freshness. Match data must be requested from the plLive function first, and the stored Match entity sorted by kickoff must be used only when the live function returns no matches or fails. (explicit) — rationale: the product's value depends on live gameweek state, with stored data as a resilience path.
NFR-2 — Graceful degradation. A failure of the live match function, the player fetch, or the standings fetch must not prevent the rest of the Fixtures Hub from rendering. (explicit) — rationale: the source's fallback and catch behavior keeps the page usable when one data source is unavailable.
NFR-3 — Loading feedback. A loading spinner must be shown while the initial data fetch is in flight, and must be replaced by the page content once the fetch settles. (explicit) — rationale: the source renders the spinner in place of the page until loading completes.
NFR-4 — Readable text and controls at every viewport. Headlines, wordmarks, labels, numbers, and card text and controls must stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling to fit, with no other element covering any part of them. (explicit — creative direction) — rationale: legibility of dense data is the product's core value.
NFR-5 — Reduced-motion support. Under prefers-reduced-motion, all animation must stop and content must render in its final state; the fixture ticker must become a static wrapped grid of whole cells or a horizontally scrollable row whose further items are reached by scrolling. (explicit — creative direction) — rationale: motion is decorative and must not gate access to information.
NFR-6 — Anonymous access. Both the Landing page and the Fixtures Hub must be reachable without an account, and no sign-in, profile, or account-management capability is part of the product. (explicit — planning scope access contract) — rationale: the accepted journeys require no private durable state or identity-bound commitment.
NFR-7 — No gradients, glows, or rounded corners. The interface must use flat colour blocks, 2px rules, and 1px hairlines with 0px radius on cards, buttons, and inputs; gold and red are the only accents. (explicit — creative direction) — rationale: the Swiss Style direction treats colour as status code, not decoration.
StatCards, TopPerformers, GameweekFixtures, SidebarLeagueTable, FixtureTicker, and CalendarSync components. (explicit — source)lucide-react (Calendar, Trophy, CalendarClock, Radio, Target, CalendarPlus). (explicit — source)base44 client — base44.entities.Player.list("-avg_points", 60), base44.entities.Match.list("-kickoff", 50), and base44.functions.invoke("plLive"). (explicit — source)fetchPlStandings from @/lib/plStandings, returning a table array. (explicit — source)plLive function, the Player and Match entities, and the standings source. (explicit — planning scope)plLive function returns a payload with a matches array; when that array is empty or the invocation throws, the application falls back to the stored Match entity. (explicit — source)Player entity exposes an avg_points field used for descending sort, and the Match entity exposes kickoff, status, gameweek, home_score, and away_score fields. (explicit — source)table array; a failed fetch leaves the table empty without blocking the page. (explicit — source)null and the gameweek stat shows "—". (explicit — source)plLive — the live match data function invoked by the application; its results are used when present, with the stored Match entity as fallback.fetchPlStandings) that supplies the League Table rows.
Live gameweek fixtures, top performers, and the Premier League table.
Every match in the current gameweek, carrying its live, scheduled, or finished state on a hard-edged status bar — plus the running goal total for the round.
The players setting the pace, ranked by average points so the leading returns sit at the top of the list rather than buried in a squad view.
The full standings as a ruled tabular system, with position numbers held in the first column and every club reading down a single legible line.

Live gameweek fixtures, top performers, and the Premier League table.
Every match in the current gameweek, carrying its live, scheduled, or finished state on a hard-edged status bar — plus the running goal total for the round.
The players setting the pace, ranked by average points so the leading returns sit at the top of the list rather than buried in a squad view.
The full standings as a ruled tabular system, with position numbers held in the first column and every club reading down a single legible line.
No comments yet. Be the first!