2026-05-25 19:34:22 +02:00
## Overview
2026-06-09 18:37:44 +02:00
Mimic is a **BAS (Breach and Attack Simulation) purple-team console ** — not a product catalog, not a marketing page. The aesthetic is **Bloomberg Terminal / SOC dashboard ** : dense, angular, semantic-color-driven, zero ornament. Every surface decision reinforces operational trust: data is primary, chrome is invisible.
2026-05-25 19:34:22 +02:00
2026-06-11 11:01:00 +02:00
The system sits on a **pale-tinted canvas ** (light: `#f3f5f8` ) / **dark slab ** (dark) with one chromatic action color — **Electric Blue ** (`{colors.primary}` — `#024ad8` ) — and semantic status signals (`success` , `warn` , `bloom-deep` ). Inter handles body/headers/labels. JetBrains Mono carries data: IDs, ISO dates, commands, execution output, MITRE technique codes, metrics — anything that must be read at a glance without typographic distraction.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**No rounded corners on containers.** No shadows on interactive surfaces. No transitions. Hover is instantaneous. Focus rings are sharp. This is a tool, not a storefront.
2026-05-25 19:34:22 +02:00
**Key Characteristics:**
2026-06-09 18:37:44 +02:00
- Angular surfaces everywhere (`border-radius: 0` ) — exception: status pills (`rounded-pill` ) and avatars
- Zero transitions / zero animations — state changes are immediate
- Semantic color signals: primary blue = action, success green = confirmed, warn amber = pending/caution, bloom-deep = destructive/error
- Monospace data discipline: `font-mono` ONLY for IDs, dates, codes, output, metrics — never for headers, labels, prose
- Dense spacing: section gap 48px (not 80px), card padding 12– 16px on dense surfaces
- Light + dark modes both supported; dark mode is the primary operational mode for SOC analysts
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
## Colors
2026-05-25 19:34:22 +02:00
### Brand & Accent
2026-06-09 18:37:44 +02:00
- **Electric Blue** (`{colors.primary}` — `#024ad8` ): primary CTA fill, active nav indicator, focus ring. Never used as a section background.
- **Bright Blue** (`{colors.primary-bright}` — `#296ef9` ): CTA on dark slab surfaces where `#024ad8` muddles.
- **Deep Navy** (`{colors.primary-deep}` — `#0e3191` ): pressed state for primary CTA.
- **Soft Blue** (`{colors.primary-soft}` — `#c9e0fc` ): selection highlight, chip background on light surfaces.
2026-05-25 19:34:22 +02:00
### Surface
2026-06-11 11:01:00 +02:00
- **Canvas** (`{colors.canvas}` — `#f3f5f8` light / `#111827` dark): universal page background. In light mode, canvas is tinted while paper stays pure white so cards lift without shadow or radius, preserving brutalism.
2026-06-09 18:37:44 +02:00
- **Paper** (`{colors.paper}` — `#ffffff` light / `#1f2937` dark): card and panel surfaces.
- **Cloud** (`{colors.cloud}` — `#f7f7f7` light / `#1f2937` dark): alternating section band, table row zebra.
- **Fog** (`{colors.fog}` — `#e8e8e8` light / `#374151` dark): secondary section band, input background on dense panels.
- **Steel** (`{colors.steel}` — `#c2c2c2` light / `#4b5563` dark): hairline borders, disabled states.
- **Hairline** (`{colors.hairline}` ): 1px divider between cells, panels, table rows.
- **Slab** (`{colors.slab}` — `#111827` ): fixed-dark surface — utility strip, footer, dark bands. Does NOT invert in dark mode.
2026-05-25 19:34:22 +02:00
### Text
2026-06-09 18:37:44 +02:00
- **Ink** (`{colors.ink}` — `#1a1a1a` light / `#f9fafb` dark): universal body text color.
- **Ink Deep** (`{colors.ink-deep}` — `#000000` light / `#ffffff` dark): maximum contrast for headings.
- **Ink Soft** (`{colors.ink-soft}` — `#292929` light / `#e5e7eb` dark): muted body, secondary labels.
- **On Ink** (`{colors.ink-on}` — `#ffffff` light / `#111827` dark): text on slab surfaces.
- **Charcoal** (`{colors.charcoal}` — `#3d3d3d` light / `#d1d5db` dark): secondary descriptions, captions.
- **Graphite** (`{colors.graphite}` — `#636363` light / `#9ca3af` dark): timestamps, metadata, footnotes.
### Semantic (Status Signals)
- **Success** (`{colors.success}` — `#16a34a` light / `#22c55e` dark): confirmed detections, done status, positive metrics. Background softened to `{colors.success-soft}` (`#dcfce7` light / `#14532d` dark) for badge fills.
- **Warn** (`{colors.warn}` — `#d97706` light / `#f59e0b` dark): pending review, caution states, partial detection. Background softened to `{colors.warn-soft}` (`#fef3c7` light / `#78350f` dark) for badge fills.
- **Bloom Deep** (`{colors.bloom-deep}` — `#b3262b` ): error, destructive action, failed detection. Bloom family covers red-spectrum signals.
- **Bloom Wine** (`{colors.bloom-wine}` — `#5a1313` ): darkened destructive emphasis.
- **Bloom Coral** (`{colors.bloom-coral}` — `#ff5050` ): alert highlight on dark surfaces.
---
2026-05-25 19:34:22 +02:00
## Typography
2026-06-09 18:37:44 +02:00
### Font Families
- **Inter Variable** (`{fontFamily.sans}` ): body text, labels, headers, navigation, form fields. The universal surface font.
- **JetBrains Mono Variable** (`{fontFamily.mono}` ): data cells ONLY — engagement IDs, simulation IDs, ISO 8601 dates, execution commands, terminal output, MITRE technique codes (T1059.001), numeric metrics, usernames-as-identifiers. Never used for prose, headings, or labels.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
Both fonts are bundled locally via `@fontsource-variable/inter` and `@fontsource-variable/jetbrains-mono` . Zero CDN loading at runtime.
2026-05-25 19:34:22 +02:00
### Hierarchy
2026-06-09 18:37:44 +02:00
| Token | Size | Weight | Line Height | Use |
|---|---|---|---|---|
| `{typography.display-xxl}` | 40px | 500 | 1.1 | Page-level hero (rare — dashboard title) |
| `{typography.display-xl}` | 32px | 500 | 1.1 | Section title (engagement name, modal header) |
| `{typography.display-lg}` | 28px | 500 | 1.1 | Sub-section header, panel title |
| `{typography.display-md}` | 24px | 500 | 1.1 | Card title, table header group |
| `{typography.display-sm}` | 20px | 500 | 1.1 | Item title, form section header |
| `{typography.display-xs}` | 16px | 600 | 1.1 | Compact section header, sidebar label |
| `{typography.body-lg}` | 18px | 400 | 1.4 | Lead paragraph |
| `{typography.body-md}` | 16px | 400 | 1.4 | Default body, form labels |
| `{typography.body-emphasis}` | 16px | 500 | 1.4 | Bolded inline copy, table column headers |
| `{typography.caption-md}` | 14px | 400 | 1.5 | Secondary metadata, captions, table cells (non-data) |
| `{typography.caption-bold}` | 14px | 700 | 1.3 | Status labels, tag text |
| `{typography.caption-sm}` | 12px | 400 | 1.33 | Footnotes, legal fine-print |
| `{typography.button-md}` | 14px | 600 | 1.4 | Button labels (uppercase) |
| `{typography.button-sm}` | 12.6px | 700 | 1.0 | Compact button in tight cells |
### Monospace Discipline
JetBrains Mono carries data that must be scanned without typographic noise. Apply `font-mono` (Tailwind) or `font-family: var(--font-mono)` to:
- Engagement IDs, simulation IDs (any UUID or integer identifier)
- ISO 8601 dates and timestamps (`2024-06-09T14:32:00` )
- MITRE technique codes (`T1059.001` , `TA0002` )
- Execution commands and command fields
- Terminal / execution output
- Numeric metrics (counts, durations)
- Usernames displayed as record identifiers (not greeting text)
Never apply `font-mono` to: page titles, section headers, body prose, navigation, form labels, button text.
---
2026-05-25 19:34:22 +02:00
## Layout
### Spacing System
2026-06-09 18:37:44 +02:00
- **Base unit**: 8px. Half-step 4px.
- **Tokens**: `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 20px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.section}` 48px
- **Section padding**: 48px vertical between major bands (desktop); ~24px on mobile.
- **Card padding**: 16px on dense panels; 24px on standard cards.
- **Gutter**: 24px between grid columns on desktop; 16px on tablet/mobile.
2026-05-25 19:34:22 +02:00
### Grid & Container
2026-06-09 18:37:44 +02:00
- **Max-width**: 1366px content container, full-bleed on canvas.
- **List pages**: full-width table with 1px hairline borders, no card wrap.
- **Detail pages**: 2-column split (60/40) on desktop, stacked on mobile.
- **Form pages**: single-column centered at 640px max-width.
2026-05-25 19:34:22 +02:00
### Whitespace Philosophy
2026-06-09 18:37:44 +02:00
Dense but not cramped. Table rows at 44px height (WCAG touch target). Card padding minimum 12px. No whitespace used as decoration — every gap serves alignment or grouping. Editorial breathing room (80px sections, hero-scale photography) does not apply here.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
## Shapes
2026-06-09 18:37:44 +02:00
### Border Radius
2026-05-25 19:34:22 +02:00
| Token | Value | Use |
|---|---|---|
2026-06-09 18:37:44 +02:00
| `{rounded.none}` | 0px | **Default for everything ** : buttons, cards, modals, inputs, dropdowns, panels, tags, tables |
| `{rounded.pill}` | 9999px | **Status pills only ** (`StatusBadge` , `SimulationStatusBadge` ) and circular avatars |
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
No intermediate radius values (`xs` , `sm` , `md` , `lg` , `xl` ) are used on visible surfaces. The brutalist rule: if it's not a status pill or avatar, `border-radius: 0` .
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
## Elevation
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
No shadows on interactive surfaces. Elevation is communicated by **border contrast ** (1px hairline on paper over canvas) not box-shadow.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
| Level | Treatment | Use |
|---|---|---|
| 0 — Flat | No border, no shadow | Page background, full-bleed bands |
| 1 — Hairline | `1px solid {colors.hairline}` | Cards, panels, table cells, input borders |
| 2 — Modal overlay | `rgba(0,0,0,0.6)` backdrop | Modal dialogs — backdrop only, frame stays hairline |
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
Shadows (`box-shadow` ) are not used anywhere.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
## Components
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
> Every component spec below: border-radius **0** unless noted. No `transition-*` on any interactive surface. Hover is instantaneous.
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Buttons
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.btn-primary` ** — Electric Blue CTA
- Background `{colors.primary}` , text white, uppercase, 14px/600, `h-11` , padding `12px 24px` , `rounded-none`
- Hover: background `{colors.primary-deep}` — no transition
- Disabled: background `{colors.steel}` , cursor not-allowed
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.btn-ink` ** — Fixed-dark filled CTA
- Background `{colors.slab}` , text `{colors.slab-text}` , uppercase, same metrics as btn-primary
- Used on dark band surfaces where blue would clash
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.btn-outline` ** — Outlined blue CTA
- Background `{colors.canvas}` , text `{colors.primary}` , 1px `{colors.primary}` border, `rounded-none`
- Hover: background `{colors.primary-soft}`
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.btn-outline-ink` ** — Outlined neutral CTA
- Background `{colors.canvas}` , text `{colors.ink}` , 1px `{colors.ink}` border, `rounded-none`
- Hover: background `{colors.cloud}`
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.btn-text-link` ** — Inline text link
- Text `{colors.primary}` , no background, no border
- Hover: underline, no color change
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Inputs & Forms
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.text-input` ** — Standard text field
- Background `{colors.canvas}` , text `{colors.ink}` , 1px `{colors.steel}` border, `rounded-none` , `h-11`
- Focus: border becomes 1px `{colors.primary}` , no halo, no transition
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`textarea.text-input` ** — Multiline variant
- Same as text-input, `min-h-[88px]` , height auto
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`select.text-input` ** — Dropdown select
- Same surface as text-input, caret via OS or custom SVG
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Cards & Panels
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.card-product` ** — Standard content card
- Background `{colors.paper}` , 1px `{colors.hairline}` border, `rounded-none` , padding `{spacing.md}` (16px)
- No shadow. Dense surfaces use padding `{spacing.sm}` (12px).
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.modal-backdrop` ** — Modal overlay backdrop
- `background-color: rgba(0,0,0,0.6)` — fixed, never themed
- Modal frame: `{colors.paper}` background, 1px `{colors.hairline}` border, `rounded-none`
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Badges & Tags
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.badge-pill-*` ** — Status pills (StatusBadge, SimulationStatusBadge)
- `rounded-pill` (9999px) — THE ONLY rounded surfaces on status badges
- Semantic fill: planned→warn-soft/warn, active→primary-soft/primary, closed→cloud/graphite
- done→success-soft/success, review→warn-soft/warn, pending→cloud/graphite, in-progress→primary-soft/primary
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**MITRE technique tags** — NOT pills
- Angular (`rounded-none` ), 1px `{colors.hairline}` border, `{colors.cloud}` background, caption-md size
- They are labels, not status signals — no pill shape
2026-05-25 19:34:22 +02:00
### Navigation
2026-06-09 18:37:44 +02:00
**`.utility-strip` ** — Top utility bar
- Background `{colors.slab}` , text `{colors.slab-text}` , height 36px, `font-mono` for user role/username
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.nav-bar-top` ** — Main navigation
- Background `{colors.slab}` (fixed dark — does not invert), height 56px
- Active link: 2px `{colors.primary}` bottom border
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
**`.nav-link` ** — Navigation anchor
- Text `{colors.slab-text}` , caption-md, `rounded-none`
- Active state: 2px primary bottom border
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Data Tables
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
- `table-layout: fixed` , `word-break: break-word`
- Header row: background `{colors.cloud}` , `body-emphasis` text, 1px `{colors.hairline}` bottom border
- Data cells: 44px min-height, 1px `{colors.hairline}` bottom border
- ID / date / technique columns: `font-mono`
- Zebra striping optional — use `{colors.cloud}` for odd rows if table is wide
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
### Toast Notifications
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
- Angular (`rounded-none` ), 4px left border strip in semantic color (success/warn/bloom-deep/primary)
- Background `{colors.paper}` , 1px `{colors.hairline}` border
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
## Do's and Don'ts
### Do
2026-06-09 18:37:44 +02:00
- `rounded-none` on every container, button, input, modal, dropdown, panel, tag
- `font-mono` on IDs, ISO dates, MITRE codes, commands, output, metrics
- Semantic color for status: success green, warn amber, bloom-deep for errors
- 1px hairline borders for panel separation — never shadow
- Instant hover (no `transition-*` )
- Sharp focus ring: `outline: 2px solid {colors.primary}; outline-offset: 0`
- Keep Inter for all headers, labels, prose, navigation, button text
2026-05-25 19:34:22 +02:00
### Don't
2026-06-09 18:37:44 +02:00
- Don't round containers — not even `2px` . If it's not a status pill or avatar, `rounded-none`
- Don't use `font-mono` for headers, labels, prose, or button text
- Don't add `transition-*` on any interactive element
- Don't use shadows — hairline borders only
- Don't use `{colors.primary}` as a background for sections
- Don't drop opacity on ink text — use `{colors.charcoal}` or `{colors.graphite}` for hierarchy
- Don't use animated spinners with rounded tracks — a simple spinning line or text indicator fits the terminal aesthetic better
- Don't apply `rounded-pill` to anything that is not a STATUS BADGE or AVATAR
2026-05-25 19:34:22 +02:00
2026-06-09 18:37:44 +02:00
---
2026-05-25 19:34:22 +02:00
## Iteration Guide
2026-06-09 18:37:44 +02:00
1. One component at a time — no section refactors in one pass
2. Reference tokens by name (`{colors.primary}` , `font-mono` , `rounded-none` ) — not hex/px in prose
3. When adding a new data field: ask "is this a datum (ID, date, code, metric)?" → `font-mono` . If no → Inter
4. New status signals: map to existing semantic tokens (success/warn/bloom-deep/primary). No ad-hoc colors
5. For new badge-like elements: pill ONLY if it's a status indicator with semantic color. Otherwise angular tag