{#each statCards as card (card.label)}
{card.label}{card.value}
{/each}
Traffic & Growth (7-day windows)
Completions Velocity{signed(growth.completionsVelocity, "/day")}vs prior 7 daysCompletions Accel.{signed(growth.completionsAcceleration, "/day")}rate of change of velocityUser Velocity{signed(growth.userVelocity)}unique players, wk/wkUser Acceleration{signed(growth.userAcceleration)}rate of change of user velocityNew Players (7d){String(growth.newUsers7d)}first-time playersChurned (7d){String(growth.churned7d)}played wk prior, not this wkNet Growth (7d){signed(growth.netGrowth7d)}new minus churned
Survival Curve
Of players who completed N sessions, what % came back for N+1?
{#each sessionDepthCards as card (card.depth)}
After {card.depth} plays
{card.returnRate != null ? `${card.returnRate}%` : "N/A"}
{card.players} players
{/each}
New Player Return Rate (7-day rolling avg)
Return Rate (7d avg)
{newPlayerReturnVelocity.current7dAvg != null
? `${newPlayerReturnVelocity.current7dAvg}%`
: "N/A"}
new players who came backReturn Rate Change
{newPlayerReturnVelocity.change != null
? signed(newPlayerReturnVelocity.change, "pp")
: "N/A"}
vs prior 7 daysPrior 7d Avg
{newPlayerReturnVelocity.prior7dAvg != null
? `${newPlayerReturnVelocity.prior7dAvg}%`
: "N/A"}
days 8–14 ago
{#if newPlayerReturnSeries.length > 0}
Date
New Players
Return Rate
7d Avg
{#each (returnExpanded ? newPlayerReturnSeries : newPlayerReturnSeries.slice(0, 3)) as row (row.date)}
{mauMode === 'rolling' ? 'Unique players per 30-day window. Most recent first.' : 'Unique players per calendar month. Current month projected to end of month.'}
% of each day's players who played again exactly 7 or 30 days later (regardless of activity in between). Cohorts with fewer than 3 players are excluded.
7-Day Retention
{#if retention7dSeries.length === 0}
Not enough data yet.
{:else}
Cohort Date
n
Ret. %
{#each (ret7dExpanded ? retention7dSeries : retention7dSeries.slice(0, 3)) as row (row.date)}
{row.date}
{row.cohortSize}
{row.rate}%
{/each}
{#if retention7dSeries.length > 3}
{/if}
{/if}
30-Day Retention
{#if retention30dSeries.length === 0}
Not enough data yet.
{:else}
Cohort Date
n
Ret. %
{#each (ret30dExpanded ? retention30dSeries : retention30dSeries.slice(0, 3)) as row (row.date)}