Prometheus Design System v0.2.0 โ€” WIP

Inconsistency Resolution Log

Every inconsistency found in the audit, what was chosen as canonical, and why.

Upstream Status
The inconsistencies documented here have corresponding work tracked in the design system repository. As fixes are proposed as PRs to prometheus/prometheus, they will be linked here.

Upstream PRs: StatusBadge unification (proposed) ยท Filter bar consolidation (proposed) ยท localStorage key fix (proposed)

This page documents every inconsistency found during the codebase audit, the resolution chosen, and the reasoning behind each decision.

1. Health Badge Fragmentation

What was inconsistent

Three different approaches to health status badges across pages:

Variants that existed

PageImplementationColor Steps
AlertsPageCSS module classesgreen-1/green-9, red-1/red-9 (with light-dark())
RulesPageMantine color propMantine default shade (step-6 filled)
ScrapePoolsListConditional color propMantine default "green"/"red"

Canonical choice

The AlertsPage approach (CSS module classes with explicit light-dark() step-1/step-9 colors) was chosen as canonical because it provides the most precise dark mode support.

Reasoning

Migration

Replace all three patterns with <StatusBadge status="..." />. The component internally normalizes all status vocabularies.

2. Panel Border Inconsistency

What was inconsistent

AlertsPage and RulesPage both display accordion items with health-colored left borders, but used different color steps.

Variants that existed

PageImplementationLight Mode Steps
AlertsPagePanel.module.css classesgreen-3, red-3, orange-3, gray-3
RulesPageInline stylesgreen-4, red-4, gray-5

Canonical choice

Step-3 (light) / Step-8 (dark) from the AlertsPage implementation.

Reasoning

Migration

Replace both patterns with <HealthPanel status="..." />.

3. Duplicate Filter Bars

What was inconsistent

Four pages (AlertsPage, RulesPage, TargetsPage, ServiceDiscoveryPage) each had their own copy of the filter bar pattern: Group + StateMultiSelect + TextInput + optional ActionIcon.

Variants that existed

Canonical choice

A single FilterToolbar component with optional showCollapseAll prop.

Reasoning

The pattern is identical across all four pages. The only difference is whether a collapse/expand button is shown. A single component with a boolean flag is simpler than four separate implementations.

4. localStorage Key Collision (Bug)

What was inconsistent

Both AlertsPage and RulesPage used the key "alertsPage.showEmptyGroups". Toggling "show empty groups" on one page affected the other.

Resolution

RulesPage key changed to "rulesPage.showEmptyGroups".

Impact

Existing users lose their RulesPage toggle state on upgrade. The default value (false) is the correct initial state, so this is acceptable.

5. SeriesName Hover Colors

What was inconsistent

SeriesName label pair hover used hardcoded light-mode-only values:

/* Before โ€” light mode only */
.labelPair:hover {
  background: #add6ffa0;  /* hardcoded light blue */
  color: #495057;          /* hardcoded dark gray */
}

Resolution

/* After โ€” dark mode support */
.labelPair:hover {
  background-color: light-dark(rgba(173, 214, 255, 0.63), rgba(100, 149, 200, 0.3));
  color: light-dark(#495057, var(--mantine-color-gray-3));
}

Reasoning

The light mode values were preserved exactly. Dark mode values were derived by reducing opacity and using an appropriate gray for text.

6. Logo Font Size

What was inconsistent

The logo text used fz={20} โ€” a unitless number that doesn't scale with user font preferences.

Resolution

Changed to var(--prom-logo-font-size): 1.25rem (equivalent to 20px at default 16px root, but scales with user preferences).

7. Icon Style Duplication

What was inconsistent

The same icon style { width: "0.9rem", height: "0.9rem" } was defined locally in 3+ files. The source code even had a TODO: This is duplicated everywhere, unify it. comment.

Resolution

FilterToolbar and other components internally use the consistent icon size. For custom usage, the design system documents the standard sizes.

8. Pool Display Limit

What was inconsistent

targetPoolDisplayLimit = 20 was defined independently in both TargetsPage.tsx and ServiceDiscoveryPage.tsx.

Resolution

Moved to PoolAccordion as a shared constant. Both pages reference the same value.

What was inconsistent

Two separate Text elements controlled logo visibility:

<Text hiddenFrom="sm">Prometheus</Text>   // visible: xs only
<Text visibleFrom="md">Prometheus</Text>  // visible: md+

Between breakpoints sm and md, neither text was visible โ€” the "Prometheus" label disappeared.

Resolution

PrometheusAppShell uses a single Text element with correct responsive visibility that avoids the gap.