- Remove VS intro from player and thumbnail VS card from match video cards.
All references (`msb-vs*`, `initVsIntro`, `setVsImg`, `HAS_VS`, `$vs`,
`$msbThumbVs`, `$hasMatchMeta`) are stripped from scoreboard partials,
video-card component, and scoreboard script. Related CSS keyframes
(`msbFadeIn/Out`, `msbDriftA/B`, `msbSweep`) removed.
- Image cropper (resources/views/components/image-cropper.blade.php):
replace unreliable third-party Cropme integration with a DIY cropper.
Pan/zoom/rotate wired directly with pointer + wheel events; on save,
the visible viewport is rendered to an offscreen canvas at the configured
output-width (with circular clip for `shape="circle"`). Also reparent the
overlay to <body> on open to escape any transformed Bootstrap-modal
ancestor's stacking context that clipped it.
- Sports match modal (resources/views/layouts/partials/sports-match-modal.blade.php):
set fighter photo croppers to 3:4 portrait (285x380) to match the VS
card's 228x304 frame; club logos + referee stay 1:1 square.
- SportsMatchController::fillFromRequest (line 174): coerce
`$this->clean($request->input('media', []))` to `[]` when it returns null
so array_merge doesn't crash under PHP 8's stricter types.
- SportsMatch::headerData(): read fighter headshots + club logos from the
canonical media.* keys (participant1_photo / participant2_photo /
club1_logo / club2_logo) that the uploader modal actually saves, with the
older p1_* / p2_* names kept as a secondary fallback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Scoreboard overlay driven by video.currentTime (scores/ticker/timeline as pure
functions of playback time; scrub-back removes points; slow-mo doesn't affect).
- Score bar + timeline + VS intro rendered verbatim from the design handoff
(drafts/score-bar.html, drafts/vs-screen.html) — only {{ }} data holes filled.
- Fixed 1150 px design canvas scaled to any player size via ResizeObserver so
the design's pixel-perfect measurements survive at every player width.
- Gear-menu injection adds a "Scoreboard" section with 7 toggle rows (Score bar,
Live scoring feed, Match info, Point timeline, Club logos, Country flags,
Penalties) using a custom 26x14 track/knob toggle matching the design.
Persists per user in localStorage['msb_prefs']; penalties defaults off.
- VS card fades in on first play of a session (skippable by click/tap/key,
2 s hold then 0.5 s fade); skipped entirely when no athlete metadata.
- SportsMatch::headerData() extended to expose sport, headshots, club logos,
division, format, match_date and per-video scoreboard defaults from existing
JSON columns (no schema migration).
- Every missing field hides its element (no "NOT SET" placeholders); athlete
name falls back to RED/BLUE per brief.
- Pushed .replay-badge down from top:2.5cqi to top:8cqi so it clears the
new KARATE KUMITE identity block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The match page header rendered hard-coded demo content (Sami Al Manea vs Hassan
Al Shallan, Match# 103, referee Ghassan Yusuf, external takeone-dev links) on
EVERY match video, ignoring the SportsMatch record the create form saves.
- Video::sportsMatch() hasOne relationship.
- SportsMatch::headerData() maps the record into the header's shape (fighters +
country flags, championship, weight class, referee, venue, match#/court),
null-safe, with a country-name/ISO2 -> flag-icons resolver.
- match.blade header now renders from headerData(): real names/flags, no
external links, and degrades gracefully to just title/views/date when a video
has no match data (instead of the fake card).
- sports-match-modal: add Match # and Court fields (stored in the existing
competition JSON, no migration) and convert fighter/referee country inputs to
the mandated <x-country-select> so header flags resolve from ISO2.
- Tracker updated for the new country-select usages.
Verified: empty state (no SportsMatch) shows only title/views/date; a populated
record renders fighters, flags (bh/us), championship, Match# 42, Court 3, U21,
referee; modal compiles with the new fields.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>