Files
Metamorph/tasks/design.md
Knacky f1fdf27012 feat(m0): bootstrap repo, design system, compose stack
- Repo scaffolding: .gitignore, .env.example, Makefile, docker-compose.yml,
  README.md, CHANGELOG.md, pre-commit config.
- Three-service stack: api (Flask 3), db (postgres:16-alpine), front (nginx
  serving the Vite bundle). Named volumes metamorph_db + metamorph_evidence.
- Backend skeleton: Flask app factory, JSON structured logging on stdout,
  GET /api/v1/health, multi-stage Dockerfile, pyproject.toml driven by uv,
  Pydantic Settings with secret guard rails (refuses to boot in non-dev with
  placeholders), APP_ENV gating.
- Frontend skeleton: Vite + React 18 + TypeScript strict + TailwindCSS, RTOps
  design tokens from tasks/design.md, self-hosted JetBrains Mono / IBM Plex
  Sans via @fontsource, base UI primitives (Card/Tag/SectionHeader/FlowNode/
  Button), home page wired to /api/v1/health.
- Engine-agnostic Makefile: auto-detects docker or podman, picks the matching
  compose driver. Targets: up/down/build/rebuild/dev/lint/fmt/test/migrate/
  seed-mitre/print-install-token/e2e/inspect-health.
- Playwright suite: e2e/tests/m0-smoke.spec.ts (8 tests) + HTML + JUnit
  reports + traces on retry.
- Docs: tasks/spec.md (finalized after Q&A), tasks/design.md, tasks/todo.md
  (14 milestones), tasks/testing-m0.md, tasks/lessons.md.

DoD: make up + make health + make e2e all pass on podman 5.x (Fedora) and
docker. TLS terminated by external reverse proxy (spec §6 NF-network).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 06:16:00 +02:00

14 KiB
Raw Permalink Blame History

Design System — Red Team Operations Map

Reusable design spec extracted from kypvas.github.io/red-team-map/. Dark "operator briefing / terminal" aesthetic: information-dense, color-coded taxonomy, monospace-first, zero ornament.


1. Philosophy

  • Dark, flat, terminal-inspired. No gradients, no drop shadows, no glows. Depth comes from 1px borders on slightly lighter card backgrounds.
  • Information over decoration. Every visual element serves data density — cards, tags, colored borders, inline code.
  • Color as taxonomy. 10 accent hues are not decoration — each one means a category (red = evasion/payload, cyan = lateral, purple = C2, etc.). Reuse hues consistently across projects so color carries meaning.
  • Monospace as identity. JetBrains Mono for everything structural (titles, labels, code, tags). IBM Plex Sans only for prose body.
  • Comment-style section markers. Headings begin with // — carries the "source code / operator notes" metaphor.

2. Color Tokens

All colors are declared as CSS custom properties on :root. Copy-paste verbatim:

:root {
  /* Surfaces */
  --bg:          #0a0e1a;  /* page background — deep navy-black */
  --bg-card:     #111827;  /* card / panel background */
  --border:      #1e2d3d;  /* default 1px border, separators */

  /* Text */
  --text:        #94a3b8;  /* default body copy (slate) */
  --text-bright: #f8fafc;  /* titles, emphasis */
  --text-dim:    #64748b;  /* metadata, subtitles, arrow labels */
  /* #475569 used inline for code comments */

  /* Accent palette — each one maps to a category */
  --red:    #ef4444;  /* evasion, payload, privesc, danger */
  --orange: #f59e0b;  /* access, credentials, AD, MOTW */
  --yellow: #eab308;  /* exfil */
  --green:  #10b981;  /* phishing, social */
  --cyan:   #06b6d4;  /* lateral movement, default code highlight */
  --blue:   #3b82f6;  /* infrastructure, cloud */
  --purple: #8b5cf6;  /* C2, macOS, tooling */
  --pink:   #ec4899;  /* injection */
  --rose:   #f43f5e;  /* OPSEC, vishing */
  --teal:   #14b8a6;  /* persistence, linux */
}

Usage pattern — tinted fills

Never use accent color as a solid background. Always as rgba(accent, 0.100.15) behind solid-colored text:

.tag.c2   { background: rgba(139, 92, 246, 0.15); color: var(--purple); }
.tag.cred { background: rgba(245, 158, 11, 0.15); color: var(--orange); }
code      { background: rgba(6, 182, 212, 0.08); color: var(--cyan); }
code.vuln { background: rgba(239, 68, 68, 0.10); color: var(--red); }
code.tool { background: rgba(139, 92, 246, 0.10); color: var(--purple); }

3. Typography

Font stack

<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
  • JetBrains Mono — headings, labels, code, tags, navigation, anything structural.
  • IBM Plex Sans — prose body only (<p>, card descriptions).
  • Weights used: Mono 300 / 400 / 500 / 600 / 700, Plex Sans 300 / 400 / 500 / 600.

Scale

