@laitszkin/apollo-toolkit 3.13.2 → 3.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/AGENTS.md +7 -7
  2. package/CHANGELOG.md +36 -0
  3. package/CLAUDE.md +8 -8
  4. package/analyse-app-logs/SKILL.md +3 -3
  5. package/bin/apollo-toolkit.ts +7 -0
  6. package/codex/codex-memory-manager/SKILL.md +2 -2
  7. package/codex/learn-skill-from-conversations/SKILL.md +3 -3
  8. package/dist/bin/apollo-toolkit.d.ts +2 -0
  9. package/dist/bin/apollo-toolkit.js +7 -0
  10. package/dist/lib/cli.d.ts +41 -0
  11. package/dist/lib/cli.js +655 -0
  12. package/dist/lib/installer.d.ts +59 -0
  13. package/dist/lib/installer.js +404 -0
  14. package/dist/lib/tool-runner.d.ts +19 -0
  15. package/dist/lib/tool-runner.js +536 -0
  16. package/dist/lib/tools/architecture.d.ts +2 -0
  17. package/dist/lib/tools/architecture.js +23 -0
  18. package/dist/lib/tools/create-specs.d.ts +2 -0
  19. package/dist/lib/tools/create-specs.js +175 -0
  20. package/dist/lib/tools/docs-to-voice.d.ts +2 -0
  21. package/dist/lib/tools/docs-to-voice.js +705 -0
  22. package/dist/lib/tools/enforce-video-aspect-ratio.d.ts +2 -0
  23. package/dist/lib/tools/enforce-video-aspect-ratio.js +312 -0
  24. package/dist/lib/tools/extract-conversations.d.ts +2 -0
  25. package/dist/lib/tools/extract-conversations.js +105 -0
  26. package/dist/lib/tools/extract-pdf-text.d.ts +2 -0
  27. package/dist/lib/tools/extract-pdf-text.js +92 -0
  28. package/dist/lib/tools/filter-logs.d.ts +2 -0
  29. package/dist/lib/tools/filter-logs.js +94 -0
  30. package/dist/lib/tools/find-github-issues.d.ts +2 -0
  31. package/dist/lib/tools/find-github-issues.js +176 -0
  32. package/dist/lib/tools/generate-storyboard-images.d.ts +2 -0
  33. package/dist/lib/tools/generate-storyboard-images.js +419 -0
  34. package/dist/lib/tools/log-cli-utils.d.ts +35 -0
  35. package/dist/lib/tools/log-cli-utils.js +233 -0
  36. package/dist/lib/tools/open-github-issue.d.ts +2 -0
  37. package/dist/lib/tools/open-github-issue.js +750 -0
  38. package/dist/lib/tools/read-github-issue.d.ts +2 -0
  39. package/dist/lib/tools/read-github-issue.js +134 -0
  40. package/dist/lib/tools/render-error-book.d.ts +2 -0
  41. package/dist/lib/tools/render-error-book.js +265 -0
  42. package/dist/lib/tools/render-katex.d.ts +2 -0
  43. package/dist/lib/tools/render-katex.js +294 -0
  44. package/dist/lib/tools/review-threads.d.ts +2 -0
  45. package/dist/lib/tools/review-threads.js +491 -0
  46. package/dist/lib/tools/search-logs.d.ts +2 -0
  47. package/dist/lib/tools/search-logs.js +164 -0
  48. package/dist/lib/tools/sync-memory-index.d.ts +2 -0
  49. package/dist/lib/tools/sync-memory-index.js +113 -0
  50. package/dist/lib/tools/validate-openai-agent-config.d.ts +2 -0
  51. package/dist/lib/tools/validate-openai-agent-config.js +190 -0
  52. package/dist/lib/tools/validate-skill-frontmatter.d.ts +2 -0
  53. package/dist/lib/tools/validate-skill-frontmatter.js +118 -0
  54. package/dist/lib/types.d.ts +82 -0
  55. package/dist/lib/types.js +2 -0
  56. package/dist/lib/updater.d.ts +34 -0
  57. package/dist/lib/updater.js +112 -0
  58. package/dist/lib/utils/format.d.ts +2 -0
  59. package/dist/lib/utils/format.js +6 -0
  60. package/dist/lib/utils/terminal.d.ts +12 -0
  61. package/dist/lib/utils/terminal.js +26 -0
  62. package/docs-to-voice/SKILL.md +0 -1
  63. package/generate-spec/SKILL.md +1 -1
  64. package/katex/SKILL.md +1 -2
  65. package/lib/cli.ts +780 -0
  66. package/lib/installer.ts +466 -0
  67. package/lib/tool-runner.ts +561 -0
  68. package/lib/tools/architecture.ts +20 -0
  69. package/lib/tools/create-specs.ts +204 -0
  70. package/lib/tools/docs-to-voice.ts +799 -0
  71. package/lib/tools/enforce-video-aspect-ratio.ts +368 -0
  72. package/lib/tools/extract-conversations.ts +114 -0
  73. package/lib/tools/extract-pdf-text.ts +99 -0
  74. package/lib/tools/filter-logs.ts +118 -0
  75. package/lib/tools/find-github-issues.ts +211 -0
  76. package/lib/tools/generate-storyboard-images.ts +455 -0
  77. package/lib/tools/log-cli-utils.ts +262 -0
  78. package/lib/tools/open-github-issue.ts +930 -0
  79. package/lib/tools/read-github-issue.ts +179 -0
  80. package/lib/tools/render-error-book.ts +300 -0
  81. package/lib/tools/render-katex.ts +325 -0
  82. package/lib/tools/review-threads.ts +590 -0
  83. package/lib/tools/search-logs.ts +200 -0
  84. package/lib/tools/sync-memory-index.ts +114 -0
  85. package/lib/tools/validate-openai-agent-config.ts +213 -0
  86. package/lib/tools/validate-skill-frontmatter.ts +124 -0
  87. package/lib/types.ts +90 -0
  88. package/lib/updater.ts +165 -0
  89. package/lib/utils/format.ts +7 -0
  90. package/lib/utils/terminal.ts +22 -0
  91. package/open-github-issue/SKILL.md +2 -2
  92. package/optimise-skill/SKILL.md +1 -1
  93. package/package.json +13 -4
  94. package/resources/project-architecture/assets/architecture.css +764 -0
  95. package/resources/project-architecture/assets/viewer.client.js +144 -0
  96. package/resources/project-architecture/index.html +42 -0
  97. package/review-spec-related-changes/SKILL.md +1 -1
  98. package/solve-issues-found-during-review/SKILL.md +2 -1
  99. package/tsconfig.json +28 -0
  100. package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
  101. package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
  102. package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
  103. package/analyse-app-logs/scripts/filter_logs_by_time.py +0 -64
  104. package/analyse-app-logs/scripts/log_cli_utils.py +0 -112
  105. package/analyse-app-logs/scripts/search_logs.py +0 -137
  106. package/analyse-app-logs/tests/test_filter_logs_by_time.py +0 -95
  107. package/analyse-app-logs/tests/test_search_logs.py +0 -100
  108. package/codex/codex-memory-manager/scripts/extract_recent_conversations.py +0 -369
  109. package/codex/codex-memory-manager/scripts/sync_memory_index.py +0 -130
  110. package/codex/codex-memory-manager/tests/test_extract_recent_conversations.py +0 -177
  111. package/codex/codex-memory-manager/tests/test_memory_template.py +0 -37
  112. package/codex/codex-memory-manager/tests/test_sync_memory_index.py +0 -84
  113. package/codex/learn-skill-from-conversations/scripts/extract_recent_conversations.py +0 -369
  114. package/codex/learn-skill-from-conversations/tests/test_extract_recent_conversations.py +0 -177
  115. package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
  116. package/docs-to-voice/scripts/docs_to_voice.py +0 -1385
  117. package/docs-to-voice/scripts/docs_to_voice.sh +0 -11
  118. package/docs-to-voice/tests/test_docs_to_voice_api_max_chars.py +0 -210
  119. package/docs-to-voice/tests/test_docs_to_voice_sentence_timeline.py +0 -115
  120. package/docs-to-voice/tests/test_docs_to_voice_settings.py +0 -43
  121. package/docs-to-voice/tests/test_docs_to_voice_shell_wrapper.py +0 -51
  122. package/docs-to-voice/tests/test_docs_to_voice_speech_rate.py +0 -57
  123. package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
  124. package/generate-spec/scripts/create-specs +0 -215
  125. package/generate-spec/tests/test_create_specs.py +0 -200
  126. package/init-project-html/scripts/architecture-bootstrap-render.js +0 -16
  127. package/init-project-html/scripts/architecture.js +0 -296
  128. package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
  129. package/katex/scripts/render_katex.py +0 -247
  130. package/katex/scripts/render_katex.sh +0 -11
  131. package/katex/tests/test_render_katex.py +0 -174
  132. package/learning-error-book/scripts/render_error_book_json_to_pdf.py +0 -590
  133. package/learning-error-book/tests/test_render_error_book_json_to_pdf.py +0 -134
  134. package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
  135. package/open-github-issue/scripts/open_github_issue.py +0 -705
  136. package/open-github-issue/tests/test_open_github_issue.py +0 -381
  137. package/openai-text-to-image-storyboard/scripts/generate_storyboard_images.py +0 -763
  138. package/openai-text-to-image-storyboard/tests/test_generate_storyboard_images.py +0 -177
  139. package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
  140. package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
  141. package/read-github-issue/scripts/find_issues.py +0 -148
  142. package/read-github-issue/scripts/read_issue.py +0 -108
  143. package/read-github-issue/tests/test_find_issues.py +0 -127
  144. package/read-github-issue/tests/test_read_issue.py +0 -109
  145. package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
  146. package/resolve-review-comments/scripts/review_threads.py +0 -425
  147. package/resolve-review-comments/tests/test_review_threads.py +0 -74
  148. package/scripts/validate_openai_agent_config.py +0 -209
  149. package/scripts/validate_skill_frontmatter.py +0 -131
  150. package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
  151. package/text-to-short-video/scripts/enforce_video_aspect_ratio.py +0 -350
  152. package/text-to-short-video/tests/test_enforce_video_aspect_ratio.py +0 -194
  153. package/weekly-financial-event-report/scripts/extract_pdf_text_pdfkit.swift +0 -99
  154. package/weekly-financial-event-report/tests/test_extract_pdf_text_pdfkit.py +0 -64
