feat(stats): use generic title wording for mixed-source library

The stats dashboard now supports both anime series and YouTube videos
in the same library, so the anime-only copy no longer fits. Rename
user-visible labels ("Active Anime", "Search anime…", "Anime — Per
Day", "Episodes per Anime", "Words In Multiple Anime", etc.) to use
"Title"/"Library" wording that covers either source.

Data-model names (animeId, animeCount, useAnimeLibrary) stay as-is;
this pass only touches strings the user actually reads.
This commit is contained in:
2026-04-09 01:55:49 -07:00
parent b1acbae580
commit c5e778d7d2
6 changed files with 20 additions and 20 deletions

View File

@@ -93,7 +93,7 @@ export function AnimeTab({
<div className="flex items-center gap-3">
<input
type="text"
placeholder="Search anime..."
placeholder="Search library..."
value={search}
onChange={(e) => setSearch(e.target.value)}
className="flex-1 bg-ctp-surface0 border border-ctp-surface1 rounded-lg px-3 py-2 text-sm text-ctp-text placeholder:text-ctp-overlay2 focus:outline-none focus:border-ctp-blue"
@@ -125,12 +125,12 @@ export function AnimeTab({
))}
</div>
<div className="text-xs text-ctp-overlay2 shrink-0">
{filtered.length} anime · {formatDuration(totalMs)}
{filtered.length} titles · {formatDuration(totalMs)}
</div>
</div>
{filtered.length === 0 ? (
<div className="text-sm text-ctp-overlay2 p-4">No anime found</div>
<div className="text-sm text-ctp-overlay2 p-4">No titles found</div>
) : (
<div className={`grid ${GRID_CLASSES[cardSize]} gap-4`}>
{filtered.map((item) => (

View File

@@ -36,7 +36,7 @@ export function HeroStats({ summary, sessions }: HeroStatsProps) {
/>
<StatCard label="Current Streak" value={`${summary.streakDays}d`} color="text-ctp-peach" />
<StatCard
label="Active Anime"
label="Active Titles"
value={formatNumber(summary.activeAnimeCount)}
color="text-ctp-mauve"
/>

View File

@@ -71,7 +71,7 @@ export function TrackingSnapshot({
</div>
</div>
</Tooltip>
<Tooltip text="Total unique episodes (videos) watched across all anime">
<Tooltip text="Total unique videos watched across all titles in your library">
<div className="rounded-lg bg-ctp-surface1/60 p-3">
<div className="text-xs uppercase tracking-wide text-ctp-overlay2">Episodes</div>
<div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-blue">
@@ -79,9 +79,9 @@ export function TrackingSnapshot({
</div>
</div>
</Tooltip>
<Tooltip text="Number of anime series fully completed">
<Tooltip text="Number of titles fully completed">
<div className="rounded-lg bg-ctp-surface1/60 p-3">
<div className="text-xs uppercase tracking-wide text-ctp-overlay2">Anime</div>
<div className="text-xs uppercase tracking-wide text-ctp-overlay2">Titles</div>
<div className="mt-1 text-xl font-semibold font-mono tabular-nums text-ctp-sapphire">
{formatNumber(summary.totalAnimeCompleted)}
</div>

View File

@@ -120,7 +120,7 @@ export function SessionRow({
}}
aria-label={`View overview for ${session.canonicalTitle ?? 'Unknown Media'}`}
className="absolute right-10 top-1/2 -translate-y-1/2 w-5 h-5 rounded border border-ctp-surface2 text-transparent hover:border-ctp-blue/50 hover:text-ctp-blue hover:bg-ctp-blue/10 transition-colors opacity-0 group-hover:opacity-100 focus:opacity-100 flex items-center justify-center"
title="View anime overview"
title="View in Library"
>
{'\u2197'}
</button>

View File

@@ -221,7 +221,7 @@ export function TrendsTab() {
type="line"
/>
<SectionHeader>Anime Per Day</SectionHeader>
<SectionHeader>Library Per Day</SectionHeader>
<AnimeVisibilityFilter
animeTitles={animeTitles}
hiddenAnime={activeHiddenAnime}
@@ -239,21 +239,21 @@ export function TrendsTab() {
})
}
/>
<StackedTrendChart title="Episodes per Anime" data={filteredEpisodesPerAnime} />
<StackedTrendChart title="Watch Time per Anime (min)" data={filteredWatchTimePerAnime} />
<StackedTrendChart title="Videos per Title" data={filteredEpisodesPerAnime} />
<StackedTrendChart title="Watch Time per Title (min)" data={filteredWatchTimePerAnime} />
<StackedTrendChart
title="Cards Mined per Anime"
title="Cards Mined per Title"
data={filteredCardsPerAnime}
colorPalette={cardsMinedStackedColors}
/>
<StackedTrendChart title="Words Seen per Anime" data={filteredWordsPerAnime} />
<StackedTrendChart title="Lookups per Anime" data={filteredLookupsPerAnime} />
<StackedTrendChart title="Words Seen per Title" data={filteredWordsPerAnime} />
<StackedTrendChart title="Lookups per Title" data={filteredLookupsPerAnime} />
<StackedTrendChart
title="Lookups/100w per Anime"
title="Lookups/100w per Title"
data={filteredLookupsPerHundredPerAnime}
/>
<SectionHeader>Anime Cumulative</SectionHeader>
<SectionHeader>Library Cumulative</SectionHeader>
<StackedTrendChart title="Watch Time Progress (min)" data={filteredWatchTimeProgress} />
<StackedTrendChart title="Episodes Progress" data={filteredAnimeProgress} />
<StackedTrendChart

View File

@@ -72,7 +72,7 @@ export function CrossAnimeWordsTable({
>
{'\u25B6'}
</span>
Words In Multiple Anime
Words Across Multiple Titles
</button>
<div className="flex items-center gap-3">
{hasKnownData && (
@@ -97,8 +97,8 @@ export function CrossAnimeWordsTable({
{collapsed ? null : ranked.length === 0 ? (
<div className="text-xs text-ctp-overlay2 mt-3">
{hideKnown
? 'All multi-anime words are already known!'
: 'No words found across multiple anime.'}
? 'All words that span multiple titles are already known!'
: 'No words found across multiple titles.'}
</div>
) : (
<>
@@ -109,7 +109,7 @@ export function CrossAnimeWordsTable({
<th className="text-left py-2 pr-3 font-medium">Word</th>
<th className="text-left py-2 pr-3 font-medium">Reading</th>
<th className="text-left py-2 pr-3 font-medium w-20">POS</th>
<th className="text-right py-2 pr-3 font-medium w-16">Anime</th>
<th className="text-right py-2 pr-3 font-medium w-16">Titles</th>
<th className="text-right py-2 font-medium w-16">Seen</th>
</tr>
</thead>