# High-Level **Best for:** end-to-end data stack overviews — ingestion → storage → query → analytics → visualization — deployed on a container orchestrator (Kubernetes, ECS, Nomad). Combines a phase chevron banner, deployment boundary, orchestration bar, identity footer, and (optionally) a right-side vertical chevron strip for cross-cutting concerns (Orchestration, Security, Observability). This type is **parametric**. The diagram is fully determined by a small list of inputs (chevrons, sources, components, connections). The formulas below tell you exactly where every shape lands given those inputs — two generations from the same inputs must produce visually identical SVG. --- ## 1. Inputs — the parameter contract Before drawing, collect these from the user (or accept them as a YAML/JSON block). Everything in this reference is derived from these inputs. Don't invent geometry on the fly. ```yaml chevrons: # ordered left → right; reserved names auto-promote to vertical - { name: "Data sources", columns: 1 } - { name: "Ingestion", columns: 1 } - { name: "Storage", columns: 1 } - { name: "Transformation", columns: 1 } - { name: "Visualization", columns: 1 } - { name: "Orchestration", vertical: true } # reserved → pairs with the bar - { name: "Security", vertical: true, color: "#b85450" } # tinted to match the Identity bar below - { name: "Observability", vertical: true } # reserved → pairs with crosscut #2 sources: # external; rendered in the dashed zone on the left - { name: "PostgreSQL", type: "db", connects_to: ["NiFi"] } - { name: "SFTP drop", type: "ftp", connects_to: ["NiFi"] } - { name: "Web forms", type: "web", connects_to: ["NiFi"] } - { name: "Legacy", type: "legacy", connects_to: ["NiFi"] } components: # inside the cluster, plus bars and cross-cutting rows - { name: "NiFi", chevron: "Ingestion", kind: node, icon: nifi, role: "COLL" } - { name: "MinIO", chevron: "Storage", kind: node, icon: minio, role: "STORE", focal: true } - { name: "Trino", chevron: "Storage", kind: node, icon: trino, role: "VIRT" } - { name: "Notebooks", chevron: "Transformation", kind: node, icon: jupyter, role: "ANLZ" } - { name: "Superset", chevron: "Visualization", kind: node, icon: superset, role: "DASH" } - { name: "Airflow", chevron: "Orchestration", kind: bar, icon: airflow, subtitle: "Apache Airflow" } - { name: "Identity", chevron: "Security", kind: cross-cutting, icon: keycloak, subtitle: "Keycloak · LDAP · OIDC", color: "#b85450" } - { name: "Monitoring", chevron: "Observability", kind: cross-cutting, icon: prometheus, subtitle: "Prometheus · Grafana · Loki" } connections: # explicit edges; focal-touching ones become accent automatically - { from: "NiFi", to: "MinIO", style: "primary" } - { from: "NiFi", to: "Trino", style: "secondary" } - { from: "MinIO", to: "Notebooks", style: "primary" } - { from: "Trino", to: "MinIO", style: "query" } # read-back (dashed) - { from: "Notebooks", to: "Superset", style: "secondary" } - { from: "Airflow", to: ["NiFi", "Trino", "Notebooks"], style: "trigger" } focal: "MinIO" # exactly one; defaults to first kind=node under "Storage" dark: false ``` **Reserved chevron names** (always vertical, even if `vertical: true` is omitted): `Orchestration`, `Security`, `Observability`, `Governance`, `Backup`. **Reserved `kind` values:** - `node` — a standard box inside the cluster (default). - `bar` — a horizontal strip spanning the cluster top. Typically one (Orchestration); see §5 for the pairing rule. - `cross-cutting` — a horizontal strip spanning the body width (stops at the strip margin), stacked below the cluster. **Zero or more allowed**; each stacks 44 px below the previous (§2.5) and pairs 1:1 with a vertical chevron (§5). **Optional `color`** (per component, hex string): tints the component's container and content while leaving connectors untouched. See §3.4. Use sparingly — a custom color is a semantic flag (e.g., red = security concern), not decoration. **Source `type` values** → icon mapping (use `references/primitive-icons.md`): - `db` → `database` - `ftp` → `bucket` or upload arrow - `web` → `internet` - `legacy` → `server` - `api` → `api` - Any explicit icon name in `primitive-icons.md` is also accepted. --- ## 2. Layout formulas — deterministic geometry Every coordinate below is derived from the inputs. **No hardcoded numbers in examples that aren't justified here.** ### 2.1 Canvas ``` has_vertical = any(c.vertical or c.name in reserved_names for c in chevrons) right_strip_w = 28 if has_vertical else 0 strip_margin = 8 if has_vertical else 0 # gap between body and right strip effective_w = 1000 - right_strip_w - strip_margin # 1000 or 964 n_cross = count of components with kind == "cross-cutting" strip_y_bot = max(428, 388 + n_cross * 44 - 4) # extends to last crosscut row viewBox_h = max(540, strip_y_bot + 112) # 112 reserved for legend viewBox = f"0 0 1000 {viewBox_h}" ``` Every horizontal element (chevron banner, cluster, orchestration bar, identity / cross-cutting bars) ends at `effective_w`. The right strip sits at `x = 1000 - right_strip_w` (= 972). The 8-px band between them is visual breathing room — never put content there. `viewBox_h` grows when more than one cross-cutting bar is declared: 1 crosscut → 540, 2 → 600 (or 584 if you want it tight; the rule rounds to the next multiple of 20 for clean grids). ### 2.2 Horizontal chevron banner ``` y_banner = 4 h_banner = 28 horizontals = [c for c in chevrons if not c.vertical and c.name not in reserved_names] sum_columns = sum(c.columns for c in horizontals) base_unit = floor_to_4(effective_w / sum_columns) # multiple of 4 widths = [max(120, base_unit * c.columns) for c in horizontals] widths[-1] += effective_w - sum(widths) # trailing absorbs remainder x_boundaries = cumulative_sum([0] + widths) # length sum_columns+1 chevron_cx(C) = (x_boundaries[index(C)] + x_boundaries[index(C)+1]) / 2 ``` **Polygon shapes:** - First (leftmost): `(x0,4) (x1-12,4) (x1,18) (x1-12,32) (x0,32)` - Middle: `(x0,4) (x1-12,4) (x1,18) (x1-12,32) (x0,32) (x0+12,18)` - Last (rightmost): `(x0,4) (effective_w,4) (effective_w,32) (x0,32) (x0+12,18)` Fills alternate between two steps of the **phase-band palette** (§6.1): `band-1` / `band-2` in light mode, `band-2` / `band-3` in dark. Labels: `band-label` fill, `eyebrow` role (mono), `font-size=7`, `letter-spacing=0.14em`, `text-anchor=middle`, centered at `chevron_cx, 21`. **Color override** (per chevron, both horizontal and vertical): a chevron may declare an optional `color: "#hex"` that replaces the alternation fill for that one chevron. Use it to flag a phase that pairs with a custom-colored component (e.g., `Security` chevron in red when the Identity bar uses `color: "#b85450"`). Rules: - Override applies to the polygon fill only. The label stays `band-label`; it never takes the active skin's `paper`. - The alternation index doesn't shift; neighboring chevrons keep their natural fill, even if it produces two adjacent same-fill chevrons. Don't try to "fix" this — overrides should be rare (≤ 2 per diagram). - In dark mode, use the same hex unless contrast against `band-label` falls below 4.5:1; if it does, pick a darker shade for dark mode and document it as a `color_dark` field on that chevron. - A chevron color override is independent of any paired component's color, but pairing them (same hex on chevron + bar) is the conventional way to make the column "read" as one concern. ### 2.3 Source zone (dashed, external) ``` sources_x = 4 sources_y = 40 sources_w = x_boundaries[1] - 8 # width of the first chevron, minus 4px gutter each side sources_h = 336 ``` Stroke: `ink @ 0.20`, `stroke-width=0.8`, `stroke-dasharray=6,3`, `rx=6`. Zone fill: `ink @ 0.02`. ### 2.4 Cluster boundary (solid) ``` cluster_x = x_boundaries[1] + 4 # starts at end of source zone + 4px gutter cluster_y = 40 cluster_w = effective_w - cluster_x # extends to right strip / canvas edge cluster_h = 336 ``` Stroke: `ink @ 0.18`, `stroke-width=1.2`, `rx=8`. Fill: `ink @ 0.02`. K8s icon + label at `(cluster_x + 16, 352)` (icon) and `(cluster_x + 40, 362)` (text). ### 2.5 Cross-cutting bars (identity, observability, …) Zero or more `kind: cross-cutting` components stack below the cluster. Each gets its own 40-px row with a 4-px gap. ``` crosscuts = [c for c in components if c.kind == "cross-cutting"] # ordered as declared cross_x = 4 cross_y(k) = 388 + k * 44 # 388, 432, 476, … cross_w = effective_w - 4 # spans body width, stops at the strip margin cross_h = 40 ``` Stroke: `ink @ 0.20`, `stroke-width=0.8`, `rx=6`. Fill: `ink @ 0.05`. Icon at `(16, cross_y(k) + 10)`, name centered at `(effective_w / 2, cross_y(k) + 22)`, subtitle at `(effective_w / 2, cross_y(k) + 34)`. Reserved cross-cutting *concerns* (informational; user can name the actual bar whatever they want): - **Identity / Security** — Keycloak, LDAP/AD, Okta, Auth0, OIDC providers - **Observability** — Prometheus + Grafana, Datadog, OpenTelemetry, Loki - **Backup / DR** — Velero, Restic, snapshot orchestrators - **Governance / Lineage** — OpenMetadata, DataHub, Apache Atlas - **Secrets / config** — Vault, Sealed Secrets, External Secrets Each cross-cutting bar pairs 1:1 with a vertical chevron in the right strip (§5). ### 2.6 Orchestration bar component (inside cluster) ``` bar_x = cluster_x + 12 bar_y = 52 bar_w = cluster_w - 24 bar_h = 44 ``` Stroke: `ink @ 0.18`, `stroke-width=0.8`, `rx=4`. Fill: `ink @ 0.05`. Tool icon at the far right (`bar_x + bar_w - 50, 58`); name centered at `(bar_x + bar_w/2, 71)`; subtitle at `(bar_x + bar_w/2, 84)`. ### 2.7 Component nodes (inside cluster) ``` node_w = 152 node_h = 80 # focal same height, accent border node_cx(N) = chevron_cx(N.chevron) # ← non-negotiable node_x(N) = node_cx(N) - node_w/2 ``` If a chevron has K nodes assigned, stack them vertically: ``` first_top_y = 120 if any bar in this column else 64 gap = 16 row_top(k) = first_top_y + k * (node_h + gap) # k = 0..K-1 ``` **Focal node:** `fill="{accent @ 0.08}"`, `stroke="{accent}"`, `stroke-width=1.2`. Title text in `accent`. All other nodes: white fill, `stroke={ink @ 0.25}`, `stroke-width=1`. Role badge top-left at `(node_x+8, node_y+6)`, size 12 high. Icon top-right at `(node_x+node_w-32, node_y+6)`, 24×24, monochrome via `currentColor`. Name centered at `(node_cx, node_y+44)` size 11 sans semibold. Subtitle at `(node_cx, node_y+56)` size 8 mono muted. ### 2.8 Source nodes (inside dashed zone) ``` src_node_w = sources_w - 8 src_node_h = 64 # uniform; chosen to fit ≤ 4 sources src_node_x = sources_x + 4 src_first_top_y = 60 src_gap = 16 src_row_top(k) = src_first_top_y + k * (src_node_h + src_gap) ``` Same role-badge / icon / name / subtitle pattern as cluster nodes (icon at `src_node_x+54, row_top(k)+6`; name centered at `src_node_x+src_node_w/2, row_top(k)+42`; subtitle one line below). Role badge text: `EXT`. Caps at 4 sources; for more, split into a separate diagram. ### 2.9 Right strip — vertical chevrons ``` strip_x = 1000 - right_strip_w # 972 when present strip_w = 28 verticals = [c for c in chevrons if c.vertical or c.name in reserved_names] strip_y_top = 40 strip_y_bot = max(428, 388 + n_cross * 44 - 4) # extends to last crosscut row (see §2.1) strip_h_total = strip_y_bot - strip_y_top heights = [floor_to_4(strip_h_total / len(verticals))] * len(verticals) heights[-1] += strip_h_total - sum(heights) # last absorbs remainder ``` Examples: - 2 verticals (Orchestration + Security), 1 crosscut → `heights = [192, 196]`, layout `[40..232, 232..428]`. - 3 verticals (Orchestration + Security + Observability), 2 crosscuts → `strip_y_bot = 472`, `strip_h_total = 432`, `heights = [144, 144, 144]`, layout `[40..184, 184..328, 328..472]`. Adjacent edges share the same y (no gap), like horizontal chevrons share x at their boundary. **Polygon shapes** (top-to-bottom flow, mirrors horizontal §2.2): - First (topmost): flat top, point at bottom — `(strip_x, y0) (strip_x+strip_w, y0) (strip_x+strip_w, y1-12) (strip_x+strip_w/2, y1) (strip_x, y1-12)` - Middle: notch on top, point on bottom — `(strip_x, y0) (strip_x+strip_w/2, y0+12) (strip_x+strip_w, y0) (strip_x+strip_w, y1-12) (strip_x+strip_w/2, y1) (strip_x, y1-12)` - Last (bottommost): notch on top, flat bottom — `(strip_x, y0) (strip_x+strip_w/2, y0+12) (strip_x+strip_w, y0) (strip_x+strip_w, y1) (strip_x, y1)` Fills alternate `band-1` / `band-2` (same phase-band palette as the horizontals, §6.1). Labels: `band-label` fill, `eyebrow` role (mono), `font-size=7`, `letter-spacing=0.14em`, **rotated −90°**, anchored at `(strip_x + strip_w/2, (y0+y1)/2)`. Vertical chevrons honor the per-chevron `color` override documented in §2.2 — apply the hex to the polygon fill, leave the rotated label `band-label`. Pair the override with the same hex on the chevron's paired bar/crosscut to bind them visually as one concern. --- ## 3. Connector rules (mandatory) These are non-negotiable. Pick the style **automatically** from the topology — do not let the user override style on focal-touching or bar-originating edges. | `style` | Stroke | Width | Dash | Marker | When required | |---|---|---|---|---|---| | `primary` | `accent` | 1.2 | — | `arrow-accent` | Every edge whose endpoint is the `focal` node. | | `secondary` | `muted` | 1.0 | — | `arrow` | Default for source→component and component→component when neither endpoint is focal. | | `trigger` | `muted` | 1.0 | `4,3` | `arrow-sm` | Every edge originating from a `kind: bar` component. | | `query` | `ink @ 0.30` | 1.0 | `4,3` | `arrow` | Read-back edges (e.g., focal ↔ Trino). | **Defs block** (required, exactly these four markers): ```svg ``` ### 3.1 Exit / entry sides (non-negotiable) | Edge kind | Exit side of source | Entry side of target | |---|---|---| | Source → cluster node | **right** of source node | **left** of target | | Component → component (within cluster) | **right** | **left** | | Bar component → node | **bottom** of bar | **top** of node | | Cross-cutting bar | — (emits no edges) | — | | Vertical chevron | — (labels only; emits no edges) | — | ### 3.2 Routing - Orthogonal elbows, **at most two bends** per path. - Use a Q-bezier 8-px corner radius at every bend. - Z-order: draw **all connectors before any node rectangle** (so node fills mask the line ends). - Exactly one `marker-end` per `` / ``. Never both `marker-start` and `marker-end`. - Labels: every `primary` and `secondary` connector gets a label (small mono, opaque paper-filled rect mask behind). `trigger` and `query` connectors are unlabelled. ### 3.3 Crossings - Avoid. Re-route via the chevron divider trunk (§4) before accepting a crossing. - If unavoidable, the path drawn second carries a 6-px arc hop over the first. ### 3.4 Component color override A component may declare an optional `color: "#hex"` (CSS color string). The override **only** retints the component's container and content — connectors are never recolored. Edges keep their topology-driven style from §3. **Where the color is applied** (given `C = color`): | Element | Light mode | Dark mode | |---|---|---| | Container fill (`rect` body) | `rgba(C, 0.06)` | `rgba(C, 0.10)` | | Container stroke | `rgba(C, 0.35)` (`stroke-width=1` for nodes, `0.8` for bars) | `rgba(C, 0.45)` | | Role badge stroke (nodes) | `rgba(C, 0.40)` | `rgba(C, 0.55)` | | Role badge text (nodes) | `rgba(C, 0.85)` | `rgba(C, 1.0)` | | Icon fill / stroke | `C` | lighten `C` by ~15% (or use `C` if already light) | | Name text | `C` | lighten `C` | | Subtitle text | **unchanged** (`muted`) | **unchanged** (`muted`) | | Connectors touching this component | **unchanged** (still topology-driven) | **unchanged** | The subtitle stays muted because it's parenthetical metadata — only the primary identity (name + icon + border) carries the color signal. **Rules**: - **Never on the focal node.** The focal node is already colored with the accent (§2.7). A `color` on the focal node is ignored — accent wins. - **Never on source nodes.** Sources live outside the cluster and stay neutral. - **Cap at 2 custom-colored components** per diagram (in addition to the focal). Three or more colored things erases the signal — the same reason §1 limits accent to 1–2 elements. - **No color on connectors.** If you find yourself wanting a colored edge, the right move is to pick a different `style` from §3, not to override. **Semantic uses** (recommended): - `#b85450` (rust-red) — Security / Identity (Keycloak, Vault) - `#5a7d9a` (slate-blue) — Observability (Prometheus, Datadog) - `#7a8c47` (olive-green) — Governance / Lineage (OpenMetadata) - `#8c6d3f` (warm-brown) — Backup / DR Stick to these unless the user's brand demands otherwise. Random hex per component is exactly the failure mode this skill avoids. --- ## 4. Block branching rules (fan-out) The single biggest reproducibility hazard. Fix these rules and the diagram becomes predictable. ### 4.1 Source fan-out (one source → N components) ``` exit_x = source.right trunk_x = cluster_x - 8 # 4-px gutter before cluster border ``` Path per target: `M exit_x,source_cy → H trunk_x → V target_cy → H target.left`. Use Q-bezier corners. ### 4.2 Component fan-out (one component → N components) ``` exit_x = node.right trunk_x = x_boundaries[index(source.chevron) + 1] + 4 # 4 px past the chevron divider ``` Path per target: `M exit_x,source_cy → H trunk_x → V target_cy → H target.left`. ### 4.3 Fan-out cap **Max 3 outgoing edges per node.** Above 3, introduce a hub (usually the `focal` node). The chevron banner is the legend; if a node is fanning out to four downstream targets, it's secretly the hub — make it explicit. ### 4.4 Bar drops (Airflow → N nodes) ``` drop_x(target) = target.cx drop_y_start = bar.bottom drop_y_end = target.top ``` Straight vertical line, `style: trigger`. One per target. No bends — bar drops never elbow. ### 4.5 Source vertical staggering When multiple sources connect to the same single target (e.g. four sources → NiFi), stagger their entry y on the target: ``` entry_y(k) = target.top + 8 + k * (target_h - 16) / (N - 1) # k = 0..N-1, evenly spaced ``` This avoids overlapping arrowheads at the target's left edge. --- ## 5. Vertical chevrons — semantics Reserved names `Orchestration`, `Security`, `Observability`, `Governance`, `Backup` always render in the right strip (§2.9). Any chevron with `vertical: true` is treated as a reserved-style vertical regardless of name. The rules: - **Pairing rule (mandatory, 1:1):** every vertical chevron pairs with exactly one cross-spanning component, and every cross-spanning component pairs with exactly one vertical chevron. The two component kinds that pair: - `kind: bar` — lives inside the cluster (top row). Conventionally paired with `Orchestration`. - `kind: cross-cutting` — lives below the cluster, one row per component. Paired with `Security`, `Observability`, `Governance`, etc. If the inputs declare a vertical chevron without a paired component (or vice versa), halt and ask the user — the diagram is incomplete. - **Count constraint:** `len(verticals) == len(bars) + len(crosscuts)`. The right strip is split evenly among all verticals (§2.9), so visual alignment between a chevron and its bar/row is approximate — the *label* is what matters, not the y-pixel match. - **Ordering convention:** declare verticals top-down in the order: bar-paired first (Orchestration), then crosscut-paired in the same order the crosscuts appear below the cluster. This keeps the visual reading order consistent. - **No edges:** vertical chevrons emit no connectors themselves. They are *labels for a column of cross-cutting concern*. - **No node placement:** no `kind: node` may be assigned to a vertical chevron. Nodes always belong to a horizontal phase. - **Right strip presence:** if any vertical chevron exists, the right strip is reserved (`effective_w = 964`) and **all** horizontal chevron widths and cluster geometry shrink accordingly. Do not draw a vertical chevron on top of the cluster. The visual contract: the vertical chevron's column visually "owns" the bar/cross-cutting row at its approximate y-band. Orchestration (top of strip) ↔ Airflow bar (top of cluster). Security ↔ Identity bar. Observability ↔ monitoring bar (below identity). And so on. --- ## 6. Dark mode `paper`, `ink`, `muted`, and `accent` invert with the skin: take their values from the dark column in [`style-guide.md`](style-guide.md). Every derived value in this reference is a **role at an opacity**, so `ink @ 0.18` resolves to dark ink on light paper and light ink on dark paper with no extra handling. Only these differ between modes: | Element | Light | Dark | Why it differs | |---|---|---|---| | Muted text | `muted` | `ink @ 0.65` | Dark mode softens secondary text by opacity rather than by hue | | Dashed border | `ink @ 0.20` | `ink @ 0.22` | A hairline needs marginally more presence on dark paper | | Node fill | `#ffffff` (white) | `ink @ 0.06` | White is opaque; on dark paper the node lifts off the ground instead | | Node stroke | `ink @ 0.25` | `ink @ 0.20` | Light ink on dark paper reads stronger at equal opacity | | Focal fill | `accent @ 0.08` | `accent @ 0.12` | ditto | | Phase bands | `band-1` / `band-2` | `band-2` / `band-3` | The alternation shifts one step lighter (§6.1) | Unchanged across modes: cluster border `ink @ 0.18`, dot pattern `ink @ 0.10`, focal stroke `accent`, accent connector `accent`, and the chevron label, which is always `band-label`. ### 6.1 Phase-band palette The chevron banner needs a **dark band with a light label in both modes**. `ink` and `paper` swap places between modes, so the banner can't be built from them. It uses four fixed tokens that ignore the light/dark flip: | Token | Value | Use | |---|---|---| | `band-1` | `#2d3142` | Darkest step: odd chevrons, light mode | | `band-2` | `#3d4460` | Middle step: even chevrons light, odd chevrons dark | | `band-3` | `#4a5270` | Lightest step: even chevrons, dark mode | | `band-label` | `#f5f5f5` | Fixed label color: 11.82:1, 8.78:1, and 7.05:1 against the three bands | **These are type-scoped tokens, not skin roles, and they do not invert.** They are the one deliberate exception to the rule that hex values live only in [`style-guide.md`](style-guide.md). `scripts/lint-skin.py` rejects `band-2` and `band-3` as off-palette, which is why the shipped high-level examples are listed in `scripts/lint-skin-baseline.txt`. Phase labels always use `band-label`, and `band-label` has to hold at least 4.5:1 against every band, because these are 7px labels in either mode. When you re-skin, derive three analogous steps from the new brand's darkest neutral and pick a fixed label color that holds 4.5:1 against all three. --- ## 7. Reproducibility checklist (the taste gate) Before emitting SVG, verify **every** item. If any fails, fix it — don't ship. 1. Every cluster `node.cx` equals its chevron's `cx` (§2.2 + §2.7). This is what makes the chevron banner a real legend. 2. Every chevron `width` is a multiple of 4 and ≥ 120. 3. The reserved right strip (28 px) exists **iff** any vertical chevron is declared. If yes, `effective_w = 964`; if no, `effective_w = 1000`. 4. Exactly **one** `focal` node. If `focal` is unset in inputs, default to the first `kind: node` under chevron "Storage". 5. Every edge whose endpoint is the focal node uses `style: primary` (accent stroke + `arrow-accent` marker). 6. Every edge originating from a `kind: bar` component uses `style: trigger` (dashed + `arrow-sm`). 7. The cross-cutting bar (if any) emits **no** edges. 8. No node has > 3 outgoing edges, or if it does, it is the declared `focal` / hub. 9. All `` and `` connectors are emitted **before** any node `` (z-order). 10. Each vertical chevron pairs **1:1** with exactly one `bar` or `cross-cutting` component (§5 pairing rule). `len(verticals) == len(bars) + len(crosscuts)`. 11. `viewBox_h = max(540, strip_y_bot + 112)` — grow the canvas when multiple crosscuts are declared so the legend still fits. 12. Custom component colors (§3.4) apply only to container + icon + name; connectors stay topology-driven. Cap at 2 custom-colored components in addition to the focal. 13. The diagram passes SKILL.md §9 (4-px grid; ≤ 2 accent elements; mono only for technical content; hairlines; no shadows; no `rounded-2xl`). --- ## 8. Anti-patterns - Chevron banner omitted — it's the key that maps visual columns to functional phases. - Node x-center off-chevron (§7 #1) — breaks the "banner-as-legend" contract. - Vertical chevron drawn on the cluster (overlay) instead of in a reserved right strip. - More than one focal node — MinIO/S3 (or whichever storage hub) is *the* focal point. - External zone with solid border — dashed border is the signal that these components are outside the cluster. - Identity bar inside the cluster boundary — it applies to all components and must span the full canvas width. - Vertical chevron without a paired bar/cross-cutting component — see §5 pairing rule. - Bar-component edges drawn solid — orchestration triggers must be dashed. - Source fanning out to >3 components without a hub. --- ## 9. Examples - `assets/example-high-level.html` — horizontal-only, 5 phases, light skin. - `assets/example-high-level-dark.html` — same, dark skin. - `assets/example-high-level-full.html` — same, editorial-card frame. - `assets/example-high-level-vertical.html` — adds vertical Orchestration + Security chevrons, Airflow bar, Keycloak cross-cutting. **Reference render of the full parametric pattern.** - `assets/example-high-level-vertical-dark.html` — vertical pattern, dark skin. - `assets/example-high-level-vertical-full.html` — vertical pattern, editorial-card frame. - `assets/example-datalake.html` — unclustered five-phase data stack (Sources → Ingest → Data Lake → Query → Consume), zone-based flow without a container-orchestrator boundary. The MinIO lake is the focal node; vertical concerns are flattened into the horizontal chevron banner. Light skin. - `assets/example-datalake-dark.html` — same, dark skin. - `assets/example-datalake-full.html` — same, editorial-card frame.