diff --git a/web/src/routes/admin/tuning/+page.svelte b/web/src/routes/admin/tuning/+page.svelte
index f1b8419b..bececa1f 100644
--- a/web/src/routes/admin/tuning/+page.svelte
+++ b/web/src/routes/admin/tuning/+page.svelte
@@ -428,13 +428,12 @@
Weekly trends
- Skip and completion are the most recent week only —
- the number after the skip rate is that week's play count, so a rate off a
- handful of plays reads as what it is. Plays and Taste hit cover the whole
- window.
Skip rate per surface over the last {trends?.weeks ?? 12} weeks (lower is better; all
users aggregated, rates only). Dashed ticks mark tuning changes. Taste hit is the share
of plays whose artist fits the current taste profile.
+ The skip and completion columns show the most recent week
+ alone, not the whole window — the figure after the skip rate is that week's
+ play count, so a rate drawn from a handful of listens reads as what it is.
{#if trendsFailed}
diff --git a/web/src/routes/admin/tuning/tuning.test.ts b/web/src/routes/admin/tuning/tuning.test.ts
index d0e2f63c..00abfa72 100644
--- a/web/src/routes/admin/tuning/tuning.test.ts
+++ b/web/src/routes/admin/tuning/tuning.test.ts
@@ -210,8 +210,11 @@ describe('Admin tuning page', () => {
// The window/last-week distinction has to be visible in the headers, or the
// Plays total reads as the denominator of the skip rate. That misreading is
// what #2495 was filed over.
- expect(screen.getByText(/Plays/)).toHaveTextContent('(window)');
- expect(screen.getByText(/^Skip/)).toHaveTextContent('(last wk)');
+ //
+ // Queried as column headers rather than by text: the caption below also
+ // mentions "Plays", and matching on the word finds the prose too.
+ expect(screen.getByRole('columnheader', { name: /Plays/ })).toHaveTextContent('(window)');
+ expect(screen.getByRole('columnheader', { name: /^Skip/ })).toHaveTextContent('(last wk)');
// The knob turn is listed under the chart AND tooltipped on each
// sparkline's marker tick, hence getAllBy.
expect(