Match player + preview
- Rebuild VS intro as a 1920×1080 scaled canvas (arena design from drafts/):
angled RED/BLUE panels with clip-paths, slam-in VS with pulse+shine,
event/stage/weight header, Match/Court/Referee chips, per-fighter
Record/Rank/Stats chip row. Every placeholder from the artifact is
always in the DOM; empty ones are hidden by `.vs-nullable:empty`
and `.vs-nullable-hide` so the layout adapts without losing the
design's HTML shape. Country codes always render as full country
names (via new App\Data\Countries::name()).
- Real-time 6s countdown Skip button; video pinned at t=0 while
the intro runs, released to play at zero or on Skip.
- Standalone preview page at /videos/{video}/vs-preview.
Video cards (home + everywhere)
- Match cards get a `vs-mini` overlay of the same arena design
(fixed canvas, per-card ResizeObserver, animations replay every
time the mouse leaves the thumb). On hover the mini explodes
outward (panels fly out, VS scales+blurs+fades) and the hover
video plays over the cleared thumb.
- Match cards also render a `scorebar-mini` overlay (verbatim of
the full-player msb-scale scorebar + msb-feed) that shows
during hover playback. Live-scoring is wired per-card via a
data-sbm-state payload of rounds+points; RED/BLUE score, round
label, per-round clock, and the top-right Live Scoring ticker
(4 entries, sport-aware Yuko/Waza-ari/Ippon or Punch/Body
kick/… labels) all update from the mini video's timeupdate.
Bug fixes
- Hover video wasn't playing sound: dropped the `muted` attribute
I'd added while debugging match previews.
- White flash strobing on the left of match cards: removed the
`.vs-mini-flash` element (intro-only flourish that fired on
every mouseleave replay).
- Sports-match modal was showing "Please complete the required
fields" when saving basic info for match videos that had no
SportsMatch row yet: the submit gate only checked matchId, not
the attached videoId; now it correctly skips uploadVideoFirst()
in both edit and attach-existing-video modes.
Country names project-wide
- New helper App\Data\Countries::name($iso2) → full country name.
- Swapped `?? country` fallbacks to `?? Countries::name(country)`
in admin dashboard, video-analytics, video-insights payloads
(VideoController + SuperAdminController), and the VS partials.
Now user-visible country labels always show "Bahrain" instead
of "BH", including chart tooltips and modal titles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds one chip per language currently present in public content —
counting both primary language and any secondary audio track, sorted
by video count, capped at 12. Clicking a chip lists every video whose
primary is that language or that has a matching secondary track; cards
surfaced only via a secondary track link straight to /videos/{key}?track=<id>
so the pinned playback wiring loads the right audio, get a small flag
badge on the thumbnail, and their hover-preview streams the track file
instead of the primary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The base card CSS (.yt-video-card/.yt-video-thumb/.yt-video-info) lived inside
video-card's @once <style> block, so it only emitted when a video card rendered.
Playlist cards reuse those classes, so on playlist-only pages (no video cards)
they rendered completely unstyled — a mess.
Extract the shared card CSS into resources/views/components/partials/card-styles
(kept @once) and @include it from BOTH video-card and playlist-card. Now the CSS
loads whenever either card renders, and @once still dedupes it to one copy on
pages that show both (home feed verified: emitted exactly once).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>