WIP: Dashboard redesign — design system overhaul and component updates
Frontend redesign in progress: updated styles, layout, and components across all pages to align with new design system. Includes Jira API compliance specs, property tests, and load test script.
This commit is contained in:
235
docs/design-system-redesign/README.md
Normal file
235
docs/design-system-redesign/README.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# STEAM Security Design System
|
||||
|
||||
A design system for the **STEAM Security Dashboard** — a self-hosted vulnerability management workbench used by the NTS-AEO-STEAM and NTS-AEO-ACCESS-ENG business units. This repo captures the visual language, content patterns, tokens, and UI kit needed to extend or rebuild the product without drifting from its established look.
|
||||
|
||||
## What the product is
|
||||
|
||||
The STEAM Security Dashboard centralises:
|
||||
|
||||
- **CVE tracking** — searchable, filterable, vendor-aware CVE list with NVD auto-fill, document attachment, and group-based ownership
|
||||
- **Ivanti / RiskSense host findings** — live remediation queue with FP / Archer / CARD workflows, inline editing, per-finding notes, and a personal "Ivanti Queue" staging list
|
||||
- **AEO compliance posture** — weekly xlsx upload with drift detection, diff preview, per-team metric health cards, device-level violation tracking, and timestamped notes
|
||||
- **Archer EXC tickets** — risk-acceptance ticket tracking linked to CVE / vendor pairs
|
||||
- **Knowledge base** — internal document library (PDF, Markdown, Office, etc.) for runbooks, advisories, and policies
|
||||
- **Admin panel** — user / group management, audit log, system info — all gated behind an Admin group
|
||||
|
||||
Four user groups (`Admin`, `Standard_User`, `Leadership`, `Read_Only`) define every permission boundary, and every state-changing action is audit-logged.
|
||||
|
||||
## The 6 pages
|
||||
|
||||
1. **Home / Dashboard** — CVE list, filters, calendar widget for due dates
|
||||
2. **Reporting** — Ivanti host findings, charts, queue, export
|
||||
3. **Compliance** — AEO posture, metric health cards, device drill-in
|
||||
4. **Knowledge Base** — document library
|
||||
5. **Exports** — bulk export tools (group-gated)
|
||||
6. **Admin Panel** — user management, audit log, system info (Admin only)
|
||||
|
||||
## Sources
|
||||
|
||||
- **Codebase:** `https://vulcan.apophisnetworking.net/jramos/cve-dashboard` (Gitea, master branch). Auth required; raw file fetch is gated. The repo's own `README.md` (fetched via the source viewer) is the most accurate functional spec we had access to and is the basis for this system.
|
||||
- **Existing design ref:** `DESIGN_SYSTEM.md` (290 lines, in-repo) — referenced in the audit but not directly accessible from the host.
|
||||
- **Component audit** provided in the project brief: 29 components, 5 primitives, 14 composites, 5 pages, 1 context provider.
|
||||
- **Stack:** React 19, lucide-react, recharts, react-markdown + rehype-sanitize, mermaid, xlsx. Backend Express 5 / SQLite3.
|
||||
|
||||
## Index — what's in this folder
|
||||
|
||||
| Path | What it is |
|
||||
|---|---|
|
||||
| `README.md` | This file — context, content + visual foundations, iconography |
|
||||
| `SKILL.md` | Agent Skill manifest for Claude Code compatibility |
|
||||
| `colors_and_type.css` | Source-of-truth tokens — color, type, spacing, radii, elevation |
|
||||
| `fonts/` | Font references (Outfit + JetBrains Mono via Google Fonts CDN) |
|
||||
| `assets/` | Logo mark, brand SVGs, severity icons |
|
||||
| `preview/` | Design System tab cards — registered as assets |
|
||||
| `ui_kits/cve-dashboard/` | High-fidelity recreation of the dashboard, focused on Knowledge Base |
|
||||
|
||||
---
|
||||
|
||||
## CONTENT FUNDAMENTALS
|
||||
|
||||
The product is a tactical operations console for security engineers. Copy is dense, terse, and assumes a reader who already knows what a CVE, EXC ticket, FP workflow, and BU filter are. There is no marketing voice, no onboarding nudges, and no exclamation marks.
|
||||
|
||||
### Voice & tone
|
||||
- **Operational, not editorial.** Buttons say "Sync", "Confirm Upload", "Reconcile Config", "Add to Queue". Never "Let's get started" or "You're all set".
|
||||
- **Imperative for actions, declarative for state.** "Save", "Delete", "Hide Selected" — never "Saving your changes…" with three dots and a heart.
|
||||
- **No emoji.** Status is communicated through colour-coded badges and short text labels.
|
||||
- **Title Case for navigation and headers**, Sentence case for body and inline labels. Tabs and buttons: `User Management`, `Audit Log`, `System Info`. Helper text: `Filter tickets by CVE ID, vendor, or status.`
|
||||
|
||||
### Person & address
|
||||
- **Second-person sparingly** — only when the system is talking *about* the user's data: "your login", "your filtered view", "your queue". Never "Welcome back, {name}".
|
||||
- **First-person plural never.** No "We've updated" or "Let us know".
|
||||
- **Errors are direct, no apology.** "SESSION_SECRET environment variable must be set." "Login rate limited — wait 15 minutes." Never "Oops! Something went wrong."
|
||||
|
||||
### Casing
|
||||
- **CVE IDs:** uppercase with hyphen — `CVE-2024-12345`. Validated against `/^CVE-\d{4}-\d{4,}$/`.
|
||||
- **EXC numbers:** uppercase — `EXC-12345`. Validated `/^EXC-\d+$/`.
|
||||
- **Severity labels:** Title Case — `Critical`, `High`, `Medium`, `Low`. Status labels: `Open`, `Addressed`, `In Progress`, `Resolved`.
|
||||
- **Workflow state badges:** SHOUT CASE for SLA states only — `OVERDUE`, `AT_RISK`, `WITHIN_SLA`. Everything else is Title Case.
|
||||
- **Group names:** snake_case in code (`Standard_User`), Title Case in UI (`Standard User`).
|
||||
|
||||
### Density and units
|
||||
- Numerical metrics are bare integers ("12 findings", "47 devices"). Percentages always carry the % sign with no space.
|
||||
- Dates are explicit, no relative time except "Last sync: 4h ago" patterns.
|
||||
- Column headers are short — `Host`, `IP Address`, `DNS`, `BU`, `SLA` — never `Host Name (Editable)`.
|
||||
|
||||
### Specific copy conventions seen in product
|
||||
- "— empty —" as a filter option for empty cells
|
||||
- "Hidden (N)" pattern for counted UI states
|
||||
- "+N" badge for overflow (e.g., 2 CVEs shown, "+5" badge)
|
||||
- "↻" revert glyph next to overridden cells, with a small amber dot ● for the overridden state
|
||||
- Tooltips appear after a 300ms delay and are session-cached
|
||||
- "View in Reporting →" inline link pattern with a literal arrow
|
||||
|
||||
### What NOT to write
|
||||
- No motivational copy ("Great work!", "You're crushing it")
|
||||
- No question-mark headlines ("Need help?")
|
||||
- No marketing CTAs ("Upgrade now", "Try premium")
|
||||
- No mascot or persona — the system is the system
|
||||
|
||||
---
|
||||
|
||||
## VISUAL FOUNDATIONS
|
||||
|
||||
The dashboard reads as a **dark tactical intelligence console** — slate / graphite backgrounds, sky-blue as the primary accent and ambient glow, severity colours used like signal flags, animated pulse-glow status dots, and information density prioritised over breathing room. The aesthetic is closer to a SOC / NOC mission display than to a flat enterprise SaaS.
|
||||
|
||||
### Colour vibe
|
||||
- **Dark slate base.** `#0F172A` (deep slate) for the page, `#1E293B` for surfaces, `#334155` for elevated surfaces and borders. Almost black, never pure black. The cool tone is consistent — no warm shadows.
|
||||
- **Sky blue is the brand accent** — `#38BDF8` is the primary action / link / focused state colour. It appears in buttons, active nav items, link text, and the "create" badge in the audit log.
|
||||
- **Severity is a fixed semantic system** — the colours below MUST mean what they mean and nothing else.
|
||||
- Critical → Red `#EF4444`
|
||||
- High → Amber `#F59E0B`
|
||||
- Medium → Sky `#38BDF8`
|
||||
- Low → Emerald `#10B981`
|
||||
- **Neutral text scale** — `#F1F5F9` (primary fg), `#CBD5E1` (secondary), `#94A3B8` (muted), `#64748B` (placeholder / disabled). Never pure white.
|
||||
- **Group badges** — Admin red, Standard_User accent blue, Leadership amber, Read_Only muted grey. The same severity language reappears here for status urgency.
|
||||
|
||||
### Typography
|
||||
- **Outfit** for all UI (headers, body, buttons, navigation). Geometric sans, friendly but precise; weights 400 / 500 / 600 / 700.
|
||||
- **JetBrains Mono** for *data* — CVE IDs, IP addresses, hostnames, EXC numbers, finding IDs, code blocks. Anything you'd grep for.
|
||||
- **Scale** is compact. Page titles 24–28px / 600 weight; section headers 16–18px / 600; body 14px / 400; data table cells 13px / 400 mono. Line-height stays tight (1.4) to preserve density.
|
||||
|
||||
### Spacing
|
||||
- **4 / 8 / 12 / 16 / 24 / 32 / 48** — a roughly 4px grid. Cards have 16–20px internal padding; rows in dense tables have 8–10px vertical padding; modals have 24px internal padding.
|
||||
- **Section gaps** are 24–32px. Between siblings, 12–16px is the dominant rhythm.
|
||||
|
||||
### Backgrounds
|
||||
- **No imagery.** No hero photographs, illustrations, or marketing visuals. The page is solid `#0F172A`.
|
||||
- **Subtle sky-blue grid is allowed.** A 20×20px grid at `rgba(14,165,233,0.025)` (`.grid-bg` utility) sits behind hero / empty regions. It is barely visible and never dominates.
|
||||
- **Surfaces use diagonal gradients**, not flat fills — `linear-gradient(135deg, rgba(30,41,59,0.95), rgba(51,65,85,0.9))` is the canonical card surface.
|
||||
|
||||
### Cards and surfaces (`intel-card`)
|
||||
- **Background:** diagonal gradient `135deg, rgba(30,41,59,0.95) 0%, rgba(51,65,85,0.9) 50%, rgba(30,41,59,0.95) 100%`
|
||||
- **Border:** 1.5px solid `rgba(14,165,233,0.30)` — sky-blue at low alpha, not slate grey
|
||||
- **Radius:** 8px (default) / 12px (modals) / 4px (chips)
|
||||
- **Internal padding:** 16–20px
|
||||
- **Resting shadow:** `0 4px 12px rgba(0,0,0,0.4)` + `0 2px 6px rgba(0,0,0,0.3)` + inset `0 1px 0 rgba(14,165,233,0.10)` (sky highlight on top edge)
|
||||
- **Hover:** border opacity climbs to `0.50`, the card lifts `translateY(-2px)`, and gains a `0 0 30px rgba(14,165,233,0.10)` ambient glow. A `::after` shimmer sweeps left→right on entry.
|
||||
- **Stat cards** add a 2px `linear-gradient(90deg, transparent, #0EA5E9, transparent)` rail on the top edge.
|
||||
|
||||
### Borders
|
||||
- **Sky-blue at low alpha** is the dominant border treatment — `rgba(14,165,233,0.15)` for subtle dividers, `0.25` for default, `0.40` for strong / hover. Pure slate `#334155` borders appear only on tables and inputs at rest.
|
||||
- Focus state: 2px sky-blue ring `0 0 0 2px rgba(14,165,233,0.15)` plus the border swaps to solid `#0EA5E9`.
|
||||
- Severity-tinted left borders are NOT a pattern — colour is carried by badges, dots, and glow.
|
||||
|
||||
### Animation
|
||||
- **Pulse-glow on status dots is canonical.** Every severity / SLA badge has an 8px circle that pulses `box-shadow: 0 0 5px → 15px currentColor` on a 2s ease-in-out loop (`@keyframes pulse-glow`).
|
||||
- **Card hover lift** is 300ms cubic-bezier(0.4,0,0.2,1) with a `::after` shimmer sweep — `linear-gradient(90deg, transparent, rgba(14,165,233,0.08), transparent)` translating from `left:-100%` to `100%` over 500ms.
|
||||
- **Buttons** have a circular ripple `::before` that scales from 0×0 to 300×300 on hover (500ms).
|
||||
- Modal entry: 200ms fade + slight translate. Slide-out panels: 240ms ease-out from the right.
|
||||
- Tooltips have a deliberate **300ms hover delay** before appearing.
|
||||
- A `.scan-line` utility (3s loop) is available for hero / loading affordances — used sparingly.
|
||||
|
||||
### Hover states
|
||||
- **Cards** lift `-2px`, border opacity climbs from `0.30` → `0.50`, and a sky-blue ambient glow `0 0 30px rgba(14,165,233,0.10)` appears.
|
||||
- **Buttons** brighten their gradient fill from `0.15/0.10` to `0.25/0.20` alpha, gain a `0 0 20px` brand-color glow, and lift `-1px`.
|
||||
- **Text links** lighten from `#38BDF8` to `#7DD3FC` and the bottom border brightens to match.
|
||||
- **Table rows** get a `rgba(0,217,255,0.06)` wash plus `0 2px 8px rgba(0,217,255,0.10)` sub-shadow.
|
||||
- The audit notes a current anti-pattern: hover states implemented via `onMouseEnter` / `onMouseLeave` JS handlers. The design system standard is **CSS `:hover` pseudo-classes** — JS hover is a defect to migrate away from.
|
||||
|
||||
### Press / active states
|
||||
- Button: shifts to `#0EA5E9` (slightly darker than hover), no shrink, no shadow change. Press is a colour signal, not a physics signal.
|
||||
- Rows / interactive cards: `#475569` background on `:active`.
|
||||
|
||||
### Transparency & blur
|
||||
- Modal backdrops: `rgba(10, 14, 39, 0.97)` with `backdrop-filter: blur(12px)`. The blur is heavy and the backdrop is near-opaque — modals fully obscure the background.
|
||||
- Tooltips: gradient `linear-gradient(135deg, #334155, #475569)` with a sky-blue border and `0 4px 12px` + `0 0 16px rgba(14,165,233,0.15)` glow.
|
||||
- Inputs: translucent `rgba(30,41,59,0.6)` background with `inset 0 2px 4px rgba(0,0,0,0.2)` for a subtle recessed feel.
|
||||
|
||||
### Inner / outer shadows
|
||||
- **Both are used.** Cards combine outer drop + inner sky-blue highlight: `0 4px 12px rgba(0,0,0,0.4), inset 0 1px 0 rgba(14,165,233,0.10)`.
|
||||
- **Inputs are recessed** — `inset 0 2px 4px rgba(0,0,0,0.2)` plus a `0 1px 0 rgba(255,255,255,0.03)` top sheen.
|
||||
- **Document items** (within KB / vendor lists) use a stronger inset `inset 0 2px 4px rgba(0,0,0,0.3)` to read as nested / pressed-in.
|
||||
- Modals lift on `0 20px 60px rgba(0,0,0,0.6) + 0 10px 30px rgba(14,165,233,0.10)` — heavier than most enterprise products, but the brand glow is the signature.
|
||||
|
||||
### Layout rules
|
||||
- **Full-width fluid** above 1024px — the dashboard fills the viewport, with content max-width capping at ~1600px on very wide displays.
|
||||
- **Top app bar is fixed** — height 56px, contains brand mark, page nav, and `UserMenu`. Sits above all content with `z-index: 50`.
|
||||
- **Side nav drawer (NavDrawer)** slides from the left on icon click; it does *not* push content (overlay model).
|
||||
- **Slide-out panels** (Atlas, Compliance Detail) come from the right, ~480px wide on desktop, full-width on narrow viewports.
|
||||
- **Modals** are centered, max-width 640px (small) or 960px (wizard / upload), with the standard backdrop.
|
||||
|
||||
### Severity language
|
||||
This is the most important visual rule in the product. Severity badges use the **`status-badge` pattern**:
|
||||
- 2px solid border at `0.6` alpha
|
||||
- Diagonal gradient fill at `0.20 / 0.15` alpha
|
||||
- **Lighter text** for legibility — `#FCA5A5` (critical), `#FCD34D` (high), `#7DD3FC` (medium), `#6EE7B7` (low) — not the raw severity colour
|
||||
- Text-shadow `0 0 8px` brand-color at `0.4` alpha
|
||||
- 8px filled circle dot with a pulsing `box-shadow: 0 0 12px / 0 0 6px` glow on a 2s loop
|
||||
- `0 4px 8px rgba(0,0,0,0.4)` outer shadow
|
||||
- **Always JetBrains Mono, uppercase, 0.5px letter-spacing**
|
||||
|
||||
Secondary references can use simpler tinted pills (`rgba(brand,0.12)` background + brand text, no border, no glow). Single coloured dots `●` next to numeric scores are also valid. The colour-to-severity mapping is fixed across every component.
|
||||
|
||||
### Headings — the brand glow
|
||||
Page titles and section headers are **JetBrains Mono, uppercase, sky-blue `#38BDF8`**, with `text-shadow: 0 0 16px rgba(14,165,233,0.30), 0 0 32px rgba(14,165,233,0.15)`. This is the most identifiable single signal in the product — every page header reads as a glowing terminal title. Outfit is reserved for body, helper, and table cell text. The Knowledge Base markdown viewer continues this language: `h1` sky-blue, `h2` emerald, `h3` amber — a deliberate severity-coloured hierarchy.
|
||||
|
||||
---
|
||||
|
||||
## ICONOGRAPHY
|
||||
|
||||
The product uses **lucide-react** as its sole icon system. Lucide is a 1.5px-stroke, geometric, open-source icon set — clean, restrained, and perfectly aligned with the dark tactical aesthetic.
|
||||
|
||||
### Rules
|
||||
- **All icons are line / stroke style** — never filled glyphs (with one exception: the calendar's red due-date dot is a filled circle, but it's a status indicator, not an icon).
|
||||
- **Stroke width:** 1.5–2px (lucide default). 1.5px on small icons (≤16px), 2px on larger icons.
|
||||
- **Sizes:** 14px (inline with text), 16px (default UI), 20px (nav items, prominent buttons), 24px (page-header icons).
|
||||
- **Colour:** inherits `currentColor` — text-foreground for default, `#38BDF8` for active / accent, severity colours when used as a status indicator.
|
||||
- **No emoji anywhere.** Status, severity, and category use icons + colour; never `🔴` or `⚠️`.
|
||||
- **No unicode-as-icon shortcuts** beyond `●` (status dot), `↻` (revert / cycle), `↱` (redirect), `⊙` (filter handle), `→` (inline link), `+N` (count badge). These are part of the typography, not stand-ins for missing icons.
|
||||
|
||||
### Brand mark
|
||||
The product has no published logo file in the repo (the audit references `AtlasIcon` as a custom SVG brand icon — Atlas appears to be the action-plan integration, not the dashboard's own brand). For this design system the brand mark is a **typographic stack**: `STEAM` in Outfit 700 with a sky-blue underline accent and a small shield glyph (lucide `Shield`) to the left. See `assets/logo.svg` and `assets/atlas-shield.svg`.
|
||||
|
||||
### Substitutions flagged
|
||||
- **Atlas action-plan brand icon** is recreated as a generic shield (lucide `Shield`) tinted sky-blue. **If you have the real `AtlasIcon` SVG, please attach it** — the in-product version is custom and not available from the repo URL.
|
||||
- Fonts (Outfit, JetBrains Mono) load from Google Fonts CDN. **If you need offline font files, attach the woff2s** and we'll bundle them into `fonts/`.
|
||||
|
||||
### Icons used per page (from README)
|
||||
- **Home:** Calendar (CalendarWidget), Search, Filter, Plus, Upload, Edit, Trash, X (close)
|
||||
- **Reporting:** RefreshCw (Sync), Eye / EyeOff (row visibility), Check, Filter (⊙ in column header), Columns, Download (Export), MoreHorizontal
|
||||
- **Compliance:** Upload, AlertTriangle (drift breaking), AlertCircle (drift silent-miss), Info, ChevronRight, FileText
|
||||
- **Knowledge Base:** FileText, FilePlus, Folder, Download, Eye
|
||||
- **Admin:** Users, ScrollText (audit log), Activity (system info), Shield (admin badge)
|
||||
- **Universal:** ChevronDown, ChevronUp, Check, X, Loader, ExternalLink
|
||||
|
||||
When picking an icon, prefer the lucide-react name from this list before introducing a new one.
|
||||
|
||||
---
|
||||
|
||||
## UI Kits
|
||||
|
||||
| Kit | Path | What it covers |
|
||||
|---|---|---|
|
||||
| `cve-dashboard` | `ui_kits/cve-dashboard/` | App shell (top bar, nav drawer, user menu), Knowledge Base page + viewer, primitives (Button, Badge, Pill, Input, Select, Modal shell, SlideOutPanel, DataTable, GroupBadge, SeverityBadge, EmptyState, LoadingState) |
|
||||
|
||||
The Knowledge Base page is the focused recreation. Other surfaces (Reporting, Compliance, Admin) are intentionally not built out — the primitives + shell are sufficient to compose them.
|
||||
|
||||
---
|
||||
|
||||
## How to use this system
|
||||
|
||||
1. **Tokens first.** Import `colors_and_type.css` into the root of any HTML file. All colour, type, radius, shadow, and spacing decisions should pull from these CSS custom properties.
|
||||
2. **Pick a primitive before inventing.** Severity badges, group badges, status pills, table row, modal shell, slide-out panel — they all live in `ui_kits/cve-dashboard/`.
|
||||
3. **Match the density.** When in doubt, tighter is more on-brand than airier.
|
||||
4. **Lucide for icons.** Use the lucide-react CDN or copy individual SVGs from the lucide site. Do not draw your own.
|
||||
5. **No emoji, no gradients, no illustration, no marketing copy.** The product is a console.
|
||||
Reference in New Issue
Block a user