Includes the BMAD install config, the initiative ticket tree, the portal
context-resources scripts, and the .gitignore change that tracks BMAD files
(generated _bmad/render/ is ignored).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sk72AxLwQnYttF6VFSxQLt
Calm, utility-style self-service portal for a homelab, in the spirit of the Microsoft 365 admin center. Fluent 2 web components; this DESIGN.md specifies the brand-layer delta and the portal's own components.
A calm utility. The portal should feel like the Microsoft 365 admin center's settings pages: clean, plain and confident, one clear task per page, with nothing decorative. The people who use it are not technical, so the design earns trust through restraint and legibility, not through personality. It follows Fluent 2 so the controls behave the way these users already know from Microsoft products.
Light and dark are equal citizens. The portal follows the system theme by default and the user can override it per device. The accent colour is portal-wide and set by the Admin.
Mock-ups: mockups/key-dashboard.html, mockups/key-password.html, mockups/key-picture-pending.html, mockups/key-announcement-editor.html, mockups/key-admin-appearance.html, mockups/key-admin-status.html, mockups/key-admin-audit.html. The spine wins on conflict.
Colors
{colors.brand} is the one accent: top bar, primary buttons, active-nav marker and focus emphasis. It is Admin-changeable (FR-22). In dark mode the lighter {colors.brand-dark} is used with {colors.on-brand-dark} text.
Neutrals (background, surface, nav-surface, text, text-secondary, line) carry almost everything; the dark variants have the -dark suffix. Cards sit on {colors.surface} above {colors.background}.
Severity colours colour only the left edge and icon of an announcement banner: {colors.severity-info}, {colors.severity-warning}, {colors.severity-outage}. Colour is never the only signal; each severity also has an icon and a word.
Pending uses {colors.pending-surface} and {colors.pending-text} for the "being updated" chip and nothing else.
Success ({colors.success}) marks healthy job status and saved confirmations.
Contrast. All text and control pairs meet WCAG 2.1 AA in both themes. The Admin colour check (EXPERIENCE.md, Admin Appearance) computes contrast for the chosen brand colour against {colors.on-brand} (light) and {colors.on-brand-dark} (dark) and warns when below 4.5:1.
Typography
One family, the system stack {typography.family}, because the security policy allows no external fonts. A small ramp: {typography.page-title} for the page heading ({typography.page-title-phone} on phones), {typography.card-title} for cards, {typography.body} for text, {typography.label} for field labels, {typography.small} and {typography.hint} for explanations. The announcement editor's source view, if shown, uses {typography.mono-editor}. Sentence case everywhere; no all-caps except the small group headings in the menu.
Layout & Spacing
Left menu ({spacing.nav-width}) plus a content area on desktop; the menu collapses behind a menu button on phones. Content is left-aligned in cards on a single column; two columns of cards only on the dashboard and the status page, stacked on phones. Page padding is {spacing.page-padding} ({spacing.page-padding-phone} on phones); cards are separated by {spacing.card-gap}. Lines of explanatory text stay below about 640 px wide. Touch targets are at least {spacing.touch-target-min} on phones. On phones, label/value rows stack and long values wrap, so nothing is cut off at the right edge.
Elevation & Depth
Flat. Depth comes from a 1 px {colors.line} border and the surface/background step, not from shadows. The only shadows are on the profile menu (a popover) and on dialogs.
Shapes
Small, even radii: {rounded.sm} for buttons and inputs, {rounded.md} for banners, {rounded.lg} for cards, {rounded.pill} for chips, {rounded.full} for avatars.
Components
Component
Visual spec
Top bar
{components.top-bar}: portal name at left, profile picture at right (opens the profile menu). On phones a menu button replaces the left menu. Dark mode uses {components.top-bar-dark}.
Left menu
Items {components.nav-item}; active item {components.nav-item-active}. Group headings "Veröffentlichen" and "Administration" appear only for Publishers and Admins, in small upper-case text.
Card
{components.card}; title {typography.card-title}.
Announcement banner
{components.banner}: left edge in the severity colour, icon, bold title, one or two lines of text. At most the active announcements, newest first.
Pending chip
{components.chip-pending} with the text "Wird aktualisiert".
Buttons
Primary {components.button-primary}; secondary {components.button-secondary}. One primary per card.
Fields
{components.input}; label above, hint below in {typography.hint}; error text below in the outage colour with an icon.
Profile menu
Popover from the avatar: name and username, theme (Hell, Dunkel, System), language (Deutsch, English), address form (Sie, Du; German only), sign-out.
Rich text editor
Toolbar above a text area that shows the result: bold, italic, heading, list, link. Same border as inputs.
Tables
Compact rows with {colors.line} separators, used for the audit log, job status and failed mail.
Filter chips
Pill buttons; the selected chip uses {colors.brand}.
Colour field (Admin)
Swatch, hex field, contrast table (light and dark), warning box.
Do's and Don'ts
Do keep one primary action per card and say what it will do and what happens next.
Do show state in words as well as colour.
Do keep pages short; split a long page before adding scrolling sections.
Don't add decoration, illustrations or animation beyond Fluent's own.
Don't use more than the one brand accent.
Don't hide a state in colour alone, or in hover.
Don't load fonts, icons or scripts from the network.