NOTIFICATION CENTRE: "What happened since I last looked" drawer
CLASSES: .notification-centre | .notification-centre-group | .notification-centre-item | .notification-centre-item-unread | .notification-centre-item-icon | .notification-centre-item-body | .notification-centre-item-time | .notification-centre-empty | .notification-centre-footer | .notification-centre-trigger
COMPOSES: Drawer (.drawer shell + drawer_controller.js) | Empty State (.empty-state) | Badge (.badge-dot, .badge-notification)

A right-hand drawer surfacing application status changes, document requests, and event reminders for parents/applicants — infrequent, often first-time users with no login. Rows are grouped by day, unread rows carry a surface-tint wash + link-blue dot, and every row is a real button whose accessible name announces its read state. Requires notification_centre_controller.js for mark-read / mark-all-read — no fetch, the host page owns the data.

Mixed Read / Unread

Default: Two day groups ("Today", "Yesterday"). 3 of 5 rows are unread (surface-tint wash + link-blue dot before the timestamp). Clicking a row marks it read; "Mark all as read" clears the rest. The bell's .badge-notification count and aria-label stay in sync with the live unread count — there is no separate counter to desync.

<div class="drawer notification-centre"><div class="drawer-body"><h3 class="h6 notification-centre-group">Today</h3><button class="notification-centre-item notification-centre-item-unread">...</button></div></div>

Empty State

No notifications: Composes .empty-state inside .notification-centre-empty, which stretches to fill and center in the remaining drawer height. The footer is omitted entirely — there is nothing to mark as read — matching the Drawer pattern's own "Without Footer" precedent.

<div class="notification-centre-empty empty-state"><i class="fa-regular fa-bell empty-state-icon"></i><h3 class="empty-state-title">No notifications yet</h3>...</div>

9+ Badge Overflow

Overflow: 10 unread rows — the bell badge and its aria-label cap the displayed count at 9+ rather than growing the circle. (Checked components/badge.css: .badge-notification-ceil is a flush-to-top position variant, not a numeric-overflow variant — overflow is handled entirely by capping the badge's text content, the same idiom already shown in the Badge preview's "99+" example.) Use "Mark all as read" to watch the badge collapse and hide.

<span class="badge badge-danger badge-sm badge-circle badge-notification" data-notification-centre-target="badge">9+</span>

Quick Reference

Container: .drawer .notification-centre (composed together on the panel)
Group: .h6 .notification-centre-group (composed together on the day heading)
Row: .notification-centre-item | .notification-centre-item-unread | .notification-centre-item-icon | .notification-centre-item-body | .notification-centre-item-time
Empty: .notification-centre-empty .empty-state (composed together)
Footer: .drawer-footer .notification-centre-footer (composed together)
Trigger: .btn .btn-icon .notification-centre-trigger + .badge .badge-notification
Controller: data-controller="drawer notification-centre" | data-action="click->notification-centre#markRead" | data-action="click->notification-centre#markAllRead"
Events: notification-centre:read { id, unreadCount } | notification-centre:allRead { unreadCount: 0 }