Role Family Size Weight Extras
Page title (h1) JetBrains Mono 28px 700 letter-spacing: -0.5px
Subtitle JetBrains Mono 14px 300 color --text-dim
Section (h2) JetBrains Mono 18px 600 border-bottom: 1px var(--border), padding-bottom: 12px
Card title (h3) JetBrains Mono 14px 600 color --text-bright
Card sub-label JetBrains Mono 10px 400 letter-spacing: 0.5px, --text-dim
Section desc JetBrains Mono 12px 400 --text-dim
Body copy IBM Plex Sans 12px 400 line-height: 1.7
Flow node JetBrains Mono 10px 400
Arrow label JetBrains Mono 8px 400 --text-dim
Tag / pill JetBrains Mono 9px 600 text-transform: uppercase; letter-spacing: 1px
Inline code JetBrains Mono 10px 400
<pre> block JetBrains Mono 11px 400 line-height: 1.7
Footer JetBrains Mono 11px 400 --text-dim

Global body

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'IBM Plex Sans', sans-serif;
  padding: 40px 60px;
  line-height: 1.6;
}

4. Layout & Spacing

  • Container: max-width: 1400px; margin: 0 auto;
  • Page padding: 40px 60px (desktop-first, no mobile breakpoints in the source)
  • Grid for card collections:
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
    gap: 16px;
    
  • Section rhythm: margin-top: 60px; margin-bottom: 30px on section headers.
  • Separators: thin hairlines only — border-top: 1px solid var(--border); margin: 40px 0.
  • Line-height: 1.6 globally, 1.7 inside cards and <pre> blocks for dense technical content.

5. Components

5.1 Header / Hero

<header>
  <h1>Red Team <span>Operations</span> <span class="acc2">Architecture</span> Map v1.1</h1>
  <div class="subtitle">Comprehensive Operator Reference — From Infrastructure to Impact</div>
</header>
header        { text-align: center; margin-bottom: 50px; }
header h1     { font: 700 28px 'JetBrains Mono'; color: var(--text-bright); letter-spacing: -0.5px; margin-bottom: 8px; }
header h1 span         { color: var(--red); }
header h1 .acc2        { color: var(--purple); }
header .subtitle       { font: 300 14px 'JetBrains Mono'; color: var(--text-dim); }

Pattern: white title with two coloured accent words (red + purple). Reuse <span> to highlight 12 keywords only.

5.2 Section heading

<div class="section-header">
  <h2><span>//</span> Operation <span class="red">Flow Chains</span></h2>
  <p class="section-desc">End-to-end attack chains ...</p>
</div>
.section-header          { margin-top: 60px; margin-bottom: 30px; }
.section-header h2       { font: 600 18px 'JetBrains Mono'; color: var(--text-bright);
                           padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.section-header h2 span  { color: var(--cyan); }            /* the "//" marker */
.section-header h2 .red  { color: var(--red); }              /* + .green / .orange / .purple / .pink / .teal / .yellow / .blue */
.section-desc            { font: 12px 'JetBrains Mono'; color: var(--text-dim); margin-top: 8px; }

Signature move: every h2 starts with a cyan // followed by a plain word and one colored word — source-code comment vibe.

5.3 Detail card

.detail-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
}
.detail-card h3        { font: 600 14px 'JetBrains Mono'; color: var(--text-bright); margin-bottom: 4px; }
.detail-card .card-sub { font: 10px 'JetBrains Mono'; color: var(--text-dim); margin-bottom: 12px; letter-spacing: 0.5px; }
.detail-card .card-body { font-size: 12px; line-height: 1.7; }

/* accent-border variants */
.border-red   { border-color: var(--red)    !important; }
.border-cyan  { border-color: var(--cyan)   !important; }
/* ... one class per accent */

Cards share identical chrome; they are distinguished solely by border color. That single accent ties card → category → tag → flow-node without repeating the hue anywhere else.

5.4 Tag / pill

.tag {
  font: 600 9px 'JetBrains Mono';
  text-transform: uppercase;
  letter-spacing: 1px;
  padding: 3px 8px;
  border-radius: 4px;
  display: inline-block;
  margin-bottom: 8px;
  margin-right: 4px;
}
.tag.c2       { background: rgba(139, 92, 246, 0.15); color: var(--purple); }
.tag.evasion  { background: rgba(239, 68, 68,  0.15); color: var(--red); }
.tag.lateral  { background: rgba(6,   182, 212, 0.15); color: var(--cyan); }
/* ... one class per category */

5.5 Flow node + arrow

Nodes chain horizontally in a flex row with thin SVG arrows between them.

.flow-block { margin-bottom: 18px; }
.flow-title { font: 600 12px 'JetBrains Mono'; margin-bottom: 10px; }
.flow-title.red    { color: var(--red); }     /* one per accent */

.flow-row   { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; padding: 10px 0; }

.flow-node {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  font: 10px 'JetBrains Mono';
  color: var(--text);
  white-space: nowrap;
  flex-shrink: 0;
}
.flow-node.hl-red    { border-color: var(--red);    color: var(--red); }
.flow-node.hl-cyan   { border-color: var(--cyan);   color: var(--cyan); }
/* ... one per accent */

