Frontend redesign chunk 2: primitives and marks
Rewrite components/ui/* (Button, Card, Badge, PageHeader, EmptyState, Skeleton) against the chunk-1 tokens instead of hardcoded gray-9xx classes, and drop the remaining font-mono from label/heading text. Add the three colour-blindness-validated encoding components from UI_REDESIGN.md §2.3: - components/marks/SeverityMark.tsx — glyph (filled triangle / outline triangle / outline circle) + optional spine + optional label, from the four-level severity ladder. Colour is never the only channel. - components/marks/TypeGlyph.tsx — five stroked SVG glyphs (fire, police, ems, collision, other) in currentColor. Incident type is now shape, not hue, since five hues can't clear an all-pairs CVD gate. - components/marks/NodeMark.tsx — diamond at four weights (filled+ring / filled / hollow / hollow-dashed). Green is gone from node state entirely. lib/severity.tsx now renders through SeverityMark; SEVERITY_COLORS reads the validated sev-moderate/sev-major tokens with routine/minor neutral. IncidentBadges.tsx's TypeBadge is reimplemented on TypeGlyph instead of a coloured pill. Per UI_REDESIGN.md chunk 2.
This commit is contained in:
@@ -10,10 +10,10 @@ interface EmptyStateProps {
|
||||
/** Consistent "nothing here yet" panel — replaces the ad-hoc `<p className="text-gray-600">` scattered across pages. */
|
||||
export function EmptyState({ icon, title, description, action }: EmptyStateProps) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center text-center py-12 px-6 border border-dashed border-gray-800 rounded-xl">
|
||||
{icon && <div className="text-gray-700 mb-3">{icon}</div>}
|
||||
<p className="text-gray-300 text-sm font-semibold font-mono">{title}</p>
|
||||
{description && <p className="text-gray-600 text-xs font-mono mt-1 max-w-sm">{description}</p>}
|
||||
<div className="flex flex-col items-center justify-center text-center py-12 px-6 border border-dashed border-line-strong rounded-xl">
|
||||
{icon && <div className="text-ink-muted mb-3">{icon}</div>}
|
||||
<p className="text-ink text-sm font-semibold">{title}</p>
|
||||
{description && <p className="text-ink-muted text-xs mt-1 max-w-sm">{description}</p>}
|
||||
{action && <div className="mt-4">{action}</div>}
|
||||
</div>
|
||||
);
|
||||
@@ -22,8 +22,8 @@ export function EmptyState({ icon, title, description, action }: EmptyStateProps
|
||||
/** Inline error banner — for API/Firestore errors surfaced within a page section. */
|
||||
export function ErrorBanner({ message }: { message: string }) {
|
||||
return (
|
||||
<div className="bg-red-950 border border-red-800 rounded-lg p-4">
|
||||
<p className="text-red-400 text-sm font-mono">{message}</p>
|
||||
<div className="bg-sev-major/10 border border-sev-major/40 rounded-lg p-4">
|
||||
<p className="text-sev-major text-sm">{message}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user