@@ -0,0 +1,764 @@
1
+ /* architecture.css — declarative atlas styling.
2
+ *
3
+ * Design direction: dark "blueprint × editorial" — a deep ink ground
4
+ * with a faint vellum grid; a Fraunces serif display voice for titles
5
+ * and prose, a Geist body for UI text, and JetBrains Mono for technical
6
+ * accents (slugs, edge labels, chips). Bold maximalism is avoided; the
7
+ * page sells through precision spacing, soft inner glows, and one
8
+ * accent color (signal teal) rather than rainbow chrome.
9
+ *
10
+ * Class hooks are owned by render.js; agents never hand-author the
11
+ * markup. The CLI copies this file into <outDir>/assets/.
12
+ */
13
+
14
+ :root {
15
+ color-scheme: dark;
16
+
17
+ /* ink ground */
18
+ --ink: #060B12;
19
+ --ink-1: #0B131F;
20
+ --ink-2: #0F1B2A;
21
+ --ink-3: #142336;
22
+ --ink-4: #1B304A;
23
+
24
+ /* rules and dividers */
25
+ --rule: #1F3651;
26
+ --rule-soft: #16263B;
27
+
28
+ /* vellum (foreground) */
29
+ --vellum: #EDE7D8;
30
+ --vellum-soft: #C8C2B3;
31
+ --vellum-muted: #8A99AE;
32
+
33
+ /* one accent color carries the brand */
34
+ --accent: #66E5C7;
35
+ --accent-warm: #F4B850;
36
+ --accent-rose: #F47391;
37
+ --accent-violet: #B79EFF;
38
+
39
+ /* sub-module kind palette */
40
+ --kind-ui: #7DD3FC;
41
+ --kind-api: #B79EFF;
42
+ --kind-service: #66E5C7;
43
+ --kind-db: #F4B850;
44
+ --kind-pure-fn: #C9C3B3;
45
+ --kind-queue: #F47391;
46
+ --kind-external: #FF9B6A;
47
+
48
+ /* edge palette */
49
+ --edge-call: #7DD3FC;
50
+ --edge-return: #C9C3B3;
51
+ --edge-data-row: #F4B850;
52
+ --edge-failure: #F47391;
53
+
54
+ /* shadows */
55
+ --shadow-card: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 30px 60px -30px rgba(0, 0, 0, 0.7), 0 18px 40px -30px rgba(102, 229, 199, 0.10);
56
+
57
+ /* type stack — distinctive, not generic */
58
+ --font-display: 'Fraunces', 'Iowan Old Style', 'Charter', 'Georgia', serif;
59
+ --font-ui: 'Geist', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
60
+ --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
61
+ }
62
+
63
+ * { box-sizing: border-box; }
64
+
65
+ html, body { margin: 0; padding: 0; }
66
+
67
+ body {
68
+ min-height: 100vh;
69
+ background:
70
+ radial-gradient(1200px 600px at 90% -200px, rgba(102, 229, 199, 0.10), transparent 60%),
71
+ radial-gradient(900px 500px at -10% 110%, rgba(183, 158, 255, 0.07), transparent 60%),
72
+ var(--ink);
73
+ color: var(--vellum);
74
+ font-family: var(--font-ui);
75
+ font-feature-settings: 'ss01', 'cv11';
76
+ -webkit-font-smoothing: antialiased;
77
+ text-rendering: optimizeLegibility;
78
+ position: relative;
79
+ overflow-x: hidden;
80
+ }
81
+
82
+ /* faint vellum grid behind everything — looks like blueprint paper */
83
+ body::before {
84
+ content: '';
85
+ position: fixed;
86
+ inset: 0;
87
+ background-image:
88
+ linear-gradient(to right, rgba(237, 231, 216, 0.025) 1px, transparent 1px),
89
+ linear-gradient(to bottom, rgba(237, 231, 216, 0.025) 1px, transparent 1px);
90
+ background-size: 48px 48px;
91
+ pointer-events: none;
92
+ z-index: 0;
93
+ mask-image: radial-gradient(ellipse at 50% 30%, black 0%, transparent 80%);
94
+ }
95
+
96
+ a { color: var(--accent); text-decoration: none; }
97
+ a:hover {
98
+ color: var(--vellum);
99
+ text-decoration: underline;
100
+ text-decoration-color: var(--accent);
101
+ text-decoration-thickness: 1.5px;
102
+ text-underline-offset: 4px;
103
+ }
104
+
105
+ h1, h2 { margin: 0; font-weight: 500; }
106
+ h1 {
107
+ font-family: var(--font-display);
108
+ font-weight: 380;
109
+ font-size: clamp(34px, 4vw, 52px);
110
+ letter-spacing: -0.028em;
111
+ line-height: 1.05;
112
+ color: var(--vellum);
113
+ font-variation-settings: 'opsz' 96, 'SOFT' 30;
114
+ }
115
+ h2 {
116
+ font-family: var(--font-ui);
117
+ font-size: 11px;
118
+ font-weight: 600;
119
+ letter-spacing: 0.18em;
120
+ text-transform: uppercase;
121
+ color: var(--vellum-muted);
122
+ margin-bottom: 14px;
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 12px;
126
+ }
127
+ h2::before {
128
+ content: '';
129
+ display: inline-block;
130
+ width: 22px;
131
+ height: 1px;
132
+ background: linear-gradient(90deg, var(--accent), transparent);
133
+ }
134
+
135
+ p { line-height: 1.6; color: var(--vellum-soft); }
136
+
137
+ /* =================================================================
138
+ atlas (macro)
139
+ ================================================================= */
140
+ .atlas-header {
141
+ position: relative;
142
+ padding: 56px 56px 32px;
143
+ border-bottom: 1px solid var(--rule-soft);
144
+ z-index: 1;
145
+ }
146
+ .atlas-header::before {
147
+ content: 'ATLAS · MACRO';
148
+ position: absolute;
149
+ top: 28px;
150
+ left: 56px;
151
+ font-family: var(--font-mono);
152
+ font-size: 11px;
153
+ letter-spacing: 0.32em;
154
+ color: var(--accent);
155
+ }
156
+ .atlas-header h1 { margin-top: 18px; }
157
+ .atlas-summary {
158
+ font-family: var(--font-display);
159
+ font-style: italic;
160
+ font-weight: 350;
161
+ font-size: 18px;
162
+ color: var(--vellum-soft);
163
+ max-width: 80ch;
164
+ margin: 20px 0 0;
165
+ line-height: 1.55;
166
+ }
167
+
168
+ .atlas-main {
169
+ position: relative;
170
+ z-index: 1;
171
+ display: grid;
172
+ grid-template-columns: minmax(0, 3fr) minmax(300px, 1fr);
173
+ gap: 28px;
174
+ padding: 32px 56px 64px;
175
+ align-items: start;
176
+ }
177
+
178
+ .atlas-canvas {
179
+ position: relative;
180
+ background: linear-gradient(180deg, rgba(15, 27, 42, 0.92), rgba(11, 19, 31, 0.92));
181
+ border: 1px solid var(--rule);
182
+ border-radius: 18px;
183
+ padding: 0;
184
+ box-shadow: var(--shadow-card);
185
+ overflow: hidden;
186
+ }
187
+ .atlas-canvas::before {
188
+ content: 'MACRO DIAGRAM';
189
+ position: absolute;
190
+ top: 18px;
191
+ left: 22px;
192
+ font-family: var(--font-mono);
193
+ font-size: 10px;
194
+ letter-spacing: 0.28em;
195
+ color: var(--accent);
196
+ z-index: 3;
197
+ }
198
+
199
+ .atlas-canvas__toolbar {
200
+ position: absolute;
201
+ top: 12px;
202
+ right: 14px;
203
+ display: flex;
204
+ gap: 4px;
205
+ z-index: 3;
206
+ background: rgba(6, 11, 18, 0.65);
207
+ border: 1px solid var(--rule);
208
+ border-radius: 10px;
209
+ padding: 4px;
210
+ -webkit-backdrop-filter: blur(6px);
211
+ backdrop-filter: blur(6px);
212
+ }
213
+ .atlas-canvas__toolbar button {
214
+ background: transparent;
215
+ color: var(--vellum-soft);
216
+ border: 0;
217
+ padding: 4px 12px;
218
+ border-radius: 6px;
219
+ cursor: pointer;
220
+ font-family: var(--font-mono);
221
+ font-size: 11px;
222
+ letter-spacing: 0.08em;
223
+ }
224
+ .atlas-canvas__toolbar button:hover { background: var(--ink-3); color: var(--accent); }
225
+
226
+ /* Fixed-aspect viewport: the diagram always occupies the same block
227
+ * regardless of its viewBox aspect ratio, so horizontally-biased
228
+ * atlases no longer collapse to a thin strip. The SVG fills both axes
229
+ * via preserveAspectRatio="xMidYMid meet" (rendered as 100% / 100%). */
230
+ .atlas-canvas__viewport {
231
+ position: relative;
232
+ width: 100%;
233
+ height: clamp(480px, 68vh, 760px);
234
+ overflow: hidden;
235
+ margin-top: 44px;
236
+ background:
237
+ radial-gradient(circle at 50% 38%, rgba(102, 229, 199, 0.05), transparent 60%),
238
+ linear-gradient(180deg, #05101B, #03080F);
239
+ }
240
+ .atlas-canvas__viewport::after {
241
+ /* blueprint grid only inside the viewport */
242
+ content: '';
243
+ position: absolute;
244
+ inset: 0;
245
+ background-image:
246
+ linear-gradient(to right, rgba(237, 231, 216, 0.04) 1px, transparent 1px),
247
+ linear-gradient(to bottom, rgba(237, 231, 216, 0.04) 1px, transparent 1px);
248
+ background-size: 32px 32px;
249
+ pointer-events: none;
250
+ }
251
+ .atlas-canvas__viewport.is-grabbing { cursor: grabbing; }
252
+ .atlas-canvas__viewport:not(.is-grabbing) { cursor: grab; }
253
+
254
+ .atlas-svg {
255
+ position: relative;
256
+ z-index: 1;
257
+ width: 100%;
258
+ height: 100%;
259
+ display: block;
260
+ user-select: none;
261
+ touch-action: none;
262
+ overflow: visible;
263
+ }
264
+
265
+ .atlas-legend {
266
+ list-style: none;
267
+ margin: 0;
268
+ padding: 14px 22px 18px;
269
+ display: flex;
270
+ gap: 22px;
271
+ flex-wrap: wrap;
272
+ font-family: var(--font-mono);
273
+ font-size: 11px;
274
+ letter-spacing: 0.06em;
275
+ color: var(--vellum-muted);
276
+ border-top: 1px solid var(--rule-soft);
277
+ }
278
+ .atlas-legend li { display: inline-flex; align-items: center; gap: 8px; }
279
+ .legend-swatch { display: inline-block; width: 22px; height: 2px; border-radius: 1px; }
280
+ .legend-swatch--call { background: var(--edge-call); }
281
+ .legend-swatch--return { background: var(--edge-return); }
282
+ .legend-swatch--data-row { background: var(--edge-data-row); }
283
+ .legend-swatch--failure { background: var(--edge-failure); }
284
+
285
+ .atlas-index {
286
+ background: rgba(15, 27, 42, 0.6);
287
+ border: 1px solid var(--rule);
288
+ border-radius: 18px;
289
+ padding: 22px 22px 14px;
290
+ max-height: clamp(520px, 72vh, 820px);
291
+ overflow: auto;
292
+ box-shadow: var(--shadow-card);
293
+ }
294
+ .atlas-index::-webkit-scrollbar { width: 10px; }
295
+ .atlas-index::-webkit-scrollbar-thumb { background: var(--ink-4); border-radius: 999px; }
296
+ .atlas-index::-webkit-scrollbar-track { background: transparent; }
297
+
298
+ .atlas-submodule-index {
299
+ list-style: none;
300
+ padding: 0;
301
+ margin: 0;
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 12px;
305
+ }
306
+ .atlas-submodule-index__item { position: relative; }
307
+ .atlas-submodule-index__item a {
308
+ display: grid;
309
+ grid-template-columns: minmax(0, 1fr) auto;
310
+ align-items: center;
311
+ gap: 4px 12px;
312
+ padding: 12px 14px;
313
+ background: linear-gradient(180deg, rgba(31, 54, 81, 0.42), rgba(15, 27, 42, 0.6));
314
+ border: 1px solid var(--rule);
315
+ border-radius: 12px;
316
+ color: var(--vellum);
317
+ transition: transform 140ms ease, border-color 140ms ease, background 140ms ease;
318
+ }
319
+ .atlas-submodule-index__item a:hover {
320
+ transform: translateY(-1px);
321
+ border-color: var(--accent);
322
+ background: linear-gradient(180deg, rgba(102, 229, 199, 0.07), rgba(15, 27, 42, 0.7));
323
+ }
324
+ .atlas-submodule-index__feature {
325
+ font-family: var(--font-mono);
326
+ font-size: 10px;
327
+ color: var(--vellum-muted);
328
+ text-transform: uppercase;
329
+ letter-spacing: 0.2em;
330
+ grid-column: 1 / 3;
331
+ }
332
+ .atlas-submodule-index__sub {
333
+ font-family: var(--font-display);
334
+ font-weight: 500;
335
+ font-size: 18px;
336
+ letter-spacing: -0.01em;
337
+ color: var(--vellum);
338
+ }
339
+ .atlas-submodule-index__kind {
340
+ font-family: var(--font-mono);
341
+ font-size: 10px;
342
+ padding: 3px 10px;
343
+ border-radius: 999px;
344
+ background: rgba(11, 19, 31, 0.85);
345
+ border: 1px solid var(--rule);
346
+ color: var(--vellum-soft);
347
+ text-transform: uppercase;
348
+ letter-spacing: 0.1em;
349
+ }
350
+ .atlas-submodule-index__role {
351
+ margin: 6px 14px 12px;
352
+ font-size: 12.5px;
353
+ color: var(--vellum-muted);
354
+ line-height: 1.5;
355
+ }
356
+
357
+ /* =================================================================
358
+ SVG macro nodes & edges
359
+ ================================================================= */
360
+ .m-cluster__bg {
361
+ fill: rgba(11, 19, 31, 0.55);
362
+ stroke: rgba(237, 231, 216, 0.08);
363
+ stroke-width: 1;
364
+ }
365
+ .m-cluster__title {
366
+ font-family: var(--font-mono);
367
+ font-size: 12px;
368
+ fill: var(--vellum-muted);
369
+ font-weight: 600;
370
+ letter-spacing: 0.22em;
371
+ text-transform: uppercase;
372
+ }
373
+ .m-node { cursor: pointer; }
374
+ .m-node rect {
375
+ fill: rgba(6, 11, 18, 0.92);
376
+ stroke: var(--rule);
377
+ stroke-width: 1;
378
+ transition: stroke 160ms ease, fill 160ms ease, filter 160ms ease;
379
+ }
380
+ .m-node:hover rect,
381
+ .m-node:focus rect,
382
+ .m-node:focus-visible rect {
383
+ stroke: var(--accent);
384
+ stroke-width: 1.6;
385
+ fill: rgba(102, 229, 199, 0.08);
386
+ filter: drop-shadow(0 0 14px rgba(102, 229, 199, 0.35));
387
+ }
388
+ .m-node:focus { outline: none; }
389
+ .m-node__title {
390
+ font-family: var(--font-display);
391
+ font-size: 15px;
392
+ font-weight: 500;
393
+ fill: var(--vellum);
394
+ letter-spacing: -0.01em;
395
+ }
396
+ .m-node__kind {
397
+ font-family: var(--font-mono);
398
+ font-size: 10px;
399
+ fill: var(--vellum-muted);
400
+ text-transform: uppercase;
401
+ letter-spacing: 0.22em;
402
+ }
403
+ .m-node__role {
404
+ font-family: var(--font-ui);
405
+ font-size: 11.5px;
406
+ fill: var(--vellum-soft);
407
+ }
408
+ .m-node:hover .m-node__title,
409
+ .m-node:focus .m-node__title { fill: var(--accent); }
410
+
411
+ .m-node--ui rect { stroke: var(--kind-ui); }
412
+ .m-node--api rect { stroke: var(--kind-api); }
413
+ .m-node--service rect { stroke: var(--kind-service); }
414
+ .m-node--db rect { stroke: var(--kind-db); }
415
+ .m-node--pure-fn rect { stroke: var(--kind-pure-fn); }
416
+ .m-node--queue rect { stroke: var(--kind-queue); }
417
+ .m-node--external rect { stroke: var(--kind-external); stroke-dasharray: 5 4; }
418
+
419
+ .m-edge path { stroke-width: 1.6; }
420
+ .m-edge--call path { stroke: var(--edge-call); }
421
+ .m-edge--return path { stroke: var(--edge-return); stroke-dasharray: 6 4; }
422
+ .m-edge--data-row path { stroke: var(--edge-data-row); }
423
+ .m-edge--failure path { stroke: var(--edge-failure); stroke-dasharray: 3 3; }
424
+
425
+ .m-arrow path { fill: currentColor; }
426
+ .m-arrow--call { color: var(--edge-call); }
427
+ .m-arrow--return { color: var(--edge-return); }
428
+ .m-arrow--data-row { color: var(--edge-data-row); }
429
+ .m-arrow--failure { color: var(--edge-failure); }
430
+
431
+ .m-edge__label {
432
+ fill: var(--vellum-soft);
433
+ font-family: var(--font-mono);
434
+ font-size: 11px;
435
+ letter-spacing: 0.02em;
436
+ paint-order: stroke fill;
437
+ stroke: var(--ink);
438
+ stroke-width: 3.5;
439
+ stroke-linejoin: round;
440
+ pointer-events: none;
441
+ }
442
+
443
+ /* Cross-feature edges are routed across the entire atlas and tend to
444
+ be the loudest lines on screen. Dim them so intra-feature flow
445
+ reads first; restore full strength on hover/focus. */
446
+ .m-edge--cross path { opacity: 0.5; stroke-width: 1.1; }
447
+ .m-edge--cross .m-edge__label { opacity: 0.7; }
448
+ .m-edge--cross:hover path,
449
+ .m-edge--cross:focus-within path { opacity: 1; stroke-width: 1.8; }
450
+ .m-edge--cross:hover .m-edge__label,
451
+ .m-edge--cross:focus-within .m-edge__label { opacity: 1; }
452
+
453
+ /* =================================================================
454
+ feature page
455
+ ================================================================= */
456
+ .feature-header, .submodule-header {
457
+ position: relative;
458
+ padding: 52px 56px 28px;
459
+ border-bottom: 1px solid var(--rule-soft);
460
+ z-index: 1;
461
+ }
462
+ .feature-breadcrumb, .submodule-breadcrumb {
463
+ font-family: var(--font-mono);
464
+ font-size: 11px;
465
+ letter-spacing: 0.22em;
466
+ color: var(--vellum-muted);
467
+ text-transform: uppercase;
468
+ margin-bottom: 22px;
469
+ }
470
+ .feature-breadcrumb a, .submodule-breadcrumb a { color: var(--accent); }
471
+ .feature-depends {
472
+ font-family: var(--font-mono);
473
+ font-size: 12px;
474
+ color: var(--vellum-muted);
475
+ margin: 18px 0 0;
476
+ }
477
+ .feature-main, .submodule-main {
478
+ position: relative;
479
+ padding: 36px 56px 64px;
480
+ display: flex;
481
+ flex-direction: column;
482
+ gap: 40px;
483
+ z-index: 1;
484
+ }
485
+ .feature-story p {
486
+ font-family: var(--font-display);
487
+ font-size: 19px;
488
+ font-weight: 350;
489
+ line-height: 1.6;
490
+ max-width: 70ch;
491
+ color: var(--vellum-soft);
492
+ }
493
+
494
+ .submodule-nav {
495
+ list-style: none;
496
+ padding: 0;
497
+ margin: 0;
498
+ display: grid;
499
+ gap: 16px;
500
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
501
+ }
502
+ .submodule-card {
503
+ background: linear-gradient(180deg, rgba(31, 54, 81, 0.42), rgba(15, 27, 42, 0.65));
504
+ border: 1px solid var(--rule);
505
+ border-radius: 14px;
506
+ padding: 18px 18px 16px;
507
+ transition: transform 160ms ease, border-color 160ms ease;
508
+ }
509
+ .submodule-card:hover { transform: translateY(-2px); border-color: var(--accent); }
510
+ .submodule-card__link {
511
+ display: flex;
512
+ align-items: center;
513
+ justify-content: space-between;
514
+ color: var(--vellum);
515
+ font-family: var(--font-display);
516
+ font-weight: 500;
517
+ font-size: 18px;
518
+ }
519
+ .submodule-card__name { letter-spacing: -0.01em; }
520
+ .submodule-card__kind {
521
+ font-family: var(--font-mono);
522
+ font-size: 10px;
523
+ padding: 3px 10px;
524
+ border-radius: 999px;
525
+ border: 1px solid var(--rule);
526
+ color: var(--vellum-soft);
527
+ text-transform: uppercase;
528
+ letter-spacing: 0.1em;
529
+ }
530
+ .submodule-card__role {
531
+ margin: 10px 0 0;
532
+ font-size: 13px;
533
+ color: var(--vellum-muted);
534
+ line-height: 1.5;
535
+ }
536
+
537
+ .feature-edges__list {
538
+ list-style: none;
539
+ padding: 0;
540
+ margin: 0;
541
+ display: flex;
542
+ flex-direction: column;
543
+ gap: 10px;
544
+ }
545
+ .feature-edges__item {
546
+ display: grid;
547
+ grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 2.2fr);
548
+ gap: 12px;
549
+ padding: 12px 16px;
550
+ background: rgba(15, 27, 42, 0.55);
551
+ border: 1px solid var(--rule);
552
+ border-radius: 12px;
553
+ font-size: 13px;
554
+ align-items: center;
555
+ }
556
+ .feature-edges__endpoints { font-family: var(--font-mono); color: var(--vellum); }
557
+ .feature-edges__kind {
558
+ font-family: var(--font-mono);
559
+ font-size: 10px;
560
+ color: var(--vellum-muted);
561
+ text-transform: uppercase;
562
+ letter-spacing: 0.18em;
563
+ }
564
+ .feature-edges__label { color: var(--vellum-soft); }
565
+ .feature-edges__item--call { border-left: 3px solid var(--edge-call); }
566
+ .feature-edges__item--return { border-left: 3px solid var(--edge-return); }
567
+ .feature-edges__item--data-row { border-left: 3px solid var(--edge-data-row); }
568
+ .feature-edges__item--failure { border-left: 3px solid var(--edge-failure); }
569
+
570
+ /* =================================================================
571
+ submodule page
572
+ ================================================================= */
573
+ .submodule-kind {
574
+ display: inline-block;
575
+ font-family: var(--font-mono);
576
+ font-size: 11px;
577
+ padding: 4px 12px;
578
+ border-radius: 999px;
579
+ border: 1px solid var(--rule);
580
+ color: var(--accent);
581
+ margin-left: 14px;
582
+ vertical-align: middle;
583
+ text-transform: uppercase;
584
+ letter-spacing: 0.18em;
585
+ }
586
+ .submodule-role {
587
+ color: var(--vellum-soft);
588
+ margin: 14px 0 0;
589
+ max-width: 70ch;
590
+ font-family: var(--font-display);
591
+ font-size: 17px;
592
+ font-weight: 350;
593
+ line-height: 1.55;
594
+ }
595
+
596
+ .sub-table {
597
+ width: 100%;
598
+ border-collapse: collapse;
599
+ font-size: 13px;
600
+ background: rgba(15, 27, 42, 0.55);
601
+ border: 1px solid var(--rule);
602
+ border-radius: 12px;
603
+ overflow: hidden;
604
+ }
605
+ .sub-table th, .sub-table td {
606
+ padding: 12px 16px;
607
+ border-bottom: 1px solid var(--rule-soft);
608
+ text-align: left;
609
+ vertical-align: top;
610
+ }
611
+ .sub-table tr:last-child td { border-bottom: none; }
612
+ .sub-table th {
613
+ font-family: var(--font-mono);
614
+ font-size: 10px;
615
+ color: var(--vellum-muted);
616
+ text-transform: uppercase;
617
+ letter-spacing: 0.16em;
618
+ background: rgba(6, 11, 18, 0.7);
619
+ }
620
+ .sub-table td { color: var(--vellum-soft); font-family: var(--font-mono); }
621
+ .sub-table td:first-child { color: var(--vellum); }
622
+
623
+ .sub-section__empty {
624
+ color: var(--vellum-muted);
625
+ font-style: italic;
626
+ font-size: 13px;
627
+ padding: 14px 18px;
628
+ background: rgba(15, 27, 42, 0.4);
629
+ border: 1px dashed var(--rule);
630
+ border-radius: 12px;
631
+ font-family: var(--font-display);
632
+ }
633
+
634
+ .sub-dataflow__canvas {
635
+ position: relative;
636
+ background: linear-gradient(180deg, rgba(15, 27, 42, 0.92), rgba(11, 19, 31, 0.92));
637
+ border: 1px solid var(--rule);
638
+ border-radius: 18px;
639
+ padding: 0;
640
+ box-shadow: var(--shadow-card);
641
+ overflow: hidden;
642
+ }
643
+ .sub-dataflow__canvas::before {
644
+ content: 'INTERNAL FLOW';
645
+ position: absolute;
646
+ top: 18px;
647
+ left: 22px;
648
+ font-family: var(--font-mono);
649
+ font-size: 10px;
650
+ letter-spacing: 0.28em;
651
+ color: var(--accent);
652
+ z-index: 3;
653
+ }
654
+ .sub-dataflow__toolbar {
655
+ position: absolute;
656
+ top: 12px;
657
+ right: 14px;
658
+ display: flex;
659
+ gap: 4px;
660
+ z-index: 3;
661
+ background: rgba(6, 11, 18, 0.65);
662
+ border: 1px solid var(--rule);
663
+ border-radius: 10px;
664
+ padding: 4px;
665
+ -webkit-backdrop-filter: blur(6px);
666
+ backdrop-filter: blur(6px);
667
+ }
668
+ .sub-dataflow__toolbar button {
669
+ background: transparent;
670
+ color: var(--vellum-soft);
671
+ border: 0;
672
+ padding: 4px 12px;
673
+ border-radius: 6px;
674
+ cursor: pointer;
675
+ font-family: var(--font-mono);
676
+ font-size: 11px;
677
+ letter-spacing: 0.08em;
678
+ }
679
+ .sub-dataflow__toolbar button:hover { background: var(--ink-3); color: var(--accent); }
680
+
681
+ .sub-dataflow__viewport {
682
+ position: relative;
683
+ width: 100%;
684
+ height: clamp(480px, 64vh, 720px);
685
+ overflow: hidden;
686
+ margin-top: 44px;
687
+ background:
688
+ radial-gradient(circle at 50% 38%, rgba(102, 229, 199, 0.05), transparent 60%),
689
+ linear-gradient(180deg, #05101B, #03080F);
690
+ }
691
+ .sub-dataflow__viewport::after {
692
+ content: '';
693
+ position: absolute;
694
+ inset: 0;
695
+ background-image:
696
+ linear-gradient(to right, rgba(237, 231, 216, 0.04) 1px, transparent 1px),
697
+ linear-gradient(to bottom, rgba(237, 231, 216, 0.04) 1px, transparent 1px);
698
+ background-size: 32px 32px;
699
+ pointer-events: none;
700
+ }
701
+ .sub-dataflow__viewport.is-grabbing { cursor: grabbing; }
702
+ .sub-dataflow__viewport:not(.is-grabbing) { cursor: grab; }
703
+ .sub-dataflow__svg {
704
+ position: relative;
705
+ z-index: 1;
706
+ width: 100%;
707
+ height: 100%;
708
+ display: block;
709
+ user-select: none;
710
+ touch-action: none;
711
+ overflow: visible;
712
+ }
713
+ .sub-dataflow__badge { fill: rgba(102, 229, 199, 0.12); stroke: var(--accent); stroke-width: 1.5; }
714
+ .sub-dataflow__badge-text {
715
+ font-family: var(--font-mono);
716
+ font-size: 14px;
717
+ font-weight: 600;
718
+ fill: var(--accent);
719
+ letter-spacing: 0.04em;
720
+ }
721
+ .sub-dataflow__step .sub-dataflow__box {
722
+ fill: rgba(15, 27, 42, 0.78);
723
+ stroke: var(--rule);
724
+ stroke-width: 1;
725
+ filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.35));
726
+ }
727
+ .sub-dataflow__step:hover .sub-dataflow__box { stroke: var(--accent); }
728
+ .sub-dataflow__text {
729
+ font-family: var(--font-display);
730
+ font-size: 15px;
731
+ font-weight: 400;
732
+ fill: var(--vellum);
733
+ }
734
+ .sub-dataflow__arrow { stroke: var(--accent); stroke-width: 1.5; opacity: 0.7; }
735
+ .sub-dataflow__fn-bg { fill: rgba(102, 229, 199, 0.16); stroke: var(--accent); stroke-width: 1; }
736
+ .sub-dataflow__fn-text {
737
+ font-family: var(--font-mono);
738
+ font-size: 11px;
739
+ font-weight: 600;
740
+ fill: var(--accent);
741
+ letter-spacing: 0.04em;
742
+ }
743
+ .sub-dataflow__chip {
744
+ font-family: var(--font-mono);
745
+ font-size: 11px;
746
+ font-weight: 500;
747
+ }
748
+ .sub-dataflow__chip--reads { fill: var(--kind-service); }
749
+ .sub-dataflow__chip--writes { fill: var(--kind-db); }
750
+ .sub-dataflow__empty {
751
+ color: var(--vellum-muted);
752
+ font-style: italic;
753
+ padding: 14px 18px;
754
+ border: 1px dashed var(--rule);
755
+ border-radius: 12px;
756
+ font-family: var(--font-display);
757
+ }
758
+
759
+ @media (max-width: 960px) {
760
+ .atlas-header, .feature-header, .submodule-header { padding: 40px 28px 24px; }
761
+ .atlas-header::before { left: 28px; }
762
+ .atlas-main { grid-template-columns: 1fr; padding: 24px 28px 48px; gap: 22px; }
763
+ .feature-main, .submodule-main { padding: 28px 28px 48px; gap: 32px; }
764
+ }