.flow-arrow              { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
.flow-arrow svg          { width: 36px; height: 20px; }
.flow-arrow .arrow-label { font: 8px 'JetBrains Mono'; color: var(--text-dim); margin-top: -2px; }

Arrow SVG template (inline, stroke colour = destination-node accent):

<svg viewBox="0 0 36 20">
  <line x1="0" y1="10" x2="31" y2="10"
        stroke="#10b981" stroke-width="1.5"
        marker-end="url(#arrowG)"/>
</svg>

5.6 Data-flow / code card

.data-flow-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px;
  margin-bottom: 20px;
}
.data-flow-card h4   { font: 600 13px 'JetBrains Mono'; color: var(--text-bright); margin-bottom: 12px; }
.data-flow-card pre  { font: 11px 'JetBrains Mono'; line-height: 1.7; color: var(--text-dim); overflow-x: auto; }
.data-flow-card pre .key     { color: var(--cyan);   font-weight: 600; }
.data-flow-card pre .val     { color: var(--text-bright); }
.data-flow-card pre .type    { color: var(--blue); }
.data-flow-card pre .comment { color: #475569; font-style: italic; }
.data-flow-card pre .danger  { color: var(--red);    font-weight: 600; }

Pseudo-syntax-highlighting via <span class="key|val|type|comment|danger"> inside <pre> blocks — mimics an IDE theme without a real parser.

5.7 Inline code

code               { font: 10px 'JetBrains Mono'; padding: 2px 6px; border-radius: 3px;
                     background: rgba(6, 182, 212, 0.08); color: var(--cyan); }
code.vuln          { background: rgba(239, 68, 68,  0.10); color: var(--red); }
code.tool          { background: rgba(139, 92, 246, 0.10); color: var(--purple); }

5.8 List inside card

.card-list          { list-style: none; padding: 0; }
.card-list li       { padding: 3px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.03); }

Near-invisible divider (rgba(255,255,255,0.03)) — rhythm without visual noise.

footer {
  text-align: center;
  margin-top: 60px;
  padding: 30px 0;
  border-top: 1px solid var(--border);
  font: 11px 'JetBrains Mono';
  color: var(--text-dim);
}

6. Borders, Radii, Elevation

Element Radius Border
Detail card 10px 1px solid var(--border) or accent
Data-flow card 10px 1px solid var(--border)
Flow node 6px 1px solid var(--border) or accent
Tag 4px none
Inline code 3px none
  • No box-shadow anywhere.
  • No gradients. Surfaces are flat hex fills.
  • Depth cue = border on a #111827 panel over a #0a0e1a background. That's the whole elevation system.

7. Motion

The stylesheet defines no transitions, no hovers, no animations. Static document. If you add motion in derivative work, keep it restrained: ~120 ms fades on border-color at most. Don't introduce scale, shadow, or glow effects — they'd break the briefing aesthetic.


8. Iconography

No icon font, no Lucide/Heroicons. All pictograms are inline SVG arrows with stroke-width: 1.5 and <marker-end> arrowheads, one per accent color. Tags replace icons: [C2], [EVASION], [LATERAL] carry the same recognition load.

If icons are ever added, use a thin (1.5px) monochrome line set (e.g. Lucide strokeWidth={1.5}) and color them with accent vars.


9. Reusable Starter Template

Drop-in <head> + body baseline for a new project in this style:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Project Name</title>
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
  <style>
    :root {
      --bg: #0a0e1a; --bg-card: #111827; --border: #1e2d3d;
      --text: #94a3b8; --text-bright: #f8fafc; --text-dim: #64748b;
      --red:#ef4444; --orange:#f59e0b; --yellow:#eab308; --green:#10b981;
      --cyan:#06b6d4; --blue:#3b82f6; --purple:#8b5cf6; --pink:#ec4899;
      --rose:#f43f5e; --teal:#14b8a6;
    }
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: var(--bg); color: var(--text); font-family: 'IBM Plex Sans', sans-serif; padding: 40px 60px; line-height: 1.6; }
    .container { max-width: 1400px; margin: 0 auto; }
  </style>
</head>
<body>
  <div class="container">
    <header>
      <h1>Project <span style="color:var(--red)">Name</span> <span style="color:var(--purple)">Subtitle</span></h1>
      <div class="subtitle">One-line mission statement</div>
    </header>
    <!-- sections with <h2>// Section <span class="red">Name</span></h2> ... -->
  </div>
</body>
</html>

10. Checklist for "Does this match the style?"

  • Background #0a0e1a, cards #111827, borders #1e2d3d.
  • JetBrains Mono for structure, IBM Plex Sans for prose.
  • Every section <h2> starts with a cyan //.
  • Exactly one accent hue per category, reused across border + tag + code + flow node.
  • Accent backgrounds are tinted (rgba(accent, 0.100.15)), never solid.
  • Zero shadows, zero gradients, zero rounded > 10px.
  • Tags are 9px uppercase mono with 1px letter-spacing.
  • Container capped at 1400px, page padded 40px 60px.
  • No hover animations beyond border-color if any at all.