Merge remote-tracking branch 'origin/main' into codex/pr24-final

This commit is contained in:
Cathryn Lavery
2026-08-11 21:37:11 -07:00
105 changed files with 1123 additions and 422 deletions
+15 -1
View File
@@ -430,6 +430,9 @@ Run before producing any diagram.
**Technical:**
- [ ] Diagram `<svg>` has `role="img"` and `aria-labelledby` resolving to its `<title>` and `<desc>`?
- [ ] `<title>` is the first child of `<svg>` (before `<defs>`) and both `<title>` and `<desc>` are filled in?
- [ ] `<title>` / `<desc>` IDs are prefixed for this diagram and variant — never bare `title` / `desc`?
- [ ] Arrows drawn before boxes?
- [ ] **Every connector between off-axis nodes uses a rounded right-angle elbow (`r=8`)? No diagonal `<line>` slants?**
- [ ] **Every arrow label has a visible 6–10px gap above its connector? (Mask rect not touching the stroke.)**
@@ -471,7 +474,7 @@ Every diagram ships in three variants (see `assets/`):
1. Copy the variant closest to what you want (`template.html` for minimal, `template-full.html` for cards).
2. Load the matching `references/type-<name>.md` for layout conventions.
3. Replace the eyebrow, h1, and SVG body.
3. Replace the eyebrow, h1, and SVG body. Replace `[diagram-slug]` with the file's diagram/variant slug, fill the copied `<title>` / `<desc>` placeholders, and do not delete them.
4. Run the §9 taste gate.
---
@@ -517,6 +520,17 @@ Always produce a single self-contained `.html` file:
Renders correctly in any modern browser.
### Accessible SVG contract
Every diagram is an accessible figure by default:
1. Its `<svg>` carries `role="img"` and `aria-labelledby` naming the diagram's `<title>` and `<desc>`.
2. `<title>` is the first child of `<svg>`, before `<defs>`. Assistive technology may ignore a title placed later.
3. The IDs are prefixed per diagram and variant: `<slug>-title` / `<slug>-desc`, where the slug matches the file (`loop`, `loop-dark`, `loop-full`). Bare `title` / `desc` IDs are banned because two inline diagrams would create duplicate IDs and the second could be announced with the first diagram's name.
4. `<title>` is the short name of the subject — roughly the page `<h1>`, and about 60 characters or fewer.
5. `<desc>` is one sentence stating what the diagram shows in terms a reader needs without the image. Describe the content, not the geometry: “Org chart showing a command center routing work to specialist agents and escalation owners,” not “A box at the top with five boxes below it.” A shape-by-shape narration is worse than no useful description.
6. Decorative-only SVG, such as the specimen glyphs in `assets/icons.html`, carries `aria-hidden="true"` instead. Giving decorative marks accessible names adds noise.
### Exporting to PNG / SVG
When the user asks to export, save, rasterize, or convert a generated diagram to `.png` or `.svg`, load [`references/export.md`](references/export.md) and follow the procedure there. Both formats deliver the diagram only (the `<svg>` node) — editorial wrappers like cards and headers are dropped by design. Export is **manual** — never produce export files unprompted.
@@ -58,7 +58,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>Content site in production</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="architecture-dark-title architecture-dark-desc">
<title id="architecture-dark-title">Content site in production</title>
<desc id="architecture-dark-desc">Architecture diagram showing reader requests moving through Cloudflare to an Astro origin, MDX bundle, and content CMS.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -48,7 +48,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="architecture-full-title architecture-full-desc">
<title id="architecture-full-title">Content site in production</title>
<desc id="architecture-full-desc">Architecture diagram showing reader requests moving through Cloudflare to an Astro origin, MDX bundle, and content CMS.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>Content site in production</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="architecture-title architecture-desc">
<title id="architecture-title">Content site in production</title>
<desc id="architecture-desc">Architecture diagram showing reader requests moving through Cloudflare to an Astro origin, MDX bundle, and content CMS.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -28,7 +28,9 @@
<p class="eyebrow">Bar · Diagram Design</p>
<h1>Sprint velocity · 8-sprint view</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="bar-dark-title bar-dark-desc">
<title id="bar-dark-title">Sprint velocity · 8-sprint view</title>
<desc id="bar-dark-desc">Bar chart showing story points delivered across sprints S1 through S8, with Sprint 5 as the record high.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -36,7 +36,9 @@
<p class="subtitle">Story points delivered per two-week sprint over one product cycle. Sprint 5 is the standout — a focused scope and no mid-sprint scope additions.</p>
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="bar-full-title bar-full-desc">
<title id="bar-full-title">Sprint velocity · 8-sprint view</title>
<desc id="bar-full-desc">Bar chart showing story points delivered across sprints S1 through S8, with Sprint 5 as the record high.</desc>
<defs><pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern></defs>
<rect width="100%" height="100%" fill="#f5f5f5"/>
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
@@ -28,7 +28,9 @@
<p class="eyebrow">Bar · Diagram Design</p>
<h1>Sprint velocity · 8-sprint view</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="bar-title bar-desc">
<title id="bar-title">Sprint velocity · 8-sprint view</title>
<desc id="bar-desc">Bar chart showing story points delivered across sprints S1 through S8, with Sprint 5 as the record high.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -38,9 +38,9 @@
<p class="eyebrow">Data flow · Diagram Design</p>
<h1>Role-scoped analytics pipeline</h1>
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flow-title flow-desc">
<title id="flow-title">Role-scoped analytics data flow</title>
<desc id="flow-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="data-flow-dark-title data-flow-dark-desc">
<title id="data-flow-dark-title">Role-scoped analytics data flow</title>
<desc id="data-flow-dark-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="rgba(245,245,245,0.10)"/></pattern>
<marker id="arr-muted" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto"><path d="M0 0 L6 3 L0 6 Z" fill="#bfc0c0"/></marker>
@@ -58,9 +58,9 @@
</header>
<div class="diagram-container">
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flow-title flow-desc">
<title id="flow-title">Role-scoped analytics data flow</title>
<desc id="flow-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="data-flow-full-title data-flow-full-desc">
<title id="data-flow-full-title">Role-scoped analytics data flow</title>
<desc id="data-flow-full-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="rgba(45,49,66,0.10)"/></pattern>
<marker id="arr-muted" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto"><path d="M0 0 L6 3 L0 6 Z" fill="#4f5d75"/></marker>
@@ -38,9 +38,9 @@
<p class="eyebrow">Data flow · Diagram Design</p>
<h1>Role-scoped analytics pipeline</h1>
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flow-title flow-desc">
<title id="flow-title">Role-scoped analytics data flow</title>
<desc id="flow-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<svg viewBox="0 0 728 356" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="data-flow-title data-flow-desc">
<title id="data-flow-title">Role-scoped analytics data flow</title>
<desc id="data-flow-desc">A Data Engineer ingests and stores commerce data, a Data Scientist transforms and analyzes it, and an Analyst publishes a dashboard.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="rgba(45,49,66,0.10)"/></pattern>
<marker id="arr-muted" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto"><path d="M0 0 L6 3 L0 6 Z" fill="#4f5d75"/></marker>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>Open data lake · End-to-end stack</h1>
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="datalake-dark-title datalake-dark-desc">
<title id="datalake-dark-title">Open data lake · End-to-end stack</title>
<desc id="datalake-dark-desc">Data lake architecture showing app servers and databases flowing through Apache NiFi into MinIO, then Trino, StarRocks, Superset, JupyterLab, and Python.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -106,7 +108,7 @@
<rect x="16" y="60" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="24" y="66" width="26" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="37" y="75" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -119,7 +121,7 @@
<rect x="16" y="164" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="24" y="170" width="26" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="37" y="179" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -132,7 +134,7 @@
<rect x="188" y="60" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="196" y="66" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="210" y="75" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">FLOW</text>
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/>
</svg>
<text x="256" y="102" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -143,7 +145,7 @@
<rect x="188" y="164" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="196" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="210" y="179" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORCH</text>
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="256" y="206" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Airflow</text>
@@ -154,7 +156,7 @@
<rect x="392" y="100" width="160" height="80" rx="8" fill="rgba(240,138,89,0.10)" stroke="#f08a59" stroke-width="1.2"/>
<rect x="400" y="106" width="36" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.50)" stroke-width="0.8"/>
<text x="418" y="115" fill="rgba(240,138,89,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59">
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="472" y="148" fill="#f08a59" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO</text>
@@ -165,7 +167,7 @@
<rect x="616" y="60" width="144" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="624" y="66" width="36" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="642" y="75" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="688" y="102" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -176,7 +178,7 @@
<rect x="616" y="164" width="144" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="624" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="638" y="179" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">OLAP</text>
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#f5f5f5">
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#f5f5f5" aria-hidden="true">
<path d="M11.8,26.4c-0.1,2.2,0.9,3.4,2.3,4.5c9,7.4,18,14.8,27,22.2c2.5,2.1,2.7,3.5,1,6.2c-4.4,6.7-8.8,13.4-13.2,20.1c-1.7,2.5-3.2,2.9-5.9,1.4c-2.8-1.6-5.6-3.2-8.4-4.8c-3.2-1.8-4.8-4.6-4.8-8.3c0-11.8,0-23.6,0-35.5C9.8,30.2,10.3,28.4,11.8,26.4z"/>
<path d="M87.9,73.8c0.6-2.3-0.5-3.5-1.9-4.6c-9-7.4-17.9-14.7-26.8-22.1c-2.9-2.4-3.1-3.6-1.1-6.7c4.3-6.6,8.7-13.2,13-19.8c1.7-2.6,3.3-2.9,6-1.4c2.8,1.6,5.6,3.2,8.3,4.8c3.2,1.8,4.7,4.5,4.7,8.2c0,11.9,0,23.7,0,35.6C90.2,69.9,89.6,71.9,87.9,73.8z"/>
<path d="M67.1,56.8c0.6,0.4,17.3,14.1,17.5,14.3c2.4,2.2,2.2,4.1-0.6,5.8C76.8,81,57.3,92.1,54.8,93.6c-3.2,1.9-6.4,1.9-9.6,0c-4.6-2.7-9.2-5.3-13.8-8c-2.2-1.3-2.2-2.7,0-3.9C42.3,75.5,53.1,69.2,64,63C66.5,61.6,68.2,60.1,67.1,56.8z"/>
@@ -190,7 +192,7 @@
<rect x="816" y="60" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="824" y="66" width="18" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="833" y="75" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BI</text>
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="884" y="102" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
@@ -201,7 +203,7 @@
<rect x="816" y="152" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="824" y="158" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="835" y="167" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">NB</text>
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="884" y="194" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">JupyterLab</text>
@@ -212,7 +214,7 @@
<rect x="816" y="244" width="136" height="56" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="824" y="250" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="840" y="259" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PROC</text>
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"/>
</svg>
<text x="884" y="286" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Python</text>
@@ -43,7 +43,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="datalake-full-title datalake-full-desc">
<title id="datalake-full-title">Open data lake · End-to-end stack</title>
<desc id="datalake-full-desc">Data lake architecture showing app servers and databases flowing through Apache NiFi into MinIO, then Trino, StarRocks, Superset, JupyterLab, and Python.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -91,7 +93,7 @@
<rect x="16" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="24" y="66" width="26" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="37" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -103,7 +105,7 @@
<rect x="16" y="164" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="24" y="170" width="26" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="37" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -115,7 +117,7 @@
<rect x="188" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="196" y="66" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="210" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">FLOW</text>
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/>
</svg>
<text x="256" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -125,7 +127,7 @@
<rect x="188" y="164" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="196" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="210" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORCH</text>
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="256" y="206" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Airflow</text>
@@ -135,7 +137,7 @@
<rect x="392" y="100" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="400" y="106" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="418" y="115" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36">
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="472" y="148" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO</text>
@@ -145,7 +147,7 @@
<rect x="616" y="60" width="144" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="624" y="66" width="36" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="642" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="688" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -155,7 +157,7 @@
<rect x="616" y="164" width="144" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="624" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="638" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">OLAP</text>
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#2d3142">
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#2d3142" aria-hidden="true">
<path d="M11.8,26.4c-0.1,2.2,0.9,3.4,2.3,4.5c9,7.4,18,14.8,27,22.2c2.5,2.1,2.7,3.5,1,6.2c-4.4,6.7-8.8,13.4-13.2,20.1c-1.7,2.5-3.2,2.9-5.9,1.4c-2.8-1.6-5.6-3.2-8.4-4.8c-3.2-1.8-4.8-4.6-4.8-8.3c0-11.8,0-23.6,0-35.5C9.8,30.2,10.3,28.4,11.8,26.4z"/>
<path d="M87.9,73.8c0.6-2.3-0.5-3.5-1.9-4.6c-9-7.4-17.9-14.7-26.8-22.1c-2.9-2.4-3.1-3.6-1.1-6.7c4.3-6.6,8.7-13.2,13-19.8c1.7-2.6,3.3-2.9,6-1.4c2.8,1.6,5.6,3.2,8.3,4.8c3.2,1.8,4.7,4.5,4.7,8.2c0,11.9,0,23.7,0,35.6C90.2,69.9,89.6,71.9,87.9,73.8z"/>
<path d="M67.1,56.8c0.6,0.4,17.3,14.1,17.5,14.3c2.4,2.2,2.2,4.1-0.6,5.8C76.8,81,57.3,92.1,54.8,93.6c-3.2,1.9-6.4,1.9-9.6,0c-4.6-2.7-9.2-5.3-13.8-8c-2.2-1.3-2.2-2.7,0-3.9C42.3,75.5,53.1,69.2,64,63C66.5,61.6,68.2,60.1,67.1,56.8z"/>
@@ -168,7 +170,7 @@
<rect x="816" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="66" width="18" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="833" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BI</text>
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="884" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
@@ -178,7 +180,7 @@
<rect x="816" y="152" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="158" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="835" y="167" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">NB</text>
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="884" y="194" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">JupyterLab</text>
@@ -188,7 +190,7 @@
<rect x="816" y="244" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="250" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="840" y="259" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PROC</text>
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"/>
</svg>
<text x="884" y="286" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Python</text>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>Open data lake · End-to-end stack</h1>
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 488" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="datalake-title datalake-desc">
<title id="datalake-title">Open data lake · End-to-end stack</title>
<desc id="datalake-desc">Data lake architecture showing app servers and databases flowing through Apache NiFi into MinIO, then Trino, StarRocks, Superset, JupyterLab, and Python.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -129,7 +131,7 @@
<rect x="16" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="24" y="66" width="26" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="37" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -142,7 +144,7 @@
<rect x="16" y="164" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="24" y="170" width="26" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="37" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="72" y="170" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -155,7 +157,7 @@
<rect x="188" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="196" y="66" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="210" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">FLOW</text>
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="244" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/>
</svg>
<text x="256" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -166,7 +168,7 @@
<rect x="188" y="164" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="196" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="210" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ORCH</text>
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="244" y="170" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="256" y="206" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Airflow</text>
@@ -177,7 +179,7 @@
<rect x="392" y="100" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="400" y="106" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="418" y="115" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36">
<svg x="460" y="108" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="472" y="148" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO</text>
@@ -188,7 +190,7 @@
<rect x="616" y="60" width="144" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="624" y="66" width="36" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="642" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">QUERY</text>
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="676" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="688" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -199,7 +201,7 @@
<rect x="616" y="164" width="144" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="624" y="170" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="638" y="179" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">OLAP</text>
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#2d3142">
<svg x="676" y="170" width="24" height="24" viewBox="0 0 100 100" fill="#2d3142" aria-hidden="true">
<path d="M11.8,26.4c-0.1,2.2,0.9,3.4,2.3,4.5c9,7.4,18,14.8,27,22.2c2.5,2.1,2.7,3.5,1,6.2c-4.4,6.7-8.8,13.4-13.2,20.1c-1.7,2.5-3.2,2.9-5.9,1.4c-2.8-1.6-5.6-3.2-8.4-4.8c-3.2-1.8-4.8-4.6-4.8-8.3c0-11.8,0-23.6,0-35.5C9.8,30.2,10.3,28.4,11.8,26.4z"/>
<path d="M87.9,73.8c0.6-2.3-0.5-3.5-1.9-4.6c-9-7.4-17.9-14.7-26.8-22.1c-2.9-2.4-3.1-3.6-1.1-6.7c4.3-6.6,8.7-13.2,13-19.8c1.7-2.6,3.3-2.9,6-1.4c2.8,1.6,5.6,3.2,8.3,4.8c3.2,1.8,4.7,4.5,4.7,8.2c0,11.9,0,23.7,0,35.6C90.2,69.9,89.6,71.9,87.9,73.8z"/>
<path d="M67.1,56.8c0.6,0.4,17.3,14.1,17.5,14.3c2.4,2.2,2.2,4.1-0.6,5.8C76.8,81,57.3,92.1,54.8,93.6c-3.2,1.9-6.4,1.9-9.6,0c-4.6-2.7-9.2-5.3-13.8-8c-2.2-1.3-2.2-2.7,0-3.9C42.3,75.5,53.1,69.2,64,63C66.5,61.6,68.2,60.1,67.1,56.8z"/>
@@ -213,7 +215,7 @@
<rect x="816" y="60" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="66" width="18" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="833" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">BI</text>
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="66" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="884" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
@@ -224,7 +226,7 @@
<rect x="816" y="152" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="158" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="835" y="167" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">NB</text>
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="158" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="884" y="194" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">JupyterLab</text>
@@ -235,7 +237,7 @@
<rect x="816" y="244" width="136" height="56" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="824" y="250" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
<text x="840" y="259" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">PROC</text>
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="872" y="250" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"/>
</svg>
<text x="884" y="286" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Python</text>
@@ -15,7 +15,9 @@
<div class="frame">
<p class="eyebrow">DP Integration · Diagram Design</p>
<h1>Generic data platform integration topology</h1>
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces">
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces" role="img" aria-labelledby="dp-integration-dark-title dp-integration-dark-desc">
<title id="dp-integration-dark-title">Generic data platform integration topology</title>
<desc id="dp-integration-dark-desc">Integration topology showing CRM, POS exports, and an event stream landing in object storage for query, notebooks, dashboards, and a partner API.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -18,7 +18,9 @@
<h1>Generic data platform integration topology</h1>
<p class="subtitle">Three source patterns land in shared object storage, a query surface serves three consumer modes, and platform-wide services remain visibly cross-cutting.</p>
<div class="diagram-container">
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces">
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces" role="img" aria-labelledby="dp-integration-full-title dp-integration-full-desc">
<title id="dp-integration-full-title">Generic data platform integration topology</title>
<desc id="dp-integration-full-desc">Integration topology showing CRM, POS exports, and an event stream landing in object storage for query, notebooks, dashboards, and a partner API.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -15,7 +15,9 @@
<div class="frame">
<p class="eyebrow">DP Integration · Diagram Design</p>
<h1>Generic data platform integration topology</h1>
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces">
<svg viewBox="0 0 1200 664" xmlns="http://www.w3.org/2000/svg" aria-label="Sources connect to a core data platform and three consumer surfaces" role="img" aria-labelledby="dp-integration-title dp-integration-desc">
<title id="dp-integration-title">Generic data platform integration topology</title>
<desc id="dp-integration-desc">Integration topology showing CRM, POS exports, and an event stream landing in object storage for query, notebooks, dashboards, and a partner API.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -16,8 +16,8 @@
</style>
</head>
<body><main class="frame"><p class="eyebrow">DP security matrix · Diagram Design</p><h1>Data platform access matrix</h1><p class="subtitle">Five operating roles × five platform components, expressed as admin, write, read, or none.</p><div class="diagram">
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="matrix-dark-title matrix-dark-desc" xmlns="http://www.w3.org/2000/svg">
<title id="matrix-dark-title">Data platform access matrix</title><desc id="matrix-dark-desc">A five by five permission matrix for platform roles and components.</desc><rect width="1084" height="400" fill="#2d3142"/>
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="dp-security-matrix-dark-title dp-security-matrix-dark-desc" xmlns="http://www.w3.org/2000/svg">
<title id="dp-security-matrix-dark-title">Data platform access matrix</title><desc id="dp-security-matrix-dark-desc">A five by five permission matrix for platform roles and components.</desc><rect width="1084" height="400" fill="#2d3142"/>
<rect class="component-head" x="12" y="72" width="208" height="52" rx="6"/><text class="head-name" x="116" y="96" text-anchor="middle">Component</text><text class="head-sub" x="116" y="112" text-anchor="middle">vs. AD group</text>
<rect class="role" x="232" y="72" width="148" height="52" rx="6"/><text class="role-name" x="306" y="92" text-anchor="middle">Data Engineer</text><text class="role-code" x="306" y="108" text-anchor="middle">GRP-DATA-ENG</text><rect class="role" x="396" y="72" width="148" height="52" rx="6"/><text class="role-name" x="470" y="92" text-anchor="middle">Data Scientist</text><text class="role-code" x="470" y="108" text-anchor="middle">GRP-DATA-SCI</text><rect class="role" x="560" y="72" width="148" height="52" rx="6"/><text class="role-name" x="634" y="92" text-anchor="middle">Analyst</text><text class="role-code" x="634" y="108" text-anchor="middle">GRP-ANALYST</text><rect class="role" x="724" y="72" width="148" height="52" rx="6"/><text class="role-name" x="798" y="92" text-anchor="middle">Administrator</text><text class="role-code" x="798" y="108" text-anchor="middle">GRP-ADMIN</text><rect class="role" x="888" y="72" width="148" height="52" rx="6"/><text class="role-name" x="962" y="92" text-anchor="middle">External Partner</text><text class="role-code" x="962" y="108" text-anchor="middle">GRP-PARTNER</text>
<rect class="component" x="12" y="140" width="208" height="36" rx="4"/><text class="component-name" x="24" y="162">Object storage</text><text class="hint" x="208" y="162" text-anchor="end">S3</text><rect class="cell write" x="232" y="140" width="148" height="36" rx="4"/><text class="value write-text" x="306" y="162" text-anchor="middle">Write</text><rect class="cell read" x="396" y="140" width="148" height="36" rx="4"/><text class="value read-text" x="470" y="162" text-anchor="middle">Read</text><rect class="cell none" x="560" y="140" width="148" height="36" rx="4"/><text class="value none-text" x="634" y="162" text-anchor="middle">None</text><rect class="cell full" x="724" y="140" width="148" height="36" rx="4"/><text class="value full-text" x="798" y="162" text-anchor="middle">Admin</text><rect class="cell none" x="888" y="140" width="148" height="36" rx="4"/><text class="value none-text" x="962" y="162" text-anchor="middle">None</text>
@@ -14,8 +14,8 @@
</style>
</head>
<body><main class="container"><header class="header"><p class="header-eyebrow">DP security matrix · Diagram Design</p><h1>Data platform access matrix</h1><p class="subtitle">A compact policy view for five human roles across storage, query, analysis, reporting, and orchestration. Each intersection resolves to one explicit permission level.</p></header><div class="diagram-container">
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="matrix-full-title matrix-full-desc" xmlns="http://www.w3.org/2000/svg">
<title id="matrix-full-title">Data platform access matrix</title><desc id="matrix-full-desc">A five by five permission matrix for platform roles and components.</desc><rect width="1084" height="400" fill="#f5f5f5"/>
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="dp-security-matrix-full-title dp-security-matrix-full-desc" xmlns="http://www.w3.org/2000/svg">
<title id="dp-security-matrix-full-title">Data platform access matrix</title><desc id="dp-security-matrix-full-desc">A five by five permission matrix for platform roles and components.</desc><rect width="1084" height="400" fill="#f5f5f5"/>
<rect class="component-head" x="12" y="72" width="208" height="52" rx="6"/><text class="head-name" x="116" y="96" text-anchor="middle">Component</text><text class="head-sub" x="116" y="112" text-anchor="middle">vs. AD group</text>
<rect class="role" x="232" y="72" width="148" height="52" rx="6"/><text class="role-name" x="306" y="92" text-anchor="middle">Data Engineer</text><text class="role-code" x="306" y="108" text-anchor="middle">GRP-DATA-ENG</text><rect class="role" x="396" y="72" width="148" height="52" rx="6"/><text class="role-name" x="470" y="92" text-anchor="middle">Data Scientist</text><text class="role-code" x="470" y="108" text-anchor="middle">GRP-DATA-SCI</text><rect class="role" x="560" y="72" width="148" height="52" rx="6"/><text class="role-name" x="634" y="92" text-anchor="middle">Analyst</text><text class="role-code" x="634" y="108" text-anchor="middle">GRP-ANALYST</text><rect class="role" x="724" y="72" width="148" height="52" rx="6"/><text class="role-name" x="798" y="92" text-anchor="middle">Administrator</text><text class="role-code" x="798" y="108" text-anchor="middle">GRP-ADMIN</text><rect class="role" x="888" y="72" width="148" height="52" rx="6"/><text class="role-name" x="962" y="92" text-anchor="middle">External Partner</text><text class="role-code" x="962" y="108" text-anchor="middle">GRP-PARTNER</text>
<rect class="component" x="12" y="140" width="208" height="36" rx="4"/><text class="component-name" x="24" y="162">Object storage</text><text class="hint" x="208" y="162" text-anchor="end">S3</text><rect class="cell write" x="232" y="140" width="148" height="36" rx="4"/><text class="value write-text" x="306" y="162" text-anchor="middle">Write</text><rect class="cell read" x="396" y="140" width="148" height="36" rx="4"/><text class="value read-text" x="470" y="162" text-anchor="middle">Read</text><rect class="cell none" x="560" y="140" width="148" height="36" rx="4"/><text class="value none-text" x="634" y="162" text-anchor="middle">None</text><rect class="cell full" x="724" y="140" width="148" height="36" rx="4"/><text class="value full-text" x="798" y="162" text-anchor="middle">Admin</text><rect class="cell none" x="888" y="140" width="148" height="36" rx="4"/><text class="value none-text" x="962" y="162" text-anchor="middle">None</text>
@@ -26,8 +26,8 @@
<main class="frame">
<p class="eyebrow">DP security matrix · Diagram Design</p><h1>Data platform access matrix</h1><p class="subtitle">Five operating roles × five platform components, expressed as admin, write, read, or none.</p>
<div class="diagram">
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="matrix-title matrix-desc" xmlns="http://www.w3.org/2000/svg">
<title id="matrix-title">Data platform access matrix</title><desc id="matrix-desc">A five by five permission matrix for platform roles and components.</desc>
<svg viewBox="0 0 1084 400" role="img" aria-labelledby="dp-security-matrix-title dp-security-matrix-desc" xmlns="http://www.w3.org/2000/svg">
<title id="dp-security-matrix-title">Data platform access matrix</title><desc id="dp-security-matrix-desc">A five by five permission matrix for platform roles and components.</desc>
<rect width="1084" height="400" fill="#f5f5f5"/>
<!-- Header: y=72, h=52; role x positions derive from the 148px column formula -->
@@ -58,7 +58,9 @@
<p class="eyebrow">ER · Diagram Design</p>
<h1>Content platform · data model</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="er-dark-title er-dark-desc">
<title id="er-dark-title">Content platform · data model</title>
<desc id="er-dark-desc">Entity-relationship diagram showing authors writing articles and articles connecting to tags and categories.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="er-full-title er-full-desc">
<title id="er-full-title">Content platform · data model</title>
<desc id="er-full-desc">Entity-relationship diagram showing authors writing articles and articles connecting to tags and categories.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
+3 -1
View File
@@ -58,7 +58,9 @@
<p class="eyebrow">ER · Diagram Design</p>
<h1>Content platform · data model</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="er-title er-desc">
<title id="er-title">Content platform · data model</title>
<desc id="er-desc">Entity-relationship diagram showing authors writing articles and articles connecting to tags and categories.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Flowchart · Diagram Design</p>
<h1>Should you write this as a skill?</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flowchart-dark-title flowchart-dark-desc">
<title id="flowchart-dark-title">Should you write this as a skill?</title>
<desc id="flowchart-dark-desc">Flowchart showing when a new workflow should stay manual, become a project note, or be written as a reusable skill.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flowchart-full-title flowchart-full-desc">
<title id="flowchart-full-title">Should you write this as a skill?</title>
<desc id="flowchart-full-desc">Flowchart showing when a new workflow should stay manual, become a project note, or be written as a reusable skill.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Flowchart · Diagram Design</p>
<h1>Should you write this as a skill?</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="flowchart-title flowchart-desc">
<title id="flowchart-title">Should you write this as a skill?</title>
<desc id="flowchart-desc">Flowchart showing when a new workflow should stay manual, become a project note, or be written as a reusable skill.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -24,7 +24,9 @@
<!-- Rows: label col x=20-196, timeline x=200-956 -->
<!-- Row height=40, bar h=24, bar top pad=8 -->
<!-- Week x = 200 + i*63, i=0..12 -->
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="gantt-dark-title gantt-dark-desc">
<title id="gantt-dark-title">Q2 product launch · 12-week plan</title>
<desc id="gantt-dark-desc">Gantt chart showing a twelve-week product launch from market research and interviews through design review, development, beta testing, and launch.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -36,7 +36,9 @@
<p class="subtitle">Three phases from research through launch. Design review in week 8 is the critical gate — development doesn't continue until sign-off.</p>
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="gantt-full-title gantt-full-desc">
<title id="gantt-full-title">Q2 product launch · 12-week plan</title>
<desc id="gantt-full-desc">Gantt chart showing a twelve-week product launch from market research and interviews through design review, development, beta testing, and launch.</desc>
<defs><pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern></defs>
<rect width="100%" height="100%" fill="#f5f5f5"/>
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
@@ -24,7 +24,9 @@
<!-- Rows: label col x=20-196, timeline x=200-956 -->
<!-- Row height=40, bar h=24, bar top pad=8 -->
<!-- Week x = 200 + i*63, i=0..12 -->
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="gantt-title gantt-desc">
<title id="gantt-title">Q2 product launch · 12-week plan</title>
<desc id="gantt-desc">Gantt chart showing a twelve-week product launch from market research and interviews through design review, development, beta testing, and launch.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>High-level architecture · End-to-end stack</h1>
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-dark-title high-level-dark-desc">
<title id="high-level-dark-title">High-level architecture · End-to-end stack</title>
<desc id="high-level-dark-desc">Architecture diagram showing data sources moving through Apache NiFi and MinIO into Trino, data modeling, and Superset dashboards, with Airflow orchestration.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -110,7 +112,7 @@
<rect x="12" y="60" width="132" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="20" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="31" y="75" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="9"/>
<path d="M3.6 9h16.8M3.6 15h16.8"/>
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/>
@@ -122,7 +124,7 @@
<rect x="12" y="140" width="132" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="20" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="31" y="155" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>
<path d="M7 9l5 -5l5 5"/><path d="M12 4l0 12"/>
</svg>
@@ -133,7 +135,7 @@
<rect x="12" y="220" width="132" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="20" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="31" y="235" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -145,7 +147,7 @@
<rect x="12" y="304" width="132" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="20" y="310" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="31" y="319" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -155,7 +157,7 @@
<!-- Airflow bar -->
<rect x="176" y="52" width="808" height="44" rx="4" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.18)" stroke-width="0.8"/>
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#bfc0c0">
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#bfc0c0" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="564" y="71" fill="#f5f5f5" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
@@ -165,7 +167,7 @@
<rect x="176" y="112" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="184" y="118" width="30" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="199" y="127" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/>
</svg>
<text x="252" y="154" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -175,7 +177,7 @@
<rect x="372" y="104" width="160" height="72" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="380" y="110" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="394" y="119" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="452" y="146" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -185,7 +187,7 @@
<rect x="372" y="208" width="160" height="80" rx="8" fill="rgba(240,138,89,0.12)" stroke="#f08a59" stroke-width="1.2"/>
<rect x="380" y="214" width="36" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.55)" stroke-width="0.8"/>
<text x="398" y="223" fill="rgba(240,138,89,0.85)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59">
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="452" y="252" fill="#f08a59" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
@@ -195,7 +197,7 @@
<rect x="600" y="144" width="164" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="608" y="150" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="624" y="159" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="682" y="186" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Data Modeling</text>
@@ -205,14 +207,14 @@
<rect x="820" y="144" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="828" y="150" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.25)" stroke-width="0.8"/>
<text x="842" y="159" fill="rgba(245,245,245,0.45)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="896" y="186" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Dashboards</text>
<text x="896" y="198" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Superset · reports</text>
<!-- Kubernetes label -->
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/>
<circle cx="12" cy="12" r="3"/>
<line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/>
@@ -222,7 +224,7 @@
<text x="204" y="362" fill="#bfc0c0" font-size="8" font-weight="500" font-family="'Geist', sans-serif">Kubernetes</text>
<!-- Identity Manager -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1-8.5 15a12 12 0 0 1-8.5-15a12 12 0 0 0 8.5-3"/>
<circle cx="12" cy="11" r="1" fill="#bfc0c0"/>
<line x1="12" y1="12" x2="12" y2="14.5"/>
@@ -41,7 +41,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-full-title high-level-full-desc">
<title id="high-level-full-title">High-level architecture · End-to-end stack</title>
<desc id="high-level-full-desc">Architecture diagram showing data sources moving through Apache NiFi and MinIO into Trino, data modeling, and Superset dashboards, with Airflow orchestration.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -98,34 +100,34 @@
<rect x="12" y="60" width="132" height="64" rx="6" fill="#f5f5f5"/><rect x="12" y="60" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M3.6 9h16.8M3.6 15h16.8"/><path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/></svg>
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M3.6 9h16.8M3.6 15h16.8"/><path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/></svg>
<text x="78" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">WEB</text>
<text x="78" y="114" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Census · Survey · Admin</text>
<rect x="12" y="140" width="132" height="64" rx="6" fill="#f5f5f5"/><rect x="12" y="140" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="155" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><path d="M7 9l5 -5l5 5"/><path d="M12 4l0 12"/></svg>
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><path d="M7 9l5 -5l5 5"/><path d="M12 4l0 12"/></svg>
<text x="78" y="182" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">FTP</text>
<text x="78" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Census · Business</text>
<rect x="12" y="220" width="132" height="64" rx="6" fill="#f5f5f5"/><rect x="12" y="220" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="235" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/><path d="M4 6v6a8 3 0 0 0 16 0v-6"/><path d="M4 12v6a8 3 0 0 0 16 0v-6"/></svg>
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/><path d="M4 6v6a8 3 0 0 0 16 0v-6"/><path d="M4 12v6a8 3 0 0 0 16 0v-6"/></svg>
<text x="78" y="262" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">DB Connection</text>
<text x="78" y="274" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">CDC · SQL · API</text>
<rect x="12" y="304" width="132" height="64" rx="6" fill="#f5f5f5"/><rect x="12" y="304" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="310" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="319" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/><path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/><path d="M7 8l0 .01"/><path d="M7 16l0 .01"/></svg>
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/><path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/><path d="M7 8l0 .01"/><path d="M7 16l0 .01"/></svg>
<text x="78" y="346" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Legacy System</text>
<text x="78" y="358" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Trade data</text>
<!-- Airflow bar -->
<rect x="176" y="52" width="808" height="44" rx="4" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.18)" stroke-width="0.8"/>
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75"><path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/></svg>
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75" aria-hidden="true"><path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/></svg>
<text x="564" y="71" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
<text x="564" y="84" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">(Apache Airflow)</text>
@@ -133,7 +135,7 @@
<rect x="176" y="112" width="152" height="80" rx="6" fill="#f5f5f5"/><rect x="176" y="112" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="184" y="118" width="30" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="199" y="127" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/></svg>
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/></svg>
<text x="252" y="154" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
<text x="252" y="166" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Collect · route · transform</text>
@@ -141,7 +143,7 @@
<rect x="372" y="104" width="160" height="72" rx="6" fill="#f5f5f5"/><rect x="372" y="104" width="160" height="72" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="380" y="110" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="394" y="119" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/></svg>
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/></svg>
<text x="452" y="146" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
<text x="452" y="158" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">SQL · data virtualization</text>
@@ -149,7 +151,7 @@
<rect x="372" y="208" width="160" height="80" rx="8" fill="#f5f5f5"/><rect x="372" y="208" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="380" y="214" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="398" y="223" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36"><path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/></svg>
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true"><path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/></svg>
<text x="452" y="252" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
<text x="452" y="268" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" opacity="0.75">Object store · S3-API</text>
@@ -157,7 +159,7 @@
<rect x="600" y="144" width="164" height="80" rx="6" fill="#f5f5f5"/><rect x="600" y="144" width="164" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="608" y="150" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="624" y="159" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/></svg>
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/></svg>
<text x="682" y="186" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Data Modeling</text>
<text x="682" y="198" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Notebook · Python · R</text>
@@ -165,16 +167,16 @@
<rect x="820" y="144" width="152" height="80" rx="6" fill="#f5f5f5"/><rect x="820" y="144" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="828" y="150" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="842" y="159" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/></svg>
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/></svg>
<text x="896" y="186" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Dashboards</text>
<text x="896" y="198" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Superset · reports</text>
<!-- Kubernetes label -->
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/><circle cx="12" cy="12" r="3"/><line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/><line x1="20.2" y1="7.5" x2="14.9" y2="10.5"/><line x1="9.1" y1="13.5" x2="3.8" y2="16.5"/><line x1="20.2" y1="16.5" x2="14.9" y2="13.5"/><line x1="9.1" y1="10.5" x2="3.8" y2="7.5"/></svg>
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/><circle cx="12" cy="12" r="3"/><line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/><line x1="20.2" y1="7.5" x2="14.9" y2="10.5"/><line x1="9.1" y1="13.5" x2="3.8" y2="16.5"/><line x1="20.2" y1="16.5" x2="14.9" y2="13.5"/><line x1="9.1" y1="10.5" x2="3.8" y2="7.5"/></svg>
<text x="204" y="362" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist', sans-serif">Kubernetes</text>
<!-- Identity Manager -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1-8.5 15a12 12 0 0 1-8.5-15a12 12 0 0 0 8.5-3"/><circle cx="12" cy="11" r="1" fill="#4f5d75"/><line x1="12" y1="12" x2="12" y2="14.5"/></svg>
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1-8.5 15a12 12 0 0 1-8.5-15a12 12 0 0 0 8.5-3"/><circle cx="12" cy="11" r="1" fill="#4f5d75"/><line x1="12" y1="12" x2="12" y2="14.5"/></svg>
<text x="500" y="410" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Identity Manager</text>
<text x="500" y="422" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">(Active Directory)</text>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design · Parametric</p>
<h1>High-level architecture · Vertical Orchestration + Security</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-vertical-dark-title high-level-vertical-dark-desc">
<title id="high-level-vertical-dark-title">High-level architecture · Vertical Orchestration + Security</title>
<desc id="high-level-vertical-dark-desc">Architecture diagram showing data sources moving through ingestion, storage, transformation, and visualization alongside orchestration, security, and observability.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -122,7 +124,7 @@
<rect x="8" y="60" width="176" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="16" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="27" y="75" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -133,7 +135,7 @@
<rect x="8" y="140" width="176" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="16" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="27" y="155" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>
<path d="M7 9l5 -5l5 5"/>
<path d="M12 4l0 12"/>
@@ -144,7 +146,7 @@
<rect x="8" y="220" width="176" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="16" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="27" y="235" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="9"/>
<path d="M3.6 9h16.8M3.6 15h16.8"/>
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/>
@@ -155,7 +157,7 @@
<rect x="8" y="300" width="176" height="64" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="16" y="306" width="22" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="27" y="315" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f5f5f5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -165,7 +167,7 @@
<!-- Airflow bar -->
<rect x="208" y="52" width="744" height="44" rx="4" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.18)" stroke-width="0.8"/>
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#bfc0c0">
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#bfc0c0" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="580" y="71" fill="#f5f5f5" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
@@ -175,7 +177,7 @@
<rect x="212" y="120" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="220" y="126" width="30" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="235" y="135" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0z"/>
</svg>
<text x="288" y="166" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -184,7 +186,7 @@
<rect x="404" y="120" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="412" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="426" y="135" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075z"/>
</svg>
<text x="480" y="166" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -194,7 +196,7 @@
<rect x="404" y="216" width="152" height="80" rx="8" fill="rgba(240,138,89,0.12)" stroke="#f08a59" stroke-width="1.2"/>
<rect x="412" y="222" width="36" height="12" rx="2" fill="transparent" stroke="rgba(240,138,89,0.55)" stroke-width="0.8"/>
<text x="430" y="231" fill="rgba(240,138,89,0.95)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59">
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#f08a59" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Z"/>
</svg>
<text x="480" y="262" fill="#f08a59" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
@@ -203,7 +205,7 @@
<rect x="596" y="120" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="604" y="126" width="32" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="620" y="135" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="672" y="166" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Notebooks</text>
@@ -212,14 +214,14 @@
<rect x="790" y="120" width="152" height="80" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
<rect x="798" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
<text x="812" y="135" fill="rgba(245,245,245,0.65)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5">
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#f5f5f5" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="866" y="166" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
<text x="866" y="178" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Dashboards · reports</text>
<!-- Kubernetes label -->
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/>
<circle cx="12" cy="12" r="3"/>
<line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/>
@@ -229,7 +231,7 @@
<text x="236" y="362" fill="#bfc0c0" font-size="8" font-weight="500" font-family="'Geist', sans-serif">Kubernetes</text>
<!-- Cross-cutting bar #1 — Identity (Security row, y=388..428, color=#d97a78 lightened red for dark mode) -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#d97a78">
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#d97a78" aria-hidden="true">
<path d="M12.0001.0036C5.376.0036 0 5.3796 0 12.0036c0 6.6276 5.376 12 12.0001 12 6.6275 0 12-5.3724 12-12 0-6.624-5.3725-12-12-12zm5.532 17.0496c-.612 0-3.972-3.144-5.532-5.046C10.452 13.9356 7.092 17.0796 6.48 17.0796c-1.788 0-2.052-3.564-2.052-5.076 0-1.512.264-5.076 2.052-5.076.612 0 3.972 3.144 5.5201 5.046 1.548-1.932 4.908-5.046 5.532-5.046 1.788 0 2.052 3.564 2.052 5.076 0 1.512-.264 5.076-2.052 5.076z"/>
</svg>
<text x="484" y="410" fill="#d97a78" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Identity Manager</text>
@@ -237,7 +239,7 @@
<!-- Cross-cutting bar #2 — Monitoring (Observability row, y=432..472) -->
<rect x="4" y="432" width="960" height="40" rx="6" fill="rgba(245,245,245,0.06)" stroke="rgba(245,245,245,0.18)" stroke-width="0.8"/>
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#bfc0c0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 3v18h18"/>
<path d="M7 14l3-3 2 2 5-5"/>
<path d="M14 8h3v3"/>
@@ -41,7 +41,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-vertical-full-title high-level-vertical-full-desc">
<title id="high-level-vertical-full-title">High-level architecture · Vertical Orchestration + Security</title>
<desc id="high-level-vertical-full-desc">Architecture diagram showing data sources moving through ingestion, storage, transformation, and visualization alongside orchestration, security, and observability.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -99,34 +101,34 @@
<rect x="8" y="60" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/><path d="M4 6v6a8 3 0 0 0 16 0v-6"/><path d="M4 12v6a8 3 0 0 0 16 0v-6"/></svg>
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/><path d="M4 6v6a8 3 0 0 0 16 0v-6"/><path d="M4 12v6a8 3 0 0 0 16 0v-6"/></svg>
<text x="96" y="102" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">PostgreSQL</text>
<text x="96" y="114" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">CDC · SQL · API</text>
<rect x="8" y="140" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="155" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><path d="M7 9l5 -5l5 5"/><path d="M12 4l0 12"/></svg>
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><path d="M7 9l5 -5l5 5"/><path d="M12 4l0 12"/></svg>
<text x="96" y="182" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">SFTP drop</text>
<text x="96" y="194" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Batch · landing</text>
<rect x="8" y="220" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="235" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M3.6 9h16.8M3.6 15h16.8"/><path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/></svg>
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M3.6 9h16.8M3.6 15h16.8"/><path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/></svg>
<text x="96" y="262" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Web forms</text>
<text x="96" y="274" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Survey · admin</text>
<rect x="8" y="300" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="306" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="315" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/><path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/><path d="M7 8l0 .01"/><path d="M7 16l0 .01"/></svg>
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/><path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/><path d="M7 8l0 .01"/><path d="M7 16l0 .01"/></svg>
<text x="96" y="342" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Legacy system</text>
<text x="96" y="354" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Trade · mainframe</text>
<!-- Airflow bar -->
<rect x="208" y="52" width="744" height="44" rx="4" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.18)" stroke-width="0.8"/>
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75"><path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/></svg>
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75" aria-hidden="true"><path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/></svg>
<text x="580" y="71" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
<text x="580" y="84" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">(Apache Airflow)</text>
@@ -134,50 +136,50 @@
<rect x="212" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="220" y="126" width="30" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="235" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0z"/></svg>
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0z"/></svg>
<text x="288" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
<text x="288" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Collect · route · transform</text>
<rect x="404" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="412" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="426" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075z"/></svg>
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075z"/></svg>
<text x="480" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
<text x="480" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">SQL · data virtualization</text>
<rect x="404" y="216" width="152" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="412" y="222" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="430" y="231" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36"><path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Z"/></svg>
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true"><path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Z"/></svg>
<text x="480" y="262" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
<text x="480" y="276" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" opacity="0.75">Object store · S3-API</text>
<rect x="596" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="604" y="126" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="620" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424z"/></svg>
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424z"/></svg>
<text x="672" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Notebooks</text>
<text x="672" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Jupyter · Python · R</text>
<rect x="790" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="798" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="812" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142"><path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/></svg>
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true"><path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/></svg>
<text x="866" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
<text x="866" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Dashboards · reports</text>
<!-- Kubernetes label -->
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/><circle cx="12" cy="12" r="3"/><line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/><line x1="20.2" y1="7.5" x2="14.9" y2="10.5"/><line x1="9.1" y1="13.5" x2="3.8" y2="16.5"/><line x1="20.2" y1="16.5" x2="14.9" y2="13.5"/><line x1="9.1" y1="10.5" x2="3.8" y2="7.5"/></svg>
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/><circle cx="12" cy="12" r="3"/><line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/><line x1="20.2" y1="7.5" x2="14.9" y2="10.5"/><line x1="9.1" y1="13.5" x2="3.8" y2="16.5"/><line x1="20.2" y1="16.5" x2="14.9" y2="13.5"/><line x1="9.1" y1="10.5" x2="3.8" y2="7.5"/></svg>
<text x="236" y="362" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist', sans-serif">Kubernetes</text>
<!-- Cross-cutting bar #1 — Identity (color=#b85450 rust-red) -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#b85450"><path d="M12.0001.0036C5.376.0036 0 5.3796 0 12.0036c0 6.6276 5.376 12 12.0001 12 6.6275 0 12-5.3724 12-12 0-6.624-5.3725-12-12-12zm5.532 17.0496c-.612 0-3.972-3.144-5.532-5.046C10.452 13.9356 7.092 17.0796 6.48 17.0796c-1.788 0-2.052-3.564-2.052-5.076 0-1.512.264-5.076 2.052-5.076.612 0 3.972 3.144 5.5201 5.046 1.548-1.932 4.908-5.046 5.532-5.046 1.788 0 2.052 3.564 2.052 5.076 0 1.512-.264 5.076-2.052 5.076z"/></svg>
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#b85450" aria-hidden="true"><path d="M12.0001.0036C5.376.0036 0 5.3796 0 12.0036c0 6.6276 5.376 12 12.0001 12 6.6275 0 12-5.3724 12-12 0-6.624-5.3725-12-12-12zm5.532 17.0496c-.612 0-3.972-3.144-5.532-5.046C10.452 13.9356 7.092 17.0796 6.48 17.0796c-1.788 0-2.052-3.564-2.052-5.076 0-1.512.264-5.076 2.052-5.076.612 0 3.972 3.144 5.5201 5.046 1.548-1.932 4.908-5.046 5.532-5.046 1.788 0 2.052 3.564 2.052 5.076 0 1.512-.264 5.076-2.052 5.076z"/></svg>
<text x="484" y="410" fill="#b85450" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Identity Manager</text>
<text x="484" y="422" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">(Keycloak · LDAP · OIDC)</text>
<!-- Cross-cutting bar #2 — Monitoring -->
<rect x="4" y="432" width="960" height="40" rx="6" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.20)" stroke-width="0.8"/>
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="M7 14l3-3 2 2 5-5"/><path d="M14 8h3v3"/></svg>
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="M7 14l3-3 2 2 5-5"/><path d="M14 8h3v3"/></svg>
<text x="484" y="454" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Monitoring &amp; Observability</text>
<text x="484" y="466" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">(Prometheus · Grafana · Loki)</text>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design · Parametric</p>
<h1>High-level architecture · Vertical Orchestration + Security</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-vertical-title high-level-vertical-desc">
<title id="high-level-vertical-title">High-level architecture · Vertical Orchestration + Security</title>
<desc id="high-level-vertical-desc">Architecture diagram showing data sources moving through ingestion, storage, transformation, and visualization alongside orchestration, security, and observability.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -155,7 +157,7 @@
<rect x="8" y="60" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -167,7 +169,7 @@
<rect x="8" y="140" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="155" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>
<path d="M7 9l5 -5l5 5"/>
<path d="M12 4l0 12"/>
@@ -179,7 +181,7 @@
<rect x="8" y="220" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="235" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="9"/>
<path d="M3.6 9h16.8M3.6 15h16.8"/>
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/>
@@ -191,7 +193,7 @@
<rect x="8" y="300" width="176" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="16" y="306" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="27" y="315" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="62" y="306" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -203,7 +205,7 @@
AIRFLOW BAR (Orchestration, x=208 y=52 w=744 h=44 — 12-px inside cluster on both sides)
═══════════════════════════════════════════ -->
<rect x="208" y="52" width="744" height="44" rx="4" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.18)" stroke-width="0.8"/>
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75">
<svg x="914" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="580" y="71" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
@@ -217,7 +219,7 @@
<rect x="212" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="220" y="126" width="30" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="235" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="332" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947z"/>
</svg>
<text x="288" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -227,7 +229,7 @@
<rect x="404" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="412" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="426" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="524" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="480" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -237,7 +239,7 @@
<rect x="404" y="216" width="152" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="412" y="222" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="430" y="231" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36">
<svg x="524" y="222" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="480" y="262" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
@@ -247,7 +249,7 @@
<rect x="596" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="604" y="126" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="620" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="716" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="672" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Notebooks</text>
@@ -257,14 +259,14 @@
<rect x="790" y="120" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="798" y="126" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="812" y="135" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="910" y="126" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="866" y="166" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Superset</text>
<text x="866" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Dashboards · reports</text>
<!-- ── Kubernetes label (bottom-left of cluster) ── -->
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="212" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/>
<circle cx="12" cy="12" r="3"/>
<line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/>
@@ -276,7 +278,7 @@
<!-- ═══════════════════════════════════════════
CROSS-CUTTING BAR #1 — Identity (Security, y=388..428, color=#b85450)
═══════════════════════════════════════════ -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#b85450">
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="#b85450" aria-hidden="true">
<path d="M12.0001.0036C5.376.0036 0 5.3796 0 12.0036c0 6.6276 5.376 12 12.0001 12 6.6275 0 12-5.3724 12-12 0-6.624-5.3725-12-12-12zm5.532 17.0496c-.612 0-3.972-3.144-5.532-5.046C10.452 13.9356 7.092 17.0796 6.48 17.0796c-1.788 0-2.052-3.564-2.052-5.076 0-1.512.264-5.076 2.052-5.076.612 0 3.972 3.144 5.5201 5.046 1.548-1.932 4.908-5.046 5.532-5.046 1.788 0 2.052 3.564 2.052 5.076 0 1.512-.264 5.076-2.052 5.076z"/>
</svg>
<text x="484" y="410" fill="#b85450" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Identity Manager</text>
@@ -286,7 +288,7 @@
CROSS-CUTTING BAR #2 — Monitoring (Observability, y=432..472)
═══════════════════════════════════════════ -->
<rect x="4" y="432" width="960" height="40" rx="6" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.20)" stroke-width="0.8"/>
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="16" y="442" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 3v18h18"/>
<path d="M7 14l3-3 2 2 5-5"/>
<path d="M14 8h3v3"/>
@@ -52,7 +52,9 @@
<p class="eyebrow">Architecture · Diagram Design</p>
<h1>High-level architecture · End-to-end stack</h1>
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="high-level-title high-level-desc">
<title id="high-level-title">High-level architecture · End-to-end stack</title>
<desc id="high-level-desc">Architecture diagram showing data sources moving through Apache NiFi and MinIO into Trino, data modeling, and Superset dashboards, with Airflow orchestration.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -144,7 +146,7 @@
<rect x="12" y="60" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="66" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="75" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="66" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="9"/>
<path d="M3.6 9h16.8M3.6 15h16.8"/>
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18"/>
@@ -157,7 +159,7 @@
<rect x="12" y="140" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="146" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="155" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="146" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>
<path d="M7 9l5 -5l5 5"/>
<path d="M12 4l0 12"/>
@@ -170,7 +172,7 @@
<rect x="12" y="220" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="226" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="235" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="226" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0"/>
<path d="M4 6v6a8 3 0 0 0 16 0v-6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
@@ -183,7 +185,7 @@
<rect x="12" y="304" width="132" height="64" rx="6" fill="white" stroke="rgba(45,49,66,0.22)" stroke-width="1"/>
<rect x="20" y="310" width="22" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="31" y="319" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">EXT</text>
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="66" y="310" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2d3142" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 7a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3"/>
<path d="M3 15a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3l0 -2"/>
<path d="M7 8l0 .01"/><path d="M7 16l0 .01"/>
@@ -193,7 +195,7 @@
<!-- ── Airflow orchestration bar ── -->
<rect x="176" y="52" width="808" height="44" rx="4" fill="rgba(45,49,66,0.05)" stroke="rgba(45,49,66,0.18)" stroke-width="0.8"/>
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75">
<svg x="950" y="58" width="24" height="24" viewBox="0 0 24 24" fill="#4f5d75" aria-hidden="true">
<path d="M17.195 16.822l4.002-4.102C23.55 10.308 23.934 5.154 24 .43a.396.396 0 0 0-.246-.373.392.392 0 0 0-.437.09l-6.495 6.658-4.102-4.003C10.309.45 5.154.066.43 0H.423a.397.397 0 0 0-.277.683l6.658 6.494-4.003 4.103C.45 13.692.065 18.846 0 23.57a.398.398 0 0 0 .683.282l6.494-6.657 3.934 3.837.17.165c2.41 2.353 7.565 2.737 12.288 2.803h.006a.397.397 0 0 0 .277-.683l-6.657-6.495z"/>
</svg>
<text x="564" y="71" fill="#2d3142" font-size="10" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orchestration / Workflow Automation</text>
@@ -204,7 +206,7 @@
<rect x="176" y="112" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="184" y="118" width="30" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="199" y="127" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">COLL</text>
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="240" y="118" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M11.648 0a.093.093 0 0 0-.084.053A30.71 30.71 0 0 1 8.592 4.73c-2.09 2.728-5.145 6.466-5.145 10.364a8.201 8.201 0 0 0 8.201 8.2v-5.003c0-.106.087-.193.194-.193h2.81v-2.813c0-.106.087-.191.194-.191h5.004c0-3.9-3.056-7.636-5.145-10.364A30.712 30.712 0 0 1 11.732.053.094.094 0 0 0 11.648 0zm-1.632 3.867c.05 0 .08.034.037.112-.11.197-.218.397-.328.593-.396.702-.819 1.389-1.23 2.08-.196-.032-.39-.06-.585-.088.495-.651 1-1.296 1.48-1.959.153-.209.302-.423.454-.634a.24.24 0 0 1 .172-.104zM7.44 7.186c.221.035.444.076.666.119-.073.129-.15.256-.223.383a29.073 29.073 0 0 0-1.625 3.261c-.874 2.123-1.383 4.444-.77 6.707a8.222 8.222 0 0 0 2.217 3.74c.083.083-.02.216-.119.155a7.568 7.568 0 0 1-.93-.686A7.674 7.674 0 0 1 4.1 16.248c-.329-2.156.387-4.246 1.418-6.115a27.44 27.44 0 0 1 1.92-2.947zm7.931 8.435a.193.193 0 0 0-.191.191V18.3h2.677V15.62zm3.299 0V18.3h1.348a7.975 7.975 0 0 0 .515-2.678zm-6.303 3.004a.193.193 0 0 0-.191.193v2.485h2.678v-2.678Zm3.295.484v2.68h2.115a.562.562 0 0 0 .399-.162v-.004a.562.562 0 0 0 .16-.397V19.11zm3.674.182v1.98a7.999 7.999 0 0 0 1.217-1.98zm-6.969 2.824a.193.193 0 0 0-.191.192v1.672a7.997 7.997 0 0 0 2.678-.516v-1.348zm3.48.668V24a8.008 8.008 0 0 0 1.98-1.217z"/>
</svg>
<text x="252" y="154" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Apache NiFi</text>
@@ -215,7 +217,7 @@
<rect x="372" y="104" width="160" height="72" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="380" y="110" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="394" y="119" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">VIRT</text>
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="440" y="110" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M14.124 16.8529a.1615.1615 0 1 1 .1576.1614.1577.1577 0 0 1-.1576-.1614zm-5.607-.1576a.1614.1614 0 1 0 0 .3228.1614.1614 0 0 0 0-.3228zm10.1341-.6648v1.9869c-.031.5788-.524 1.0237-1.1029.9954h-.3843a5.0596 5.0596 0 0 1-1.1298 1.7178.3192.3192 0 0 0 0 .465l.2382.2191a.3036.3036 0 0 1 .0385.4304c-1.126 1.3835-2.9669 2.1521-5.0498 2.1521a6.575 6.575 0 0 1-4.8192-1.8985c-.0029-.0032-.0059-.0063-.0087-.0096a.6302.6302 0 0 1 .0548-.8896c.137-.1265.1371-.3462 0-.4727a4.944 4.944 0 0 1-1.126-1.714h-.3497c-.5797.0284-1.0737-.416-1.1068-.9954v-1.9869c.0351-.5779.5286-1.02 1.1068-.9915h.2728a5.7648 5.7648 0 0 1 2.0791-3.0936c-.4227-1.0991-1.1529-3.2551-1.226-5.0075C6.0229 4.4705 6.2189.078 7.8253.001c1.6064-.0768 1.3719 4.0275 1.0991 6.6946a32.732 32.732 0 0 0-.123 4.4503 6.994 6.994 0 0 1 2.4826-.4304 7.2414 7.2414 0 0 1 1.7371.2075c.2614-1.2682.8762-3.574 2.0292-5.1958 1.6717-2.352 3.4357-4.7808 4.6116-4.1006 1.176.6802-.3074 3.1398-1.3297 4.4272-1.0222 1.2874-2.7862 3.2089-3.3742 4.2274-.2114.3843-.4304.8032-.5956 1.1529a5.7375 5.7375 0 0 1 2.9169 3.6125h.073v-2.3058a.3075.3075 0 0 0-.1806-.2844.9148.9148 0 0 1-.5573-.8148 1.0184 1.0184 0 0 1 .9045-.9044c.5593-.0598 1.061.3452 1.1208.9044a.9187.9187 0 0 1-.5534.8148.3074.3074 0 0 0-.1691.2844v2.1522a.3113.3113 0 0 0 .1691.2805.9724.9724 0 0 1 .5648.857z"/>
</svg>
<text x="452" y="146" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Trino</text>
@@ -226,7 +228,7 @@
<rect x="372" y="208" width="160" height="80" rx="8" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1.2"/>
<rect x="380" y="214" width="36" height="12" rx="2" fill="transparent" stroke="rgba(235,108,54,0.50)" stroke-width="0.8"/>
<text x="398" y="223" fill="rgba(235,108,54,0.80)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">STORE</text>
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36">
<svg x="440" y="214" width="24" height="24" viewBox="0 0 24 24" fill="#eb6c36" aria-hidden="true">
<path d="M13.2072.006c-.6216-.0478-1.2.1943-1.6211.582a2.15 2.15 0 0 0-.0938 3.0352l3.4082 3.5507a3.042 3.042 0 0 1-.664 4.6875l-.463.2383V7.2853a15.4198 15.4198 0 0 0-8.0174 10.4862v.0176l6.5487-3.3281v7.621L13.7794 24V13.6817l.8965-.4629a4.4432 4.4432 0 0 0 1.2207-7.0292l-3.371-3.5254a.7489.7489 0 0 1 .037-1.0547.7522.7522 0 0 1 1.0567.0371l.4668.4863-.006.0059 4.0704 4.2441a.0566.0566 0 0 0 .082 0 .06.06 0 0 0 0-.0703l-3.1406-5.1425-.1484.1425.1484-.1445C14.4945.3926 13.8287.0538 13.2072.006Zm-.9024 9.8652v2.9941l-4.1523 2.1484a13.9787 13.9787 0 0 1 2.7676-3.9277 14.1784 14.1784 0 0 1 1.3847-1.2148z"/>
</svg>
<text x="452" y="252" fill="#eb6c36" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">MinIO / S3</text>
@@ -237,7 +239,7 @@
<rect x="600" y="144" width="164" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="608" y="150" width="32" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="624" y="159" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">ANLZ</text>
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="670" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799 1.784 1.799 0 0 1 1.784-1.799 1.784 1.799 0 0 1 1.783 1.799zM20.582 1.427a1.415 1.427 0 0 1-1.415 1.428 1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427zM4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056zm7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.363 9.363 0 0 0-3.393-4.547 9.238 9.238 0 0 0-5.377-1.728A9.238 9.238 0 0 0 6.95 3.73a9.363 9.363 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424zm.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.363 9.363 0 0 0 3.394 4.547A9.238 9.238 0 0 0 12.33 21a9.238 9.238 0 0 0 5.377-1.729 9.363 9.363 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425z"/>
</svg>
<text x="682" y="186" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Data Modeling</text>
@@ -248,14 +250,14 @@
<rect x="820" y="144" width="152" height="80" rx="6" fill="white" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
<rect x="828" y="150" width="28" height="12" rx="2" fill="transparent" stroke="rgba(45,49,66,0.28)" stroke-width="0.8"/>
<text x="842" y="159" fill="rgba(45,49,66,0.55)" font-size="7" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.08em">DASH</text>
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142">
<svg x="884" y="150" width="24" height="24" viewBox="0 0 24 24" fill="#2d3142" aria-hidden="true">
<path d="M6.168 6.045C2.603 6.045 0 8.579 0 12.014c0 3.434 2.603 5.941 6.168 5.941 2.184 0 3.888-1.026 5.775-3.078 1.53 2.033 4.037 3.136 5.89 3.078 3.566 0 6.167-2.503 6.167-5.941 0-3.438-2.601-5.97-6.168-5.97-2.864 0-5.138 2.425-5.771 3.173-.76-.9-1.674-1.665-2.682-2.274-1.019-.588-2.084-.898-3.211-.898z"/>
</svg>
<text x="896" y="186" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Dashboards</text>
<text x="896" y="198" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">Superset · reports</text>
<!-- ── Kubernetes label (bottom-left of boundary) ── -->
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="180" y="348" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M19.875 6.27a2.225 2.225 0 0 1 1.125 1.948v7.284c0 .809-.443 1.555-1.158 1.948l-6.75 3.98a2.5 2.5 0 0 1-2.184 0l-6.75-3.98a2.225 2.225 0 0 1-1.158-1.948v-7.284c0-.809.443-1.555 1.158-1.948l6.75-3.98a2.5 2.5 0 0 1 2.184 0z"/>
<circle cx="12" cy="12" r="3"/>
<line x1="12" y1="3" x2="12" y2="9"/><line x1="12" y1="15" x2="12" y2="21"/>
@@ -265,7 +267,7 @@
<text x="204" y="362" fill="#4f5d75" font-size="8" font-weight="500" font-family="'Geist', sans-serif">Kubernetes</text>
<!-- ── Identity Manager bar ── -->
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<svg x="16" y="398" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#4f5d75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1-8.5 15a12 12 0 0 1-8.5-15a12 12 0 0 0 8.5-3"/>
<circle cx="12" cy="11" r="1" fill="#4f5d75"/>
<line x1="12" y1="12" x2="12" y2="14.5"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Architecture · Imported from draw.io · doc-inline · balanced</p>
<h1>Order platform — request path</h1>
<svg viewBox="0 0 960 600" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 960 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="import-drawio-title import-drawio-desc">
<title id="import-drawio-title">Order platform — request path</title>
<desc id="import-drawio-desc">Architecture diagram showing web and mobile clients entering through an API Gateway, then reaching authentication, orders, Postgres, object storage, and Redis.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
@@ -34,8 +34,8 @@
<h1>Legacy retail reporting landscape</h1>
<p class="subtitle">File exports, desktop spreadsheets, and manual publication before a shared data platform.</p>
<div class="diagram">
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-dark-title it-dark-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-dark-title">Northwind Retail current IT landscape</title><desc id="it-dark-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-state-dark-title it-state-dark-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-state-dark-title">Northwind Retail current IT landscape</title><desc id="it-state-dark-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#6a95d8"/></marker>
@@ -34,8 +34,8 @@
<main class="container">
<header class="header"><p class="header-eyebrow">IT current-state · Northwind Retail</p><h1>Legacy retail reporting landscape</h1><p class="subtitle">Sales and supplier files converge on a shared drive, move through desktop workbooks, and reach regional teams through a manually refreshed portal and emailed report packs.</p></header>
<div class="diagram-container">
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-full-title it-full-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-full-title">Northwind Retail current IT landscape</title><desc id="it-full-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-state-full-title it-state-full-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-state-full-title">Northwind Retail current IT landscape</title><desc id="it-state-full-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker><marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker><marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
<symbol id="icon-file" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 3v4a1 1 0 0 0 1 1h4"/><path d="M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2"/></symbol><symbol id="icon-screen" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="12" rx="1"/><path d="M7 20h10M9 16v4M15 16v4"/></symbol><symbol id="icon-db" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><ellipse cx="12" cy="6" rx="8" ry="3"/><path d="M4 6v6c0 1.7 3.6 3 8 3s8-1.3 8-3V6M4 12v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></symbol><symbol id="icon-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="9" cy="8" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2M16 4.5a4 4 0 0 1 0 7M18 15a4 4 0 0 1 3 4v2"/></symbol>
@@ -44,9 +44,9 @@
<h1>Legacy retail reporting landscape</h1>
<p class="subtitle">File exports, desktop spreadsheets, and manual publication before a shared data platform.</p>
<div class="diagram">
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-title it-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-title">Northwind Retail current IT landscape</title>
<desc id="it-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<svg viewBox="0 0 960 500" role="img" aria-labelledby="it-state-title it-state-desc" xmlns="http://www.w3.org/2000/svg">
<title id="it-state-title">Northwind Retail current IT landscape</title>
<desc id="it-state-desc">Three zones show collection, processing, and dissemination through manual file handoffs.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker>
@@ -58,7 +58,9 @@
<p class="eyebrow">Layer stack · Diagram Design</p>
<h1>AI app stack · Where the work actually happens</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="layers-dark-title layers-dark-desc">
<title id="layers-dark-title">AI app stack · Where the work actually happens</title>
<desc id="layers-dark-desc">Layer stack showing model weights, SDK, prompts, agent harness, and UI surface, with the agent harness highlighted as the focal layer.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="layers-full-title layers-full-desc">
<title id="layers-full-title">AI app stack · Where the work actually happens</title>
<desc id="layers-full-desc">Layer stack showing model weights, SDK, prompts, agent harness, and UI surface, with the agent harness highlighted as the focal layer.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Layer stack · Diagram Design</p>
<h1>AI app stack · Where the work actually happens</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="layers-title layers-desc">
<title id="layers-title">AI app stack · Where the work actually happens</title>
<desc id="layers-desc">Layer stack showing model weights, SDK, prompts, agent harness, and UI surface, with the agent harness highlighted as the focal layer.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -20,7 +20,9 @@
<p class="eyebrow">Line · Diagram Design</p>
<h1>Weekly signups · Organic leads the growth</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-dark-title line-dark-desc">
<title id="line-dark-title">Weekly signups · Organic leads the growth</title>
<desc id="line-dark-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -36,7 +36,9 @@
<p class="subtitle">Signup volume by acquisition channel over eight weeks. Organic search is both the largest and fastest-growing channel; Direct is the stable baseline.</p>
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-full-title line-full-desc">
<title id="line-full-title">Weekly signups · Organic leads the growth</title>
<desc id="line-full-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
<defs><pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern></defs>
<rect width="100%" height="100%" fill="#f5f5f5"/>
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
@@ -20,7 +20,9 @@
<p class="eyebrow">Line · Diagram Design</p>
<h1>Weekly signups · Organic leads the growth</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-title line-desc">
<title id="line-title">Weekly signups · Organic leads the growth</title>
<desc id="line-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -36,9 +36,9 @@
<p class="eyebrow">Loop · Diagram Design</p>
<h1>The self-improving loop</h1>
<svg viewBox="0 0 1040 680" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="loop-title loop-desc">
<title id="loop-title">The self-improving loop</title>
<desc id="loop-desc">Six stations flow clockwise from Capture through Learn and back to Capture. Each station writes shared state into one central memory hub, with Decide highlighted as the human approval gate.</desc>
<svg viewBox="0 0 1040 680" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="loop-dark-title loop-dark-desc">
<title id="loop-dark-title">The self-improving loop</title>
<desc id="loop-dark-desc">Six stations flow clockwise from Capture through Learn and back to Capture. Each station writes shared state into one central memory hub, with Decide highlighted as the human approval gate.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
@@ -56,9 +56,9 @@
</header>
<div class="diagram-container">
<svg viewBox="0 0 1040 680" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="loop-title loop-desc">
<title id="loop-title">The self-improving loop</title>
<desc id="loop-desc">Six stations flow clockwise from Capture through Learn and back to Capture. Each station writes shared state into one central memory hub, with Decide highlighted as the human approval gate.</desc>
<svg viewBox="0 0 1040 680" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="loop-full-title loop-full-desc">
<title id="loop-full-title">The self-improving loop</title>
<desc id="loop-full-desc">Six stations flow clockwise from Capture through Learn and back to Capture. Each station writes shared state into one central memory hub, with Decide highlighted as the human approval gate.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
@@ -173,10 +173,10 @@
viewBox="0 0 1040 680"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-labelledby="loop-title loop-desc"
aria-labelledby="loop-terminal-title loop-terminal-desc"
>
<title id="loop-title">The self-improving loop</title>
<desc id="loop-desc">
<title id="loop-terminal-title">The self-improving loop</title>
<desc id="loop-terminal-desc">
Six stations flow clockwise from Capture through Learn and back to
Capture. Each station writes shared state into one central memory
hub, with Decide highlighted as the human approval gate.
@@ -37,9 +37,9 @@
<p class="eyebrow">Medallion · Diagram Design</p>
<h1>Five-tier e-commerce analytics storage</h1>
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-title medallion-desc">
<title id="medallion-title">Five-tier e-commerce analytics medallion</title>
<desc id="medallion-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-dark-title medallion-dark-desc">
<title id="medallion-dark-title">Five-tier e-commerce analytics medallion</title>
<desc id="medallion-dark-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
@@ -57,9 +57,9 @@
</header>
<div class="diagram-container">
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-title medallion-desc">
<title id="medallion-title">Five-tier e-commerce analytics medallion</title>
<desc id="medallion-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-full-title medallion-full-desc">
<title id="medallion-full-title">Five-tier e-commerce analytics medallion</title>
<desc id="medallion-full-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
@@ -58,7 +58,9 @@
<p class="eyebrow">Nested · Diagram Design</p>
<h1>The CLAUDE.md Hierarchy</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="nested-dark-title nested-dark-desc">
<title id="nested-dark-title">The CLAUDE.md Hierarchy</title>
<desc id="nested-dark-desc">Nested diagram showing how project CLAUDE.md instructions inherit broader scopes from the global, vault, business, and marketing levels.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="nested-full-title nested-full-desc">
<title id="nested-full-title">The CLAUDE.md Hierarchy</title>
<desc id="nested-full-desc">Nested diagram showing how project CLAUDE.md instructions inherit broader scopes from the global, vault, business, and marketing levels.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Nested · Diagram Design</p>
<h1>The CLAUDE.md Hierarchy</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="nested-title nested-desc">
<title id="nested-title">The CLAUDE.md Hierarchy</title>
<desc id="nested-desc">Nested diagram showing how project CLAUDE.md instructions inherit broader scopes from the global, vault, business, and marketing levels.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -3,8 +3,8 @@
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--paper:#2d3142;--paper-2:#393e53;--ink:#f5f5f5;--muted:#bfc0c0;--soft:#8e98ac;--rule:rgba(245,245,245,.12);--accent:#f08a59;--accent-tint:rgba(240,138,89,.10);--link:#6a95d8;--sans:'Geist',system-ui,sans-serif;--serif:'Instrument Serif',serif;--mono:'Geist Mono',ui-monospace,monospace}
body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:48px 32px}.frame{max-width:1180px;width:100%}.eyebrow{font-family:var(--mono);font-size:9px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}h1{font-family:var(--serif);font-size:32px;font-weight:400;line-height:1.08;letter-spacing:-.02em;margin-bottom:20px}.subtitle{color:var(--muted);font-size:14px;line-height:1.5;max-width:720px;margin-bottom:24px}svg{width:100%;min-width:980px;display:block}.cards{display:grid;grid-template-columns:1.1fr 1fr .9fr;gap:16px;margin-top:20px}.card{background:var(--paper-2);border:1px solid var(--rule);border-radius:6px;padding:16px}.card h2{font-size:14px;margin-bottom:8px}.card p{font-size:12px;line-height:1.45;color:var(--muted)}@media(max-width:860px){body{display:block;padding:32px 20px}.cards{grid-template-columns:1fr;overflow:visible}.frame{overflow-x:auto}}
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
<title id="title">Agent team org chart</title><desc id="desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="org-chart-dark-title org-chart-dark-desc">
<title id="org-chart-dark-title">Agent team org chart</title><desc id="org-chart-dark-desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
<rect width="1040" height="620" fill="#2d3142"/>
<defs><marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#bfc0c0"/></marker></defs>
<text x="40" y="64" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".16em">COMMAND CENTER</text>
@@ -42,4 +42,4 @@ body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height
<rect x="72" y="480" width="896" height="48" rx="6" fill="#2d3142"/><rect x="72" y="480" width="896" height="48" rx="6" fill="rgba(245,245,245,.04)" stroke="#8e98ac" stroke-dasharray="4,4"/>
<text x="96" y="508" fill="#f5f5f5" font-family="'Geist',sans-serif" font-size="12" font-weight="600">Setup gaps stay visible:</text><text x="244" y="508" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9">specialists without Slack bots · approval gates · backend name mismatches</text>
<line x1="40" y1="560" x2="1000" y2="560" stroke="rgba(245,245,245,.14)"/><text x="40" y="584" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".14em">LEGEND</text><rect x="132" y="572" width="16" height="12" rx="2" fill="rgba(240,138,89,.10)" stroke="#f08a59"/><text x="156" y="582" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9">front door</text><rect x="288" y="572" width="16" height="12" rx="2" fill="#393e53" stroke="#f5f5f5"/><text x="312" y="582" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9">pod / owner</text><rect x="452" y="572" width="16" height="12" rx="2" fill="rgba(245,245,245,.04)" stroke="#8e98ac" stroke-dasharray="4,4"/><text x="476" y="582" fill="#bfc0c0" font-family="'Geist Mono',monospace" font-size="9">needs setup / gap</text>
</svg></div></body></html>
</svg></div></body></html>
@@ -3,8 +3,8 @@
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--paper:#f5f5f5;--paper-2:#fff;--ink:#2d3142;--muted:#4f5d75;--soft:#7a8399;--rule:rgba(45,49,66,.12);--accent:#eb6c36;--accent-tint:rgba(235,108,54,.08);--link:#2e5aa8;--sans:'Geist',system-ui,sans-serif;--serif:'Instrument Serif',serif;--mono:'Geist Mono',ui-monospace,monospace}
body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:48px 32px}.frame{max-width:1180px;width:100%}.eyebrow{font-family:var(--mono);font-size:9px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}h1{font-family:var(--serif);font-size:32px;font-weight:400;line-height:1.08;letter-spacing:-.02em;margin-bottom:20px}.subtitle{color:var(--muted);font-size:14px;line-height:1.5;max-width:720px;margin-bottom:24px}svg{width:100%;min-width:980px;display:block}.cards{display:grid;grid-template-columns:1.1fr 1fr .9fr;gap:16px;margin-top:20px}.card{background:#fff;border:1px solid var(--rule);border-radius:6px;padding:16px}.card h2{font-size:14px;margin-bottom:8px}.card p{font-size:12px;line-height:1.45;color:var(--muted)}@media(max-width:860px){body{display:block;padding:32px 20px}.cards{grid-template-columns:1fr;overflow:visible}.frame{overflow-x:auto}}
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
<title id="title">Agent team org chart</title><desc id="desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="org-chart-full-title org-chart-full-desc">
<title id="org-chart-full-title">Agent team org chart</title><desc id="org-chart-full-desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
<rect width="1040" height="620" fill="#f5f5f5"/>
<defs><marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#4f5d75"/></marker></defs>
<text x="40" y="64" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".16em">COMMAND CENTER</text>
@@ -42,4 +42,4 @@ body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height
<rect x="72" y="480" width="896" height="48" rx="6" fill="#f5f5f5"/><rect x="72" y="480" width="896" height="48" rx="6" fill="rgba(45,49,66,.02)" stroke="#7a8399" stroke-dasharray="4,4"/>
<text x="96" y="508" fill="#2d3142" font-family="'Geist',sans-serif" font-size="12" font-weight="600">Setup gaps stay visible:</text><text x="244" y="508" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">specialists without Slack bots · approval gates · backend name mismatches</text>
<line x1="40" y1="560" x2="1000" y2="560" stroke="rgba(45,49,66,.12)"/><text x="40" y="584" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".14em">LEGEND</text><rect x="132" y="572" width="16" height="12" rx="2" fill="rgba(235,108,54,.08)" stroke="#eb6c36"/><text x="156" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">front door</text><rect x="288" y="572" width="16" height="12" rx="2" fill="#ffffff" stroke="#2d3142"/><text x="312" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">pod / owner</text><rect x="452" y="572" width="16" height="12" rx="2" fill="rgba(45,49,66,.02)" stroke="#7a8399" stroke-dasharray="4,4"/><text x="476" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">needs setup / gap</text>
</svg><div class="cards"><article class="card"><h2>Use when</h2><p>The reader needs to know who owns what, where to route work, and which roles are active vs. still being wired.</p></article><article class="card"><h2>Keep nodes short</h2><p>Name, invocation path, and 2–4 scope words. Put detailed operating rules below the figure.</p></article><article class="card"><h2>Show gaps</h2><p>Unavailable owners and missing routes should be dashed, not hidden. They are operationally useful.</p></article></div></div></body></html>
</svg><div class="cards"><article class="card"><h2>Use when</h2><p>The reader needs to know who owns what, where to route work, and which roles are active vs. still being wired.</p></article><article class="card"><h2>Keep nodes short</h2><p>Name, invocation path, and 2–4 scope words. Put detailed operating rules below the figure.</p></article><article class="card"><h2>Show gaps</h2><p>Unavailable owners and missing routes should be dashed, not hidden. They are operationally useful.</p></article></div></div></body></html>
@@ -3,8 +3,8 @@
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--paper:#f5f5f5;--paper-2:#fff;--ink:#2d3142;--muted:#4f5d75;--soft:#7a8399;--rule:rgba(45,49,66,.12);--accent:#eb6c36;--accent-tint:rgba(235,108,54,.08);--link:#2e5aa8;--sans:'Geist',system-ui,sans-serif;--serif:'Instrument Serif',serif;--mono:'Geist Mono',ui-monospace,monospace}
body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:48px 32px}.frame{max-width:1180px;width:100%}.eyebrow{font-family:var(--mono);font-size:9px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}h1{font-family:var(--serif);font-size:32px;font-weight:400;line-height:1.08;letter-spacing:-.02em;margin-bottom:20px}.subtitle{color:var(--muted);font-size:14px;line-height:1.5;max-width:720px;margin-bottom:24px}svg{width:100%;min-width:980px;display:block}.cards{display:grid;grid-template-columns:1.1fr 1fr .9fr;gap:16px;margin-top:20px}.card{background:#fff;border:1px solid var(--rule);border-radius:6px;padding:16px}.card h2{font-size:14px;margin-bottom:8px}.card p{font-size:12px;line-height:1.45;color:var(--muted)}@media(max-width:860px){body{display:block;padding:32px 20px}.cards{grid-template-columns:1fr;overflow:visible}.frame{overflow-x:auto}}
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
<title id="title">Agent team org chart</title><desc id="desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
</style></head><body><div class="frame"><p class="eyebrow">Org chart · Diagram Design</p><h1>Agent team responsibility map</h1><p class="subtitle">A responsibility map for teams, agents, and escalation paths. Unlike a generic tree, it makes the front door, owners, invocation paths, and setup gaps visible.</p><svg viewBox="0 0 1040 620" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="org-chart-title org-chart-desc">
<title id="org-chart-title">Agent team org chart</title><desc id="org-chart-desc">Org chart showing a command center routing work to specialist agents and escalation owners.</desc>
<rect width="1040" height="620" fill="#f5f5f5"/>
<defs><marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="#4f5d75"/></marker></defs>
<text x="40" y="64" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".16em">COMMAND CENTER</text>
@@ -42,4 +42,4 @@ body{font-family:var(--sans);background:var(--paper);color:var(--ink);min-height
<rect x="72" y="480" width="896" height="48" rx="6" fill="#f5f5f5"/><rect x="72" y="480" width="896" height="48" rx="6" fill="rgba(45,49,66,.02)" stroke="#7a8399" stroke-dasharray="4,4"/>
<text x="96" y="508" fill="#2d3142" font-family="'Geist',sans-serif" font-size="12" font-weight="600">Setup gaps stay visible:</text><text x="244" y="508" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">specialists without Slack bots · approval gates · backend name mismatches</text>
<line x1="40" y1="560" x2="1000" y2="560" stroke="rgba(45,49,66,.12)"/><text x="40" y="584" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9" letter-spacing=".14em">LEGEND</text><rect x="132" y="572" width="16" height="12" rx="2" fill="rgba(235,108,54,.08)" stroke="#eb6c36"/><text x="156" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">front door</text><rect x="288" y="572" width="16" height="12" rx="2" fill="#ffffff" stroke="#2d3142"/><text x="312" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">pod / owner</text><rect x="452" y="572" width="16" height="12" rx="2" fill="rgba(45,49,66,.02)" stroke="#7a8399" stroke-dasharray="4,4"/><text x="476" y="582" fill="#4f5d75" font-family="'Geist Mono',monospace" font-size="9">needs setup / gap</text>
</svg></div></body></html>
</svg></div></body></html>
@@ -17,7 +17,9 @@
<div class="frame">
<p class="eyebrow">Process · Diagram Design</p>
<h1>Order fulfillment across four teams</h1>
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure">
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure" role="img" aria-labelledby="process-dark-title process-dark-desc">
<title id="process-dark-title">Order fulfillment across four teams</title>
<desc id="process-dark-desc">Process diagram showing an order moving through customer, support, warehouse, and finance ownership from placement to close.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -20,7 +20,9 @@
<h1>Order fulfillment across four teams</h1>
<p class="subtitle">One order moves through customer, support, warehouse, and finance ownership, while the payload chips show what each handoff carries.</p>
<div class="diagram-container">
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure">
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure" role="img" aria-labelledby="process-full-title process-full-desc">
<title id="process-full-title">Order fulfillment across four teams</title>
<desc id="process-full-desc">Process diagram showing an order moving through customer, support, warehouse, and finance ownership from placement to close.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -17,7 +17,9 @@
<div class="frame">
<p class="eyebrow">Process · Diagram Design</p>
<h1>Order fulfillment across four teams</h1>
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure">
<svg viewBox="0 0 1064 436" xmlns="http://www.w3.org/2000/svg" aria-label="Order fulfillment process from customer order to support closure" role="img" aria-labelledby="process-title process-desc">
<title id="process-title">Order fulfillment across four teams</title>
<desc id="process-desc">Process diagram showing an order moving through customer, support, warehouse, and finance ownership from placement to close.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="11" cy="11" r="0.8" fill="var(--dot)"/></pattern>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0,8 3,0 6" fill="var(--muted)"/></marker>
@@ -58,7 +58,9 @@
<p class="eyebrow">Pyramid · Diagram Design</p>
<h1>Content pyramid · what compounds</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pyramid-dark-title pyramid-dark-desc">
<title id="pyramid-dark-title">Content pyramid · what compounds</title>
<desc id="pyramid-dark-desc">Content pyramid showing short posts, essays, long-form guides, and a flagship book ordered by shipping cadence and leverage.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pyramid-full-title pyramid-full-desc">
<title id="pyramid-full-title">Content pyramid · what compounds</title>
<desc id="pyramid-full-desc">Content pyramid showing short posts, essays, long-form guides, and a flagship book ordered by shipping cadence and leverage.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Pyramid · Diagram Design</p>
<h1>Content pyramid · what compounds</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pyramid-title pyramid-desc">
<title id="pyramid-title">Content pyramid · what compounds</title>
<desc id="pyramid-desc">Content pyramid showing short posts, essays, long-form guides, and a flagship book ordered by shipping cadence and leverage.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -57,7 +57,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 660" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 660" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="quadrant-consultant-title quadrant-consultant-desc">
<title id="quadrant-consultant-title">Workplace 2030 · Remote × AI automation</title>
<desc id="quadrant-consultant-desc">Scenario matrix showing four workplace futures across remote-to-in-person and human-to-AI axes, with agent teams as the headline bet.</desc>
<defs>
<!-- Double-ended axis markers -->
<marker id="axis-end" markerWidth="9" markerHeight="7" refX="8" refY="3.5" orient="auto">
@@ -58,7 +58,9 @@
<p class="eyebrow">Quadrant · Diagram Design</p>
<h1>Content ideas · Impact × Effort</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="quadrant-dark-title quadrant-dark-desc">
<title id="quadrant-dark-title">Content ideas · Impact × Effort</title>
<desc id="quadrant-dark-desc">Impact-effort matrix showing eight content projects across do first, major projects, quick wins, and avoid quadrants.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="quadrant-full-title quadrant-full-desc">
<title id="quadrant-full-title">Content ideas · Impact × Effort</title>
<desc id="quadrant-full-desc">Impact-effort matrix showing eight content projects across do first, major projects, quick wins, and avoid quadrants.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Quadrant · Diagram Design</p>
<h1>Content ideas · Impact × Effort</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="quadrant-title quadrant-desc">
<title id="quadrant-title">Content ideas · Impact × Effort</title>
<desc id="quadrant-desc">Impact-effort matrix showing eight content projects across do first, major projects, quick wins, and avoid quadrants.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Radar · Diagram Design</p>
<h1>Storage backends · Capability radar</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-dark-title radar-dark-desc">
<title id="radar-dark-title">Storage backends · Capability radar</title>
<desc id="radar-dark-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -41,7 +41,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-full-title radar-full-desc">
<title id="radar-full-title">Storage backends · Capability radar</title>
<desc id="radar-full-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Radar · Diagram Design</p>
<h1>Storage backends · Capability radar</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-title radar-desc">
<title id="radar-title">Storage backends · Capability radar</title>
<desc id="radar-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -22,7 +22,9 @@
<!-- X: 0-20 deploys/week → 880px. x = 80 + f/20*880 = 80+44*f -->
<!-- Y: 0-24 days lead time → 380px. y = 420 - lt/24*380. High lt = high y (worse) -->
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="scatter-dark-title scatter-dark-desc">
<title id="scatter-dark-title">Deploy frequency vs. lead time · 12 teams</title>
<desc id="scatter-dark-desc">Scatter plot showing twelve engineering teams by deploy frequency and lead time, with Platform in the best-performing quadrant.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -36,7 +36,9 @@
<p class="subtitle">Each point is an engineering team. Moving right means deploying more often; moving down means shipping faster. The Platform team occupies the lower-right — the ideal quadrant.</p>
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="scatter-full-title scatter-full-desc">
<title id="scatter-full-title">Deploy frequency vs. lead time · 12 teams</title>
<desc id="scatter-full-desc">Scatter plot showing twelve engineering teams by deploy frequency and lead time, with Platform in the best-performing quadrant.</desc>
<defs><pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern></defs>
<rect width="100%" height="100%" fill="#f5f5f5"/>
<rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
@@ -22,7 +22,9 @@
<!-- X: 0-20 deploys/week → 880px. x = 80 + f/20*880 = 80+44*f -->
<!-- Y: 0-24 days lead time → 380px. y = 420 - lt/24*380. High lt = high y (worse) -->
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="scatter-title scatter-desc">
<title id="scatter-title">Deploy frequency vs. lead time · 12 teams</title>
<desc id="scatter-desc">Scatter plot showing twelve engineering teams by deploy frequency and lead time, with Platform in the best-performing quadrant.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Sequence · Diagram Design</p>
<h1>Article request, cold cache</h1>
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-dark-title sequence-dark-desc">
<title id="sequence-dark-title">Article request, cold cache</title>
<desc id="sequence-dark-desc">Sequence diagram showing a cold-cache article request moving from reader and browser through Cloudflare to an Astro origin and analytics beacon.</desc>
<defs>
<!-- Dot grid background -->
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
@@ -183,7 +183,9 @@
<!-- Sequence Diagram -->
<div class="diagram-container">
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-full-title sequence-full-desc">
<title id="sequence-full-title">Article request, cold cache</title>
<desc id="sequence-full-desc">Sequence diagram showing a cold-cache article request moving from reader and browser through Cloudflare to an Astro origin and analytics beacon.</desc>
<defs>
<!-- Dot grid background -->
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
@@ -58,9 +58,9 @@
<p class="eyebrow">Sequence · Diagram Design · Special</p>
<h1>Bearer call with refresh</h1>
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="seq-title seq-desc">
<title id="seq-title">Bearer call with refresh</title>
<desc id="seq-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-oauth-dark-title sequence-oauth-dark-desc">
<title id="sequence-oauth-dark-title">Bearer call with refresh</title>
<desc id="sequence-oauth-dark-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -181,9 +181,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="seq-title seq-desc">
<title id="seq-title">Bearer call with refresh</title>
<desc id="seq-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-oauth-full-title sequence-oauth-full-desc">
<title id="sequence-oauth-full-title">Bearer call with refresh</title>
<desc id="sequence-oauth-full-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,9 +58,9 @@
<p class="eyebrow">Sequence · Diagram Design · Special</p>
<h1>Bearer call with refresh</h1>
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="seq-title seq-desc">
<title id="seq-title">Bearer call with refresh</title>
<desc id="seq-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<svg viewBox="0 0 960 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-oauth-title sequence-oauth-desc">
<title id="sequence-oauth-title">Bearer call with refresh</title>
<desc id="sequence-oauth-desc">Client calls API with a bearer token. An ALT fragment shows either a valid 200 response or a 401 path that refreshes via Auth and retries.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Sequence · Diagram Design</p>
<h1>Article request, cold cache</h1>
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 584" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="sequence-title sequence-desc">
<title id="sequence-title">Article request, cold cache</title>
<desc id="sequence-desc">Sequence diagram showing a cold-cache article request moving from reader and browser through Cloudflare to an Astro origin and analytics beacon.</desc>
<defs>
<!-- Dot grid background -->
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
@@ -58,7 +58,9 @@
<p class="eyebrow">State machine · Diagram Design</p>
<h1>Article lifecycle</h1>
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="state-dark-title state-dark-desc">
<title id="state-dark-title">Article lifecycle</title>
<desc id="state-dark-desc">State machine showing an article moving from Draft through In Review and Published to Archived, including rejection and revision.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="state-full-title state-full-desc">
<title id="state-full-title">Article lifecycle</title>
<desc id="state-full-desc">State machine showing an article moving from Draft through In Review and Published to Archived, including rejection and revision.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">State machine · Diagram Design</p>
<h1>Article lifecycle</h1>
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 460" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="state-title state-desc">
<title id="state-title">Article lifecycle</title>
<desc id="state-desc">State machine showing an article moving from Draft through In Review and Published to Archived, including rejection and revision.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Swimlane · Diagram Design</p>
<h1>Publishing an article</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="swimlane-dark-title swimlane-dark-desc">
<title id="swimlane-dark-title">Publishing an article</title>
<desc id="swimlane-dark-desc">Swimlane diagram showing an article moving from MDX draft through review, editing, approval, build, and Cloudflare Pages deployment.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="swimlane-full-title swimlane-full-desc">
<title id="swimlane-full-title">Publishing an article</title>
<desc id="swimlane-full-desc">Swimlane diagram showing an article moving from MDX draft through review, editing, approval, build, and Cloudflare Pages deployment.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Swimlane · Diagram Design</p>
<h1>Publishing an article</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="swimlane-title swimlane-desc">
<title id="swimlane-title">Publishing an article</title>
<desc id="swimlane-desc">Swimlane diagram showing an article moving from MDX draft through review, editing, approval, build, and Cloudflare Pages deployment.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Timeline · Diagram Design</p>
<h1>Product launch · fourteen months</h1>
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="timeline-dark-title timeline-dark-desc">
<title id="timeline-dark-title">Product launch · fourteen months</title>
<desc id="timeline-dark-desc">Timeline showing product milestones from the first post in February 2025 through three design versions and the schematic skill in April 2026.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="timeline-full-title timeline-full-desc">
<title id="timeline-full-title">Product launch · fourteen months</title>
<desc id="timeline-full-desc">Timeline showing product milestones from the first post in February 2025 through three design versions and the schematic skill in April 2026.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Timeline · Diagram Design</p>
<h1>Product launch · fourteen months</h1>
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 420" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="timeline-title timeline-desc">
<title id="timeline-title">Product launch · fourteen months</title>
<desc id="timeline-desc">Timeline showing product milestones from the first post in February 2025 through three design versions and the schematic skill in April 2026.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Tree · Diagram Design</p>
<h1>Claude Code skill taxonomy</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="tree-dark-title tree-dark-desc">
<title id="tree-dark-title">Claude Code skill taxonomy</title>
<desc id="tree-dark-desc">Tree diagram showing a Skills root branching into Design, Engineering, and Research categories and their leaf skills.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="tree-full-title tree-full-desc">
<title id="tree-full-title">Claude Code skill taxonomy</title>
<desc id="tree-full-desc">Tree diagram showing a Skills root branching into Design, Engineering, and Research categories and their leaf skills.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Tree · Diagram Design</p>
<h1>Claude Code skill taxonomy</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="tree-title tree-desc">
<title id="tree-title">Claude Code skill taxonomy</title>
<desc id="tree-desc">Tree diagram showing a Skills root branching into Design, Engineering, and Research categories and their leaf skills.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Venn · Diagram Design</p>
<h1>Good design · Desirable × Feasible × Viable</h1>
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="venn-dark-title venn-dark-desc">
<title id="venn-dark-title">Good design · Desirable × Feasible × Viable</title>
<desc id="venn-dark-desc">Venn diagram showing desirable, feasible, and viable product qualities intersecting at shippable.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
@@ -39,7 +39,9 @@
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="venn-full-title venn-full-desc">
<title id="venn-full-title">Good design · Desirable × Feasible × Viable</title>
<desc id="venn-full-desc">Venn diagram showing desirable, feasible, and viable product qualities intersecting at shippable.</desc>
<defs>
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
@@ -58,7 +58,9 @@
<p class="eyebrow">Venn · Diagram Design</p>
<h1>Good design · Desirable × Feasible × Viable</h1>
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1000 480" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="venn-title venn-desc">
<title id="venn-title">Good design · Desirable × Feasible × Viable</title>
<desc id="venn-desc">Venn diagram showing desirable, feasible, and viable product qualities intersecting at shippable.</desc>
<defs>
<!-- Chained clips isolate the all-three intersection: clip to Desirable, then to Feasible, then fill via the third circle. -->
<clipPath id="clip-desirable">
File diff suppressed because one or more lines are too long
@@ -58,7 +58,10 @@
<p class="eyebrow">[Type] · Diagram Design</p>
<h1>[Diagram title]</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<!-- Replace [diagram-slug] with a unique slug for this diagram before export. -->
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="[diagram-slug]-title [diagram-slug]-desc">
<title id="[diagram-slug]-title">[Diagram title]</title>
<desc id="[diagram-slug]-desc">[One sentence describing what the diagram shows]</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
@@ -175,7 +175,10 @@
<!-- Main Diagram -->
<div class="diagram-container">
<svg viewBox="0 0 1000 700" xmlns="http://www.w3.org/2000/svg">
<!-- Replace [diagram-slug] with a unique slug for this diagram before export. -->
<svg viewBox="0 0 1000 700" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="[diagram-slug]-title [diagram-slug]-desc">
<title id="[diagram-slug]-title">[Diagram title]</title>
<desc id="[diagram-slug]-desc">[One sentence describing what the diagram shows]</desc>
<defs>
<!-- OPTIONAL: dot-pattern background. Uncomment the <pattern> below and the second <rect> in the bg section to enable. -->
@@ -128,7 +128,10 @@
</p>
<h1>[Diagram title]</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<!-- Replace [diagram-slug] with a unique slug for this diagram before export. -->
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="[diagram-slug]-title [diagram-slug]-desc">
<title id="[diagram-slug]-title">[Diagram title]</title>
<desc id="[diagram-slug]-desc">[One sentence describing what the diagram shows]</desc>
<defs>
<marker
id="arrow"
+4 -1
View File
@@ -58,7 +58,10 @@
<p class="eyebrow">[Type] · Diagram Design</p>
<h1>[Diagram title]</h1>
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg">
<!-- Replace [diagram-slug] with a unique slug for this diagram before export. -->
<svg viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="[diagram-slug]-title [diagram-slug]-desc">
<title id="[diagram-slug]-title">[Diagram title]</title>
<desc id="[diagram-slug]-desc">[One sentence describing what the diagram shows]</desc>
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
@@ -20,6 +20,8 @@ The slash command is a thin wrapper that delegates here — both paths run the s
Both formats are **diagram-only** — just the `<svg>` node. Editorial wrappers (header, summary cards, footer in `-full` variants) are intentionally dropped: the export deliverable is the diagram itself, suitable for Figma, slides, social cards, or blog images.
The SVG-only export keeps the source `<title>` and `<desc>` with the diagram. Their per-diagram and per-variant prefixed IDs are what make multiple exported SVGs safe to inline in the same page without one figure resolving to another figure's accessible name.
If the user explicitly asks for "a screenshot of the whole page including the cards", that's a different request — fall back to a normal full-page screenshot via the user's OS or browser.
## SVG export procedure
@@ -29,6 +31,7 @@ If the user explicitly asks for "a screenshot of the whole page including the ca
3. Make it standalone:
- Ensure the opening tag has `xmlns="http://www.w3.org/2000/svg"`. Add it if missing.
- Ensure a `viewBox` is present. The skill's templates always include one; warn the user if absent rather than guessing.
- Preserve `role="img"`, `aria-labelledby`, and the first-child `<title>` / `<desc>` exactly as authored.
- Inject Google Fonts `@import` so the SVG renders with correct typography in a browser:
```svg
<defs>
@@ -177,4 +177,5 @@ Run alongside the SKILL.md §9 taste gate.
- [ ] Node names, sublabels, and edge labels all at the same audience level?
- [ ] CJK labels given a font fallback?
- [ ] Fidelity ledger reported for anything cut?
- [ ] Diagram `<svg>` has `role="img"`, resolving `aria-labelledby`, a non-empty first-child `<title>`, a non-empty `<desc>`, and per-diagram/variant prefixed IDs?
- [ ] Requested non-HTML formats produced via [`export.md`](export.md), not hand-authored?
File diff suppressed because one or more lines are too long