From 3f3dce5f871a2893d31b7c9eba7f5208aebda8f9 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Tue, 6 Oct 2026 02:15:54 +1100 Subject: [PATCH 1/2] feat(trending): put braille sparks and run chips on the board The new brand puts the dot motifs where the registry's evidence lives. Trending is the board readers copy from, so each row now shows its signal and its command in the brand shapes. - Each row with posts draws seven days of counted mentions as a braille spark. The loader already reads every post in the window, so the counts come from the same rows that rank the Skill, in rolling 24-hour days. - Surge and filler rows keep the star line, because stars ranked them. The surge reason now says it was a star surge, as VISION principle 4 asks of every trending number. - A compact run chip appears only where the row stands for exactly one Skill. Filler and the all-time range pick a Skill out of a repository, so a multi-Skill repository gets no command. Copies still report. - The skilld install chip sits in the header aside at every width. - The nav and the directory table drop the flame emoji for a braille mark, and the flame animation goes with it. - Ranks print in stone dots so the rose stays with the motifs. --- app/app.vue | 13 +++-- app/assets/css/main.css | 37 ------------- app/components/SkillTable.vue | 4 +- app/components/TrendingMark.vue | 33 ++++++++++++ .../app/components/TrendingBoardItem.vue | 38 +++++++++++--- .../marketing/app/pages/skills/trending.vue | 52 ++++++++++++++----- server/api/feed/trending.get.ts | 10 ++++ shared/mention-days.ts | 31 +++++++++++ shared/server/trending-skills.ts | 18 ++++++- shared/trending-range.ts | 41 +++++++++++++-- test/unit/mention-days.test.ts | 28 ++++++++++ test/unit/trending-range.test.ts | 21 ++++++++ test/unit/trending-skills.test.ts | 29 +++++++++++ 13 files changed, 283 insertions(+), 72 deletions(-) create mode 100644 app/components/TrendingMark.vue create mode 100644 shared/mention-days.ts create mode 100644 test/unit/mention-days.test.ts diff --git a/app/app.vue b/app/app.vue index 36d68bae..2581d83e 100644 --- a/app/app.vue +++ b/app/app.vue @@ -131,11 +131,10 @@ watch(() => route.fullPath, () => {
route.fullPath, () => { size="sm" class="hidden gap-1.5 whitespace-nowrap lg:inline-flex" > - + Trending Skills route.fullPath, () => { block class="min-h-11 justify-start gap-1.5 whitespace-nowrap" > - + Trending Skills /{{ skill.name }} - + Trending diff --git a/app/components/TrendingMark.vue b/app/components/TrendingMark.vue new file mode 100644 index 00000000..dbc47a0c --- /dev/null +++ b/app/components/TrendingMark.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/layers/marketing/app/components/TrendingBoardItem.vue b/layers/marketing/app/components/TrendingBoardItem.vue index ea56b2d1..1677311d 100644 --- a/layers/marketing/app/components/TrendingBoardItem.vue +++ b/layers/marketing/app/components/TrendingBoardItem.vue @@ -24,6 +24,14 @@ const emit = defineEmits<{ }>() const posts = computed(() => (row.reason._tag === 'posts' ? row.reason.posts : [])) + +/** + * Each row draws the signal that ranked it, and only that one. Mentions ranked + * a row with posts, so it gets the braille spark. Stars ranked a surge or a + * filler row, so those keep the star line. Two charts on one line would ask the + * reader which one put the row here. + */ +const mentions = computed(() => (row.reason._tag === 'posts' ? row.reason.mentionsByDay : null))