Tutorial 9: Diagram Styling, Themes & Custom Icons
Across Tutorials 1 through 8, you constructed the foundational architecture for NeoBank - linking strategic transformation goals, business capability maps, microservice topologies, mainframe hosting footprints, security controls, and autonomous AI agents.
As architecture models mature, communicating their insights to diverse audiences (C-level executives, cloud architects, security engineers, and portfolio steering committees) requires expressive visual formatting. A raw white-and-gray box diagram cannot instantly distinguish a high-priority cloud investment from an end-of-life legacy system scheduled for decommissioning.
In Scapius, visual presentation is strictly decoupled from architectural data. You never hardcode hex colors or SVG paths into your core domain entities. Instead, you author reusable Themes (.theme files) and Style Rules that dynamically format diagrams based on entity classifications, custom icons, and lifecycle attributes.
In this tutorial, you will learn:
- The separation-of-concerns philosophy and style precedence hierarchy.
- How to leverage the 1,760+ offline vector icon library (AWS, Azure, GCP, Kubernetes, technology runtimes, and local assets).
- How to dynamically color and format diagrams using the Gartner TIME classification (Tolerate, Invest, Migrate, Eliminate).
- How to write conditional style rules matching on tiers, criticality, security tags, and custom attributes.
- How to style relationship lines (curves, dash patterns, and protocol colors).
- How to package and apply a complete NeoBank Portfolio Theme with native Light and Dark mode support.
1. Architectural Decoupling & Style Cascade
In traditional modeling tools, changing the border color or icon of a microservice requires manually clicking through dozens of diagrams or cluttering the domain model with presentation properties.
Scapius follows the modern software engineering pattern of decoupled presentation:
┌──────────────────────────────────────┐ ┌───────────────────────────────────────┐
│ Domain Model (*.ea fragments) │ │ Theme & Style System (*.theme) │
│ - Entity types & IDs │ │ - Selectors (entity, type, ID, wild) │
│ - Lifecycles & TIME classifications │ ──> │ - Conditional Predicates (where ...) │
│ - Tiers, costs, & relationships │ │ - Shapes, fills, borders, & icons │
└──────────────────────────────────────┘ └───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Resolved Diagram Presentation │
│ (Dynamic SVG ForeignObject / Canvas) │
└─────────────────────────────────────────┘
Style Precedence Hierarchy
When rendering an entity or edge in a view, Scapius resolves visual styles through a 4-tier cascade:
| Precedence | Level | Declared In | Purpose |
|---|---|---|---|
| 1 (Highest) | View Overrides | views { landscape ... { style ... } } | View-specific highlighting (e.g. emphasizing a migration bottleneck in a single diagram). |
| 2 | Workspace Styles | workspace { styles { style ... } } | Repository-wide defaults and contextual rules applied across all views in the workspace. |
| 3 | Referenced Themes | styles { theme "path/to.theme" } | Packaged design systems (.theme files) shared across multiple workspaces or teams. |
| 4 (Lowest) | Built-in Defaults | Scapius Engine | Structural defaults (neutral slate borders, standard card geometry, high-contrast text). |
2. Multi-Namespace Icon Architecture
Scapius includes an offline vector repository containing over 1,760 official cloud and enterprise architecture icons. Icons are referenced through canonical namespace tokens:
| Prefix / Namespace | Source & Coverage | Examples |
|---|---|---|
aws:<id> | AWS Architecture Vectors (730+ icons) | aws:ec2, aws:api-gateway, aws:lambda, aws:s3, aws:rds, aws:dynamodb |
azure:<id> | Microsoft Azure Vectors (620+ icons) | azure:mobile, azure:virtual-machine, azure:cosmos-db, azure:app-service |
gcp:<id> | Google Cloud Platform Vectors (210+ icons) | gcp:compute-engine, gcp:cloud-storage, gcp:bigquery, gcp:cloud-run |
k8s:<id> | Kubernetes & CNCF Ecosystem (38+ icons) | k8s:pod, k8s:service, k8s:deployment, k8s:worker-node |
tech:<id> | Tech Stacks, Runtimes & Databases (150+ icons) | tech:react, tech:kafka, tech:postgresql, tech:docker, tech:redis, tech:spring-boot |
lucide:<id> or <id> | Lucide Enterprise Icons (Default, 1,590+ icons) | smartphone, server, database, shield-check, alert-octagon, trending-up |
material:<id> | Google Material Symbols | material:account_balance, material:security, material:terminal |
assets:<path> | Local Workspace Assets (<workspace>/assets/) | assets:systems/core-banking.svg, assets:branding/logo.png |
https://... | Direct HTTPS Vector URLs | https://cdn.example.com/icons/custom-service.svg |
Three Ways to Bind Icons
You can assign icons at varying levels of granularity:
styles {
# 1. By Entity Type (applies to all entities of this type)
style system {
icon "server"
}
# 2. By Specific Entity ID (pinpoint precision)
style app where id == "app_mobile_banking" {
icon "azure:mobile"
}
style infrastructure where id == "inf_ibm_z16" {
icon "assets:systems/mainframe.svg"
}
# 3. By Conditional Predicate (matching domain metadata)
style infrastructure where provider == "AWS" {
icon "aws:ec2"
}
}
You can browse all available vector tokens, copy DSL snippets, and preview icons in real time by navigating to /icon-explorer (or clicking the Icons button in the top navigation bar).
3. Dynamic Coloring with the TIME Framework
The Gartner TIME Framework is the global standard for Application Portfolio Management (APM). It categorizes software assets into four strategic quadrants based on Business Value and Technical Health:
▲ HIGH BUSINESS VALUE
│
Tolerate │ Invest
(Stable) │ (Cloud-Native / Strategic)
────────────┼─────────────────────────────► HIGH TECHNICAL
Eliminate│ Migrate FIT / HEALTH
(Retire) │ (Cloud Target / Technical Debt)
│ LOW BUSINESS VALUE
In Scapius, entities declare their TIME status canonically:
app app_mobile_banking "NeoBank Mobile App" {
time "Invest"
tier "Tier-1"
status "Active"
}
system system_core_banking "Core Banking Platform" {
time "Migrate"
tier "Tier-1"
status "Active"
}
The TIME Color Palette
By writing style rules that match against where time == "...", diagrams instantly communicate portfolio health:
styles {
# 1. Invest (Modernization & Growth) -> Emerald Green
style app where time == "Invest" {
fill "#dcfce7"
stroke "#16a34a"
stroke_width "2px"
color "#14532d"
icon "trending-up"
}
# 2. Tolerate (Stable Utility) -> Sky Blue
style app where time == "Tolerate" {
fill "#e0f2fe"
stroke "#0284c7"
stroke_width "1.5px"
color "#0369a1"
icon "shield-check"
}
# 3. Migrate (Cloud Migration Target / Refactor) -> Amber with Dashed Border
style * where time == "Migrate" {
fill "#fef3c7"
stroke "#d97706"
stroke_width "2px"
stroke_style "dashed"
color "#78350f"
icon "cloud-upload"
}
# 4. Eliminate (Sunset / Decommission) -> Rose Red with Dotted Border
style * where time == "Eliminate" {
fill "#fee2e2"
stroke "#dc2626"
stroke_width "2px"
stroke_style "dotted"
color "#7f1d1d"
icon "alert-octagon"
}
}
4. Advanced Attribute Selectors & Edge Styling
Scapius's style engine evaluates any field exposed on an entity or relationship, including custom attributes (attr.*), security tiers, and composite boolean conditions.
Attribute-Driven Selectors
styles {
# Match by Architecture Tier
style * where tier == "Tier-1" {
stroke_width "3px"
}
# Match by Security Classification
style data_object where security.confidentiality == "Critical" {
fill "#fef2f2"
stroke "#b91c1c"
icon "shield-alert"
}
# Match by Custom Domain Attributes (attr.<key>)
style app where attr.cloud_readiness == "Cloud-Native" {
css_class "cloud-badge shadow-sm"
}
# Compound Boolean Conditions (&&, ||, parenthesis)
style app where time == "Migrate" && (tier == "Tier-1" || criticality == "Mission-Critical") {
fill "#fef3c7"
stroke "#ea580c"
stroke_width "3px"
custom_css "filter: drop-shadow(0 0 6px rgba(234, 88, 12, 0.4));"
}
}
Relationship (Edge) Styling
Edges in Scapius represent data flows, service dependencies, and integrations. You can style relationships by their verb (flows_to, realizes, serves) or by tags and metadata:
styles {
# Encrypted Real-Time Synchronous Flows (Solid Green Smooth Curves)
style flows_to where tags contains "Sync" || attr.protocol == "mTLS" {
stroke "#16a34a"
stroke_width "2px"
stroke_style "solid"
curve_type "smooth_step"
}
# Asynchronous Event Streams / Queues (Dashed Purple Bezier Curves)
style flows_to where tags contains "Kafka" || tags contains "Async" {
stroke "#9333ea"
stroke_width "2px"
stroke_style "dashed"
curve_type "bezier"
}
# Legacy Batch Transfers (Dashed Amber Step Lines)
style flows_to where tags contains "Batch" {
stroke "#d97706"
stroke_width "2px"
stroke_style "dashed"
curve_type "step"
}
}
5. Hands-On: Authoring NeoBank's Portfolio Theme
Let's implement a complete theme for NeoBank inside scapius-examples/Neobank.
Step 1: Create the Standalone Theme File (themes/neobank-portfolio.theme)
Create a dedicated theme file with dual support for theme light and theme dark modes:
# ==============================================================================
# NeoBank Enterprise Portfolio Theme: TIME & Technology Design System
# ==============================================================================
# ==============================================================================
# NeoBank Enterprise Portfolio Theme: TIME & Technology Design System
# ==============================================================================
theme light "neobank-light" {
# ── Gartner TIME Classification (Light Mode) ──
style app where time == "Invest" {
fill "#dcfce7"
stroke "#16a34a"
stroke_width "2px"
color "#14532d"
}
style app where time == "Tolerate" {
fill "#e0f2fe"
stroke "#0284c7"
stroke_width "1.5px"
color "#0369a1"
}
style * where time == "Migrate" {
fill "#fef3c7"
stroke "#d97706"
stroke_width "2px"
stroke_style "dashed"
color "#78350f"
}
style * where time == "Eliminate" {
fill "#fee2e2"
stroke "#dc2626"
stroke_width "2px"
stroke_style "dotted"
color "#7f1d1d"
}
# ── Official Cloud & Tech Vector Icons ──
style app where id == "app_mobile_banking" {
icon "smartphone"
}
style app where id == "app_instant_pay" {
icon "aws:api-gateway"
}
style app where id == "app_auth_api" {
icon "shield-check"
}
style system where id == "system_core_banking" {
icon "assets:systems/core-banking.svg"
}
}
theme dark "neobank-dark" {
# ── Gartner TIME Classification (Dark Mode) ──
style app where time == "Invest" {
fill "#82c5a4"
stroke "#0e361c"
stroke_width "2px"
color "#20442e"
}
style app where time == "Tolerate" {
fill "#95b3d6"
stroke "#1a3642"
stroke_width "1.5px"
color "#142229"
}
style * where time == "Migrate" {
fill "#c5b095"
stroke "#312612"
stroke_width "2px"
stroke_style "dashed"
color "#504724"
}
style * where time == "Eliminate" {
fill "#cda1a6"
stroke "#2f1116"
stroke_width "2px"
stroke_style "dotted"
color "#461a1f"
}
# ── Icons (Inherited across both modes) ──
style app where id == "app_mobile_banking" {
icon "smartphone"
}
style app where id == "app_instant_pay" {
icon "aws:api-gateway"
}
style app where id == "app_auth_api" {
icon "shield-check"
}
style system where id == "system_core_banking" {
icon "assets:systems/core-banking.svg"
}
}
Step 2: Reference the Theme in the Root Workspace (main.ea)
Now update scapius-examples/Neobank/main.ea to load your new theme and project a dedicated portfolio view:
workspace neo_bank "Neo Bank Enterprise Architecture" {
styles {
theme "themes/neobank-portfolio.theme"
style "system" {
shape "rounded_rectangle"
css_class "card shadow-sm border-primary"
}
style "app" {
shape "pill"
css_class "card border-secondary text-primary"
}
style "actor" {
shape "actor"
css_class "actor-node text-center"
}
# Universal edge styling
style serves {
stroke "#64748b"
stroke_width "1.5px"
curve_type "bezier"
}
style flows_to {
stroke "#1e7633"
stroke_width "1px"
curve_type "smooth_step"
arrow "diamond"
label {
color "#8a57a5"
fill "#8a57a500"
stroke "#2b0f3a"
stroke_style "dashed"
stroke_width "0px"
}
}
}
views {
landscape portfolio_lifecycle_view "NeoBank Application Portfolio" {
description "APM lifecycle map showing digital channels, payment gateways, and core systems categorized by Gartner TIME."
tags ["Portfolio", "TIME", "Lifecycle", "Modernization"]
include app_mobile_banking
include app_auth_api
include app_instant_pay
include system_core_banking
include app_legacy_reports
auto_layout LeftToRight
# View-level override: Emphasize the core banking migration boundary
style system where id == "system_core_banking" {
stroke_width "3px"
}
}
}
}
6. Visual Projection: The Rendered Diagram
When compiled by the Scapius layout engine, the diagram resolves all four TIME quadrants, embeds the custom vector icons, and renders curved interaction edges:
NeoBank Application Portfolio rendered with custom cloud icons and Gartner TIME classification colors
Key Architectural Insights Visible in the View:
- Instant Modernization Visibility (Invest): The customer-facing mobile application (
app_mobile_banking) and the instant payment router (app_instant_pay) are highlighted in emerald green with mobile and AWS API Gateway icons, signaling active feature development and modern architecture. - Stable Utility Services (Tolerate): The customer authentication service (
app_auth_api) appears in sky blue with a shield icon, indicating stable operation with minimal ongoing engineering spend required. - Migration & Technical Debt (Migrate): The mainframe-hosted ledger (
system_core_banking) stands out in amber with a dashed border and server vector, indicating it is an active migration target moving to AWS Cloud. - Targeted Decommissioning (Eliminate): The legacy batch generator (
app_legacy_reports) is framed with a rose red dotted border and a decommission icon, signaling its upcoming sunset. - Seamless Mode Switching: Toggling between Light and Dark mode changes the palette tokens without disrupting icon vectors, layout coordinates, or text hierarchy.
7. Validate the Workspace
Validate that your theme and style rules pass the Scapius compiler:
dotnet run --project backend/NexusEA.Cli -- validate scapius-examples/Neobank
Output:
Validation Successful! Workspace 'Neo Bank Enterprise Architecture' is valid.
8. Summary & Next Steps
In this tutorial, you learned how to transform raw architecture models into expressive, executive-ready diagrams:
| Capability | Mechanism | Benefit |
|---|---|---|
| Separation of Concerns | Standalone .theme files | Zero pollution of domain architecture models with presentation code. |
| Multi-Namespace Icons | aws:, azure:, gcp:, tech:, lucide: | Instant visual recognition of cloud services and technical runtimes. |
| TIME Classification | where time == "Invest" | Standardized APM lifecycle status visualizable at a glance. |
| Edge Customization | curve_type, stroke_style | Distinguish sync APIs, event streams, and batch transfers visually. |
| Dual Mode Support | theme light / theme dark | Seamless legibility in both light and dark presentation modes. |
You have now mastered end-to-end modeling in Scapius: from workspace setup and multi-layer lineage to security threat modeling, autonomous AI agents, executive dashboards, and production theme styling!