feat(hub): add notification badge slot on tiles

Reserves a top-right corner badge on each chakra tile, hidden when
the module has no unread items. The Module interface gains an
optional \`unread?: number\`; tiles render a 18×18 red pill with the
count (capped at "99+") in the top-right when unread > 0.

No data source yet — this is a placeholder slot. Wires to the
per-standalone notification feeds defined in #32: each standalone
will publish its unread count, hub aggregates and projects into the
modules array. Until then every tile renders without a badge.

Picked a red pill over the theme's primary because red is the
universal "unread" signal across iOS / Slack / Discord / Gmail.
Ring-1 ring-background gives a subtle halo against any tile shade.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-02 10:13:15 +02:00
commit 772c57fd85

View file

@ -31,6 +31,8 @@ interface Module {
glow: string
envKey?: string
status?: string
/** Unread count for the corner badge. Wire to real data via #32. */
unread?: number
}
// Lower (root/red) upper (crown/violet)
@ -113,6 +115,15 @@ function notImplemented() {
<p class="text-sm font-semibold text-foreground drop-shadow">{{ m.label }}</p>
<p v-if="m.status" class="text-[9px] font-light text-muted-foreground">{{ m.status }}</p>
</div>
<!-- Notification badge wired to data once #32 lands. Hidden when unread is falsy/0. -->
<span
v-if="m.unread"
class="absolute top-1.5 right-1.5 min-w-[18px] h-[18px] px-1 rounded-full bg-red-500 text-white text-[10px] font-semibold flex items-center justify-center shadow ring-1 ring-background/60"
:aria-label="`${m.unread} unread`"
>
{{ m.unread > 99 ? '99+' : m.unread }}
</span>
</component>
</div>
</div>