mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 03:09:57 +00:00
* feat(career): career plugin — stars from song_stats, venue tiers, pack downloads (career mode PR2) Bundled plugin: per-song stars from best_accuracy (60/75/85% → 1/2/3★), cumulative stars unlock bar → club → arena (data-driven venues.json). Venue packs (UE-rendered crowd loops) download on demand to CONFIG_DIR/plugin_uploads/career/ on a background thread with sha256 + zip-slip validation, served via FileResponse. Career screen (promoted sidebar entry) shows progress and pushes the active venue's manifest into the crowd video layer (v3VenueCrowd, PR1) — degrades cleanly when either side is absent. Pack URLs land in venues.json in PR3. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(career): keep manifest cleanup path alive on delete; badge only for installed venues Codex preflight: nulling _appliedManifestVenue on delete skipped pushCrowdManifest's setManifest(null) cleanup, leaving the crowd layer on a deleted pack; and the 'playing here' badge showed for an override venue whose pack was removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(career): generation-guard in-flight manifest fetches Codex preflight: a manifest fetch resolving after a newer refresh (pack deleted, venue switched) could re-apply a stale pack over the user's newer selection — fetches now carry a generation token and bail when superseded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(career): exclude orphaned song_stats from star totals Codex preflight: scans hide rather than delete stats of removed songs, so stars now apply the same existing-song filter other stats surfaces use (filename IN (SELECT filename FROM songs)). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(career): 50/150 star thresholds + star collection overview Byron's progression tuning: club at 50★, arena at 150★. /state now returns star_detail rows (title/artist joined from the library, stars, best accuracy, next-star threshold) sorted closest-to-next-star first, and the career screen renders a collection panel: tier summary plus a per-song list with a 'N% to next star' practice hint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(career): venue select/unselect UX, intro manifest support, fullmatch guards - 'Play here' now also defaults the visualization to Venue (remembering the prior viz); active venues show 'Leave venue' which restores it and sets the '__none__' override so no installed venue silently reapplies. - Pack manifests may ship an intro block (flyover video + ambience mp3); files validate like loops/stingers, .mp3 added to the serving whitelist. - Codex preflight: whitelist regexes use fullmatch (trailing-newline names could validate but 500 on serving). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(career): let pushCrowdManifest clear the manifest on Leave venue Codex preflight: nulling _appliedManifestVenue before refresh skipped the setManifest(null) cleanup branch, leaving the crowd playing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(career): refresh tailwind output --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
67 lines
1.8 KiB
CSS
67 lines
1.8 KiB
CSS
/* Career plugin — only what the prebuilt core Tailwind doesn't ship
|
|
(plugin files are outside the core content glob, so responsive grid
|
|
variants and cyan button shades live here under plugin-prefixed names). */
|
|
|
|
.career-venues {
|
|
display: grid;
|
|
gap: 1rem;
|
|
grid-template-columns: 1fr;
|
|
}
|
|
@media (min-width: 768px) {
|
|
.career-venues { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
}
|
|
|
|
.career-btn {
|
|
font-size: 0.75rem;
|
|
line-height: 1rem;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 0.375rem;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
.career-btn-primary { background-color: #0891b2; color: #fff; }
|
|
.career-btn-primary:hover { background-color: #06b6d4; }
|
|
.career-btn-ghost { background-color: rgba(31, 41, 55, 0.7); color: #d1d5db; }
|
|
.career-btn-ghost:hover { background-color: rgba(55, 65, 81, 0.9); }
|
|
|
|
.career-bar-track {
|
|
height: 0.5rem;
|
|
border-radius: 0.25rem;
|
|
background-color: rgba(31, 41, 55, 0.9);
|
|
overflow: hidden;
|
|
}
|
|
.career-bar-fill {
|
|
height: 100%;
|
|
background-color: #06b6d4;
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
.career-star-list {
|
|
display: grid;
|
|
gap: 0.375rem;
|
|
}
|
|
.career-star-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 0.75rem;
|
|
padding: 0.375rem 0.625rem;
|
|
border-radius: 0.5rem;
|
|
background-color: rgba(31, 41, 55, 0.4);
|
|
font-size: 0.8rem;
|
|
}
|
|
.career-star-row .stars {
|
|
color: #facc15;
|
|
letter-spacing: 0.1em;
|
|
min-width: 3.2em;
|
|
}
|
|
.career-star-row .stars .off { color: rgba(250, 204, 21, 0.25); }
|
|
.career-star-row .song {
|
|
color: #e5e7eb;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.career-star-row .song .artist { color: #9ca3af; }
|
|
.career-star-row .hint { color: #6b7280; white-space: nowrap; }
|
|
.career-star-row .hint.close { color: #22d3ee; }
|