@sleep2agi/agent-network-dashboard 0.5.3-preview.99 → 0.5.4

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 (410) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +2 -0
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/diagnostics/route-bundle-stats.json +35 -35
  5. package/.next/fallback-build-manifest.json +3 -3
  6. package/.next/prerender-manifest.json +29 -0
  7. package/.next/routes-manifest.json +12 -0
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +2 -2
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  12. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +2 -2
  17. package/.next/server/app/_not-found.rsc +13 -13
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  24. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  25. package/.next/server/app/admin.html +2 -2
  26. package/.next/server/app/admin.rsc +15 -15
  27. package/.next/server/app/admin.segments/_full.segment.rsc +15 -15
  28. package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
  29. package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
  30. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  31. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
  32. package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
  33. package/.next/server/app/api/hub/upload/route/app-paths-manifest.json +3 -0
  34. package/.next/server/app/api/hub/upload/route/build-manifest.json +9 -0
  35. package/.next/server/app/api/hub/upload/route/server-reference-manifest.json +4 -0
  36. package/.next/server/app/api/hub/upload/route.js +7 -0
  37. package/.next/server/app/api/hub/upload/route.js.map +5 -0
  38. package/.next/server/app/api/hub/upload/route.js.nft.json +1 -0
  39. package/.next/server/app/api/hub/upload/route_client-reference-manifest.js +3 -0
  40. package/.next/server/app/index.html +2 -2
  41. package/.next/server/app/index.rsc +15 -15
  42. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  43. package/.next/server/app/index.segments/_full.segment.rsc +15 -15
  44. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  45. package/.next/server/app/index.segments/_index.segment.rsc +7 -7
  46. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  47. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/login.html +2 -2
  49. package/.next/server/app/login.rsc +15 -15
  50. package/.next/server/app/login.segments/_full.segment.rsc +15 -15
  51. package/.next/server/app/login.segments/_head.segment.rsc +4 -4
  52. package/.next/server/app/login.segments/_index.segment.rsc +7 -7
  53. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  54. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  55. package/.next/server/app/login.segments/login.segment.rsc +3 -3
  56. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  57. package/.next/server/app/logs.html +2 -2
  58. package/.next/server/app/logs.rsc +15 -15
  59. package/.next/server/app/logs.segments/_full.segment.rsc +15 -15
  60. package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
  61. package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
  62. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  63. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
  64. package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
  65. package/.next/server/app/manifest.webmanifest/route/app-paths-manifest.json +3 -0
  66. package/.next/server/app/manifest.webmanifest/route/build-manifest.json +9 -0
  67. package/.next/server/app/manifest.webmanifest/route/server-reference-manifest.json +4 -0
  68. package/.next/server/app/manifest.webmanifest/route.js +8 -0
  69. package/.next/server/app/manifest.webmanifest/route.js.map +5 -0
  70. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
  71. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +3 -0
  72. package/.next/server/app/manifest.webmanifest.body +1 -0
  73. package/.next/server/app/manifest.webmanifest.meta +1 -0
  74. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/messages.html +2 -2
  76. package/.next/server/app/messages.rsc +15 -15
  77. package/.next/server/app/messages.segments/_full.segment.rsc +15 -15
  78. package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
  79. package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
  80. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  81. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
  82. package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
  83. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  84. package/.next/server/app/node.html +2 -2
  85. package/.next/server/app/node.rsc +15 -15
  86. package/.next/server/app/node.segments/_full.segment.rsc +15 -15
  87. package/.next/server/app/node.segments/_head.segment.rsc +4 -4
  88. package/.next/server/app/node.segments/_index.segment.rsc +7 -7
  89. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  90. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
  91. package/.next/server/app/node.segments/node.segment.rsc +3 -3
  92. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  93. package/.next/server/app/nodes.html +2 -2
  94. package/.next/server/app/nodes.rsc +15 -15
  95. package/.next/server/app/nodes.segments/_full.segment.rsc +15 -15
  96. package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
  97. package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
  98. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  99. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
  100. package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
  101. package/.next/server/app/page_client-reference-manifest.js +1 -1
  102. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  103. package/.next/server/app/server-logs.html +2 -2
  104. package/.next/server/app/server-logs.rsc +15 -15
  105. package/.next/server/app/server-logs.segments/_full.segment.rsc +15 -15
  106. package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
  107. package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
  108. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  109. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
  110. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
  111. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  112. package/.next/server/app/settings/networks.html +2 -2
  113. package/.next/server/app/settings/networks.rsc +15 -15
  114. package/.next/server/app/settings/networks.segments/_full.segment.rsc +15 -15
  115. package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
  116. package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
  117. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  118. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
  119. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
  120. package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
  121. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  122. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/settings/tokens.html +2 -2
  124. package/.next/server/app/settings/tokens.rsc +15 -15
  125. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +15 -15
  126. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
  127. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
  128. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  129. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
  130. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
  131. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
  132. package/.next/server/app/settings.html +2 -2
  133. package/.next/server/app/settings.rsc +15 -15
  134. package/.next/server/app/settings.segments/_full.segment.rsc +15 -15
  135. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  136. package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
  137. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  138. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  139. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  140. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  141. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  142. package/.next/server/app/tasks.html +2 -2
  143. package/.next/server/app/tasks.rsc +15 -15
  144. package/.next/server/app/tasks.segments/_full.segment.rsc +15 -15
  145. package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
  146. package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
  147. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  148. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
  149. package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
  150. package/.next/server/app-paths-manifest.json +2 -0
  151. package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js +18 -0
  152. package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js.map +1 -0
  153. package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js +3 -0
  154. package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js +3 -0
  155. package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js.map +1 -0
  156. package/.next/server/chunks/{[externals]__11vad82._.js → [externals]__036g1.i._.js} +2 -2
  157. package/.next/server/chunks/[externals]__036g1.i._.js.map +1 -0
  158. package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js +3 -0
  159. package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js.map +1 -0
  160. package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js → [root-of-the-server]__0jndzts._.js} +2 -2
  161. package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js.map → [root-of-the-server]__0jndzts._.js.map} +1 -1
  162. package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js +1 -1
  163. package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js.map +1 -1
  164. package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
  165. package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
  166. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js +1 -1
  167. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js.map +1 -1
  168. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js +1 -1
  169. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js.map +1 -1
  170. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js +1 -1
  171. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js.map +1 -1
  172. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js +1 -1
  173. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js.map +1 -1
  174. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js +1 -1
  175. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js.map +1 -1
  176. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js +1 -1
  177. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js.map +1 -1
  178. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js +1 -1
  179. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js.map +1 -1
  180. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js +1 -1
  181. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js.map +1 -1
  182. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js +1 -1
  183. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js.map +1 -1
  184. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js +1 -1
  185. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js.map +1 -1
  186. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js +1 -1
  187. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js.map +1 -1
  188. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js +1 -1
  189. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js.map +1 -1
  190. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js +1 -1
  191. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js.map +1 -1
  192. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js +1 -1
  193. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js.map +1 -1
  194. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js +1 -1
  195. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js.map +1 -1
  196. package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js +4 -1
  197. package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js.map +1 -1
  198. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
  199. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
  200. package/.next/server/chunks/ssr/[root-of-the-server]__0u5aqkk._.js +1 -1
  201. package/.next/server/chunks/ssr/[root-of-the-server]__0u5aqkk._.js.map +1 -1
  202. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
  203. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  204. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  205. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  206. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  207. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  208. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
  209. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
  210. package/.next/server/middleware-build-manifest.js +3 -3
  211. package/.next/server/middleware.js +2 -2
  212. package/.next/server/middleware.js.nft.json +1 -1
  213. package/.next/server/pages/404.html +2 -2
  214. package/.next/server/pages/500.html +1 -1
  215. package/.next/static/chunks/{07~8sx3_5uiox.js → 04wjx7vbxusw5.js} +4 -1
  216. package/.next/static/chunks/089t1exs6apb8.js +4 -0
  217. package/.next/static/chunks/{084e1mr6acfta.js → 09e8kxo30n5cf.js} +1 -1
  218. package/.next/static/chunks/{0v4-5tng.uh.7.js → 0k-c1chkvf78s.js} +2 -2
  219. package/.next/static/chunks/0v2~nlpk-cx6v.css +2 -0
  220. package/.next/static/chunks/0xsye-9kffdi0.js +1 -0
  221. package/.next/static/chunks/0~rx_~akeylmq.js +1 -0
  222. package/.next/trace +2 -2
  223. package/.next/trace-build +1 -1
  224. package/.next/types/routes.d.ts +2 -1
  225. package/.next/types/validator.ts +9 -0
  226. package/app/api/hub/send/route.ts +11 -2
  227. package/app/api/hub/servers/route.ts +3 -29
  228. package/app/api/hub/upload/route.ts +83 -0
  229. package/app/components/AppShell.tsx +3 -1
  230. package/app/components/MobileNav.tsx +45 -0
  231. package/app/components/TaskChatPanel.tsx +130 -6
  232. package/app/components/TopoGraph.tsx +4591 -216
  233. package/app/globals.css +839 -0
  234. package/app/layout.tsx +6 -0
  235. package/app/lib/serverDedupe.ts +122 -0
  236. package/app/lib/vendorIdentity.ts +74 -56
  237. package/app/manifest.ts +23 -0
  238. package/package.json +4 -4
  239. package/public/vendors/claude.svg +7 -8
  240. package/public/vendors/minimax.svg +8 -9
  241. package/public/vendors/openai.svg +8 -10
  242. package/scripts/p157-rc2-dedup-test.mjs +110 -0
  243. package/scripts/topo-a11y-titles-catalog-test.mjs +132 -0
  244. package/scripts/topo-active-links-chip-halo-layers-test.mjs +81 -0
  245. package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
  246. package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
  247. package/scripts/topo-animation-temporal-modes-catalog-test.mjs +144 -0
  248. package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
  249. package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
  250. package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
  251. package/scripts/topo-avatar-rotate-test.mjs +85 -0
  252. package/scripts/topo-avatar-scale-test.mjs +89 -0
  253. package/scripts/topo-badge-chat-gate-test.mjs +74 -0
  254. package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
  255. package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
  256. package/scripts/topo-canvas-desc-a11y-test.mjs +87 -0
  257. package/scripts/topo-canvas-entrance-animation-test.mjs +117 -0
  258. package/scripts/topo-canvas-scan-beam-diagonal-test.mjs +148 -0
  259. package/scripts/topo-canvas-scan-beam-test.mjs +109 -0
  260. package/scripts/topo-canvas-scan-beam-vertical-test.mjs +123 -0
  261. package/scripts/topo-card-chat-brightness-test.mjs +86 -0
  262. package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
  263. package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
  264. package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
  265. package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
  266. package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
  267. package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
  268. package/scripts/topo-chip-pin-halo-test.mjs +85 -0
  269. package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
  270. package/scripts/topo-chrome-fullscreen-breath-test.mjs +121 -0
  271. package/scripts/topo-chrome-layout-trailer-breath-test.mjs +86 -0
  272. package/scripts/topo-chrome-nodesize-trailer-breath-test.mjs +86 -0
  273. package/scripts/topo-chrome-reset-breath-test.mjs +115 -0
  274. package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
  275. package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
  276. package/scripts/topo-chrome-zoom-wrapper-breath-test.mjs +85 -0
  277. package/scripts/topo-click-ripple-glow-test.mjs +86 -0
  278. package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
  279. package/scripts/topo-click-ripple-sw-test.mjs +110 -0
  280. package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
  281. package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
  282. package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
  283. package/scripts/topo-dual-axis-surfaces-catalog-test.mjs +94 -0
  284. package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
  285. package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
  286. package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
  287. package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
  288. package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
  289. package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
  290. package/scripts/topo-edge-chat-gate-test.mjs +71 -0
  291. package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
  292. package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
  293. package/scripts/topo-edge-pin-halo-test.mjs +99 -0
  294. package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
  295. package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
  296. package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
  297. package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
  298. package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
  299. package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
  300. package/scripts/topo-group-box-brightness-test.mjs +84 -0
  301. package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
  302. package/scripts/topo-group-chat-gate-test.mjs +77 -0
  303. package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
  304. package/scripts/topo-group-tint-brightness-test.mjs +82 -0
  305. package/scripts/topo-h2-dual-axis-breath-test.mjs +92 -0
  306. package/scripts/topo-h2-triple-axis-breath-test.mjs +142 -0
  307. package/scripts/topo-halo-chat-gate-test.mjs +72 -0
  308. package/scripts/topo-hover-detail-halo-test.mjs +76 -0
  309. package/scripts/topo-hub-a11y-title-test.mjs +95 -0
  310. package/scripts/topo-hub-core-brightness-test.mjs +82 -0
  311. package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
  312. package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
  313. package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
  314. package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
  315. package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
  316. package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
  317. package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
  318. package/scripts/topo-kicker-breath-test.mjs +100 -0
  319. package/scripts/topo-kicker-dual-axis-breath-test.mjs +81 -0
  320. package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
  321. package/scripts/topo-kicker-triple-axis-breath-test.mjs +124 -0
  322. package/scripts/topo-label-card-brightness-test.mjs +81 -0
  323. package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
  324. package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
  325. package/scripts/topo-legend-count-brightness-test.mjs +80 -0
  326. package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
  327. package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
  328. package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
  329. package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
  330. package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
  331. package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
  332. package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
  333. package/scripts/topo-live-lanes.mjs +48 -0
  334. package/scripts/topo-minimap-container-halo-test.mjs +82 -0
  335. package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
  336. package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
  337. package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
  338. package/scripts/topo-more-footer-brightness-test.mjs +94 -0
  339. package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
  340. package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
  341. package/scripts/topo-node-label-card-halo-test.mjs +76 -0
  342. package/scripts/topo-nodesize-brightness-test.mjs +82 -0
  343. package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
  344. package/scripts/topo-overlap-test.mjs +22 -8
  345. package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
  346. package/scripts/topo-panel-rect-halo-test.mjs +90 -0
  347. package/scripts/topo-panel-titles-dual-axis-breath-test.mjs +94 -0
  348. package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
  349. package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
  350. package/scripts/topo-pip-brightness-test.mjs +85 -0
  351. package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
  352. package/scripts/topo-r717-scan-beam-pair-pattern-test.mjs +100 -0
  353. package/scripts/topo-r717-triple-axis-pair-pattern-test.mjs +113 -0
  354. package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +117 -0
  355. package/scripts/topo-recent-count-brightness-test.mjs +84 -0
  356. package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
  357. package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
  358. package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
  359. package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
  360. package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
  361. package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
  362. package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
  363. package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
  364. package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
  365. package/scripts/topo-reset-brightness-test.mjs +83 -0
  366. package/scripts/topo-respiratory-axis-count-stats-test.mjs +154 -0
  367. package/scripts/topo-respiratory-patterns-catalog-test.mjs +112 -0
  368. package/scripts/topo-respiratory-rolodex-test.mjs +83 -0
  369. package/scripts/topo-respiratory-tiers-catalog-test.mjs +119 -0
  370. package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +127 -0
  371. package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
  372. package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
  373. package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
  374. package/scripts/topo-section-title-breath-test.mjs +83 -0
  375. package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
  376. package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
  377. package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
  378. package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
  379. package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
  380. package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
  381. package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
  382. package/scripts/topo-svg-title-a11y-r731-test.mjs +93 -0
  383. package/scripts/topo-svg-title-a11y-test.mjs +88 -0
  384. package/scripts/topo-title-block-entrance-animation-test.mjs +127 -0
  385. package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
  386. package/scripts/topo-tree-diag.mjs +95 -0
  387. package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
  388. package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
  389. package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
  390. package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
  391. package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
  392. package/scripts/topo-watermark-dual-axis-breath-test.mjs +88 -0
  393. package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
  394. package/scripts/topo-watermark-triple-axis-breath-test.mjs +129 -0
  395. package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
  396. package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
  397. package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
  398. package/scripts/topo-zoom-level-breath-test.mjs +87 -0
  399. package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
  400. package/scripts/topo-zoom-level-dual-axis-breath-test.mjs +83 -0
  401. package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
  402. package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +148 -0
  403. package/.next/static/chunks/09oxd2mm27b_n.js +0 -1
  404. package/.next/static/chunks/0ots8-uksxz9p.js +0 -4
  405. package/.next/static/chunks/0voxs92keb6tg.js +0 -1
  406. package/.next/static/chunks/13~aih56vx-cf.css +0 -2
  407. /package/.next/server/chunks/{[externals]__11vad82._.js.map → 0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js.map} +0 -0
  408. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_buildManifest.js +0 -0
  409. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_clientMiddlewareManifest.js +0 -0
  410. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_ssgManifest.js +0 -0
package/app/globals.css CHANGED
@@ -1100,6 +1100,845 @@ body {
1100
1100
  animation: anet-topo-brand-logo-breath-kf 5s ease-in-out infinite;
1101
1101
  }
1102
1102
 
1103
+ /* Round 683 — brand 书生 logo extends single-layer drop-shadow hover
1104
+ (R604, Tailwind `hover:drop-shadow-[0_0_8px_currentColor]`) to the
1105
+ multi-layer halo family vocabulary: near 8px + far 16px (2× blur
1106
+ stride) at currentColor (inherits inline style.color = teal #0d9488
1107
+ / cyan #67e8f9), stacked with brightness(1.10). Matches R642-R667
1108
+ 0.5×-falloff convention by using currentColor for both layers —
1109
+ the same hue at native alpha layers up because drop-shadow alpha
1110
+ accumulates additively when stacked.
1111
+ Pure CSS `:hover` so no new React state needed; the SVG element
1112
+ listens via its own pseudo-class. Inline transition list already
1113
+ covers `filter 200ms ease-out` (R557) so the multi-layer halo eases
1114
+ under the same cadence. Tailwind v4 utility composition for multi-
1115
+ drop-shadow doesn't work cleanly (per R659 detour note), so dropping
1116
+ the utility classes (`hover:brightness-110`, `hover:drop-shadow-[...]`)
1117
+ in favor of an explicit CSS rule that wins over the cascade.
1118
+ 42nd anchor in multi-layer halo family — first brand-mark anchor. */
1119
+ .anet-topo-brand-logo-mark:hover {
1120
+ filter: drop-shadow(0 0 8px currentColor)
1121
+ drop-shadow(0 0 16px currentColor)
1122
+ brightness(1.10);
1123
+ }
1124
+
1125
+ /* Round 684 — title-block H2 "Command mesh" gains multi-layer halo
1126
+ via the wrapper's `:hover` (sibling pattern to R683 brand logo —
1127
+ both lift together when ANY surface in the title-block cluster
1128
+ is hovered, including the brand logo, kicker, or H2 itself).
1129
+ Pre-R684 the H2 had only 2 typographic hover axes (R554 tracking-
1130
+ tighter + R556 font-bold) via group-hover Tailwind utilities; the
1131
+ paint axis was untouched. R684 adds the multi-layer halo paint
1132
+ axis to the H2's hover signature — same near + far layered glow
1133
+ vocabulary the 42 other surfaces in the family share.
1134
+ Stride: 4 + 8px (2× blur stride at h2 scale, text-lg = 18px —
1135
+ smaller than brand logo's 8+16 since the H2 is text not graphic).
1136
+ Tint: currentColor — inherits the H2's resolved fill color
1137
+ (white on cyber, darker on light theme overrides).
1138
+ No brightness multiply — H2 text-white is already near-peak
1139
+ luminance on cyber; adding brightness would push past saturation.
1140
+ The selector targets the H2 via its data-attr `data-topo-section-
1141
+ title` nested under the title-block wrapper's group container
1142
+ (`data-topo-section-titleblock-group`). Inline `transition-
1143
+ [letter-spacing,font-weight]` on the H2 doesn't include filter,
1144
+ so the halo would snap on. Add a transition rule here so the
1145
+ halo eases under the same 200ms cadence as the existing 2 axes —
1146
+ keeps the cluster's hover gesture motion-coherent.
1147
+ 43rd anchor in multi-layer halo family — sibling to R683 brand
1148
+ logo, closing the title-block cluster's paint-axis halo at the
1149
+ H2 element scope. */
1150
+ [data-topo-section-titleblock-group]:hover [data-topo-section-title] {
1151
+ filter: drop-shadow(0 0 4px currentColor)
1152
+ drop-shadow(0 0 8px currentColor);
1153
+ }
1154
+ [data-topo-section-title] {
1155
+ transition: letter-spacing 200ms ease-out,
1156
+ font-weight 200ms ease-out,
1157
+ filter 200ms ease-out;
1158
+ }
1159
+
1160
+ /* Round 685 — kicker "Network Topology" gains multi-layer halo via
1161
+ the title-block wrapper's `:hover`, closing the title-block trio
1162
+ at 3/3 paint-axis halo (logo R683 + H2 R684 + kicker R685). Pre-
1163
+ R685 the kicker had only 2 hover axes (R555 tracking-spread +
1164
+ color lift gray-500 → gray-400); the paint axis was untouched.
1165
+ R685 adds 2-layer drop-shadow at 2 + 4px stride (2× blur stride
1166
+ at kicker scale — text-xs = 12px, smaller than H2's 4+8 and
1167
+ logo's 8+16). currentColor inherits the kicker's resolved fill
1168
+ (gray-500 rest / gray-400 hover post-R555) so the halo paints
1169
+ in the same hue as the text.
1170
+ Selector targets the kicker via `data-topo-section-kicker` data-
1171
+ attr (already present on the kicker div). Sibling rule + transition
1172
+ pattern to R684 H2; both fire on the wrapper's :hover and ease at
1173
+ 200ms.
1174
+ When the user hovers the title cluster, ALL 3 surfaces (logo +
1175
+ H2 + kicker) glow simultaneously — cluster reads as one
1176
+ coherent hover unit, paint axis CLOSED across all surfaces.
1177
+ 44th anchor in multi-layer halo family — completes title-block
1178
+ trio 3/3. */
1179
+ [data-topo-section-titleblock-group]:hover [data-topo-section-kicker] {
1180
+ filter: drop-shadow(0 0 2px currentColor)
1181
+ drop-shadow(0 0 4px currentColor);
1182
+ }
1183
+ [data-topo-section-kicker] {
1184
+ transition: letter-spacing 200ms ease-out,
1185
+ color 200ms ease-out,
1186
+ filter 200ms ease-out;
1187
+ }
1188
+
1189
+ /* Round 697 — chrome strip segmented-control wrappers gain a wrapper-
1190
+ level multi-layer halo when ANY inner button is hovered. Pre-R697
1191
+ the 3 chrome wrappers (Layout / nodeSize / zoom) had only static
1192
+ border + background — individual buttons inside halo via R674/R675/
1193
+ R673/R668 but the parent wrapper stayed flat. R697 uses CSS `:has()`
1194
+ to detect inner button hover and applies a 2-layer drop-shadow at
1195
+ cyan-300 (#67e8f9) — compact-chrome tier (2+4 stride, 0.5/0.25 alpha).
1196
+
1197
+ When user hovers a child Ring/Grid/S/M/L/zoom button, the WRAPPER
1198
+ itself echoes the inner-button halo outward in a soft glow — chrome
1199
+ strip reads as one coherent "this control group is active" gesture
1200
+ alongside the per-button cyan halo.
1201
+
1202
+ Cyan-300 hardcoded (vs theme-driven pal.legendAccent) since CSS
1203
+ doesn't have a clean handle on the React-computed palette token at
1204
+ this wrapper level. Cyan-300 ≈ light theme's pal.legendAccent
1205
+ (#0d9488 teal-600) is bluish; the halo is hover-only + brief so the
1206
+ slight cross-theme hue mismatch is acceptable.
1207
+
1208
+ transition: filter 200ms ease-out — matches the inner buttons'
1209
+ 200ms cadence so wrapper + buttons ease together on hover-in/out.
1210
+
1211
+ 53rd anchor in multi-layer halo family — first wrapper-level
1212
+ has-hover anchor. Closes chrome-strip "active control group"
1213
+ signal at the parent scope alongside R667-R675 per-button anchors. */
1214
+ [data-topo-chrome-layout-trailer]:has(button:hover),
1215
+ [data-topo-chrome-fleet-group-trailer]:has(button:hover),
1216
+ [data-topo-chrome-zoom-wrapper]:has(button:hover) {
1217
+ filter: drop-shadow(0 0 2px rgba(103, 232, 249, 0.5))
1218
+ drop-shadow(0 0 4px rgba(103, 232, 249, 0.25));
1219
+ }
1220
+ [data-topo-chrome-layout-trailer],
1221
+ [data-topo-chrome-fleet-group-trailer],
1222
+ [data-topo-chrome-zoom-wrapper] {
1223
+ transition: background-color 200ms ease-out,
1224
+ border-color 200ms ease-out,
1225
+ filter 200ms ease-out;
1226
+ }
1227
+
1228
+ /* ─────────────────────────────────────────────────────────────────────
1229
+ Round 698 — vendor-distribution chip-row outer wrapper joins the
1230
+ R697 wrapper-level :has() halo family. Pre-R698 only the chrome-strip
1231
+ wrappers (Layout/nodeSize/zoom) echoed inner-button hover at the
1232
+ parent scope; the vendor-distribution wrapper stayed flat even though
1233
+ its inner vendor letter chips already halo'd per-element (R676/R688/
1234
+ R690).
1235
+
1236
+ R697 used `:has(button:hover)` because chrome wrappers contain real
1237
+ <button> children. The vendor letter chips are `<span role="button">`
1238
+ (clickable spans, not buttons — preserves inline-baseline alignment
1239
+ with the title text). The :has() selector variant `[role="button"]:hover`
1240
+ extends R697's wrapper-level vocabulary from real-button children
1241
+ to ARIA-button children — same gesture, broader applicability.
1242
+
1243
+ Cyan-300 (#67e8f9) at 2+4 stride, 0.5/0.25 alpha — matches R697
1244
+ cadence exactly. Transition matches the per-chip 200ms hover cascade.
1245
+ When user hovers any A:N / O:N / 书:N / ?:N chip, the outer chip-row
1246
+ wrapper echoes the per-chip halo outward — reads as "this vendor-
1247
+ distribution control group is active" alongside the existing R676
1248
+ vendor letter glyph halo + R688 count suffix halo.
1249
+
1250
+ 54th anchor in multi-layer halo family — 2nd wrapper-level :has()
1251
+ anchor. First :has() rule targeting [role="button"] (vs <button>)
1252
+ children. Closes vendor-chip-row "active control group" signal at
1253
+ the parent scope. */
1254
+ [data-topo-chrome-vendor-distribution-wrapper]:has([role="button"]:hover) {
1255
+ filter: drop-shadow(0 0 2px rgba(103, 232, 249, 0.5))
1256
+ drop-shadow(0 0 4px rgba(103, 232, 249, 0.25));
1257
+ }
1258
+ [data-topo-chrome-vendor-distribution-wrapper] {
1259
+ transition: background-color 200ms ease-out,
1260
+ border-color 200ms ease-out,
1261
+ filter 200ms ease-out;
1262
+ }
1263
+
1264
+ /* ─────────────────────────────────────────────────────────────────────
1265
+ Round 699 — kicker "Network Topology" at-rest breathing fade.
1266
+
1267
+ The H2 below ("Command mesh") already had its hover halo via the R684
1268
+ descendant rule; the kicker eyebrow above had R685 hover halo + R555
1269
+ tracking-expand, but at REST it sat at a fixed alpha — static, no
1270
+ sign of life. R699 adds a slow respiratory cycle (opacity 0.78 ↔ 1
1271
+ at 6 s ease-in-out infinite) on `.anet-topo-kicker-breath`.
1272
+
1273
+ 6 s is deliberately ~3× slower than the sidebar brand-pulse (1.6 s)
1274
+ and the recent-hot pulse (3 s) — kicker isn't signaling urgency, just
1275
+ "this section is alive". Group-hover overrides via R555/R685 take
1276
+ precedence the moment user enters the title-block, so the breath
1277
+ never competes with the gesture vocabulary.
1278
+
1279
+ Pure opacity: no transform / no filter blur / no size change → text
1280
+ bounding box stable → topo-overlap-test grid + ring untouched. Pairs
1281
+ sequentially with `anet-brand-pulse-kf` (1.6 s, brand status) and
1282
+ `anet-recent-hot-pulse-kf` (3 s, recent-signal heat) as the third
1283
+ distinct respiratory rhythm in the topo canvas.
1284
+
1285
+ prefers-reduced-motion: reduce → animation: none (kicker freezes at
1286
+ resting alpha = 1, sibling to other R29-family motion guards).
1287
+ ───────────────────────────────────────────────────────────────────── */
1288
+ /* Round 699 + R714 — kicker "Network Topology" dual-axis breath.
1289
+ R699 introduced 6s opacity breath (0.78 ↔ 1, ~22%); R714 adds a
1290
+ SECOND axis in the same @keyframes: a transform scale (0.995 ↔ 1,
1291
+ ~0.5%). Two axes share cadence (6s) so they breathe IN PHASE —
1292
+ the dimmest moment is also the smallest moment, mirroring the
1293
+ R711 H2 dual-axis at the title-block's eyebrow tier.
1294
+
1295
+ Why scale 0.5%: the kicker is the section's secondary text (eyebrow
1296
+ above the H2 headline). Its alpha range is wider (22% vs H2's 12%)
1297
+ so a slightly wider scale range (0.5% vs H2's 0.3%) keeps the
1298
+ axes proportionally weighted. Still sub-pixel at xs font-size
1299
+ (~12 px text height → 0.06px swing) — imperceptible per-frame,
1300
+ accumulates as "the eyebrow gently pulses with the breath".
1301
+
1302
+ Mirrors R711 H2 pattern (HTML text dual-axis: opacity + CSS
1303
+ transform scale) — both title-block text tiers now have dual-axis
1304
+ breath, closing title-block dual-axis symmetry across kicker and
1305
+ H2. Brand-logo (the 3rd title-block trio member) still single-axis
1306
+ since it already has its own 5-axis hover signature (R548/R549/R553/
1307
+ R557/R604) plus 5s breath; further axes would oversubscribe the
1308
+ brand mark. Pattern budget: title-block trio members get dual-axis
1309
+ if their hover signature is sparse, single-axis if rich.
1310
+
1311
+ transform-origin defaults to center — kicker scales around its own
1312
+ midpoint, no glyph drift. paint-only → flex parent stable → topo-
1313
+ overlap-test untouched. prefers-reduced-motion: reduce neutralizes. */
1314
+ /* Round 740 — one-time canvas entrance animation. Plays on FIRST PAINT
1315
+ only, then the canvas sits at scale(1) opacity(1) for the rest of
1316
+ the session. Distinct from all prior animation families:
1317
+ - breath family (R699+) is rest-axis infinite
1318
+ - ambient family (R735+) is sweep-axis infinite
1319
+ - R740 entrance is ONE-SHOT (no `infinite` keyword) — plays once
1320
+ Subsequent re-mounts (route changes, etc.) replay the animation —
1321
+ intended as a "the canvas just arrived" signal to the user.
1322
+
1323
+ Animation: 0% scale(0.99) opacity(0.8) → 100% scale(1) opacity(1)
1324
+ over 600ms with ease-out timing. Subtle: the scale change is only
1325
+ 1% (0.99 → 1.00); opacity ramps from 0.8 to 1.0. Reads as "settling
1326
+ in" — the canvas zooms in slightly while fading in.
1327
+
1328
+ transform-origin defaults to 50% 50% (canvas center), so the scale
1329
+ ripple comes from the middle outward.
1330
+
1331
+ prefers-reduced-motion guard: when reduced motion is preferred, the
1332
+ class isn't applied (JSX-level gate in TopoGraph.tsx), so the CSS
1333
+ animation never runs. Belt-and-suspenders @media block below
1334
+ neutralises if the class somehow ends up applied. */
1335
+ @keyframes anet-topo-canvas-entrance-kf {
1336
+ 0% { transform: scale(0.99); opacity: 0.8; }
1337
+ 100% { transform: scale(1); opacity: 1; }
1338
+ }
1339
+ .anet-topo-canvas-entrance {
1340
+ animation: anet-topo-canvas-entrance-kf 600ms ease-out;
1341
+ transform-origin: 50% 50%;
1342
+ }
1343
+ @media (prefers-reduced-motion: reduce) {
1344
+ .anet-topo-canvas-entrance { animation: none; }
1345
+ }
1346
+
1347
+ /* Round 728 — recent + legend panel titles join the triple-axis tier
1348
+ at 8 s, forming the "8 s triple-axis PAIR" (mirror to R724's 6 s pair).
1349
+ Both panel titles already share R700/R701 SMIL opacity (8 s) +
1350
+ R713 SMIL font-size (8 s) — R728 adds a 3rd CSS-animated axis:
1351
+ text-shadow glow at the same 8 s cadence in phase.
1352
+
1353
+ Same hybrid SMIL + CSS pattern as R722 watermark: SMIL drives SVG
1354
+ attributes (opacity, font-size); CSS drives the text-shadow CSS
1355
+ property on the same <text> element. Modern browsers honour both
1356
+ vocabularies side-by-side without conflict.
1357
+
1358
+ Multi-cadence triple-axis tier post-R728 (6 members across 4 cadences):
1359
+ 6 s kicker + watermark (R721/R722, "6 s pair")
1360
+ 8 s recent + legend titles (R728, "8 s pair") ← this round
1361
+ 9 s zoom-level readout (R727)
1362
+ 10 s H2 section title (R725)
1363
+
1364
+ Pattern structural mirror: R724's 6 s pair (title-block + canvas-
1365
+ brand tiers) finds its sibling in R728's 8 s pair (panel-title tier).
1366
+ Both pairs use parity-shape (members at same cadence). Adds new
1367
+ R717 pattern entry `triple-axis-pair-8s` (shape `8s-triple-pair`)
1368
+ to formalize the structural mirror.
1369
+
1370
+ Glow tuning vs prior 4 triple-axis members:
1371
+ R721 kicker blur 6 px, alpha 0.30 @ 6 s (title-block, sharp)
1372
+ R722 watermark blur 8 px, alpha 0.20 @ 6 s (canvas-brand, quiet)
1373
+ R725 H2 blur 8 px, alpha 0.22 @ 10 s (title-block, mellow)
1374
+ R727 zoom-level blur 5 px, alpha 0.25 @ 9 s (data tier, sharp pill)
1375
+ R728 panel-pair blur 7 px, alpha 0.23 @ 8 s (panel-title) ← this round
1376
+ Mid-range blur (7 px) — between zoom-level (5 px pill) and H2 (8 px
1377
+ heading); alpha 0.23 — between H2 (0.22 mellow) and zoom-level (0.25)
1378
+ to position the panel-title glow as a "calm-medium" register that
1379
+ matches the panel titles' weight in the visual hierarchy (heading-
1380
+ weight but smaller fontSize than H2).
1381
+
1382
+ Gating: piggybacks on the existing JSX gates (R700: !reducedMotion &&
1383
+ !activeEdgeKey; R701: !reducedMotion && !pinnedStatus). The CSS class
1384
+ is applied conditionally; when ungated, both SMIL animates and CSS
1385
+ animation coexist. prefers-reduced-motion @media guard provides
1386
+ belt-and-suspenders. */
1387
+ @keyframes anet-topo-panel-title-glow-breath-kf {
1388
+ 0%, 100% { text-shadow: none; }
1389
+ 50% { text-shadow: 0 0 7px rgba(34, 211, 238, 0.23); }
1390
+ }
1391
+ .anet-topo-panel-title-glow-breath {
1392
+ animation: anet-topo-panel-title-glow-breath-kf 8s ease-in-out infinite;
1393
+ }
1394
+ @media (prefers-reduced-motion: reduce) {
1395
+ .anet-topo-panel-title-glow-breath { animation: none; }
1396
+ }
1397
+
1398
+ /* Round 722 — watermark text becomes the 2ND TRIPLE-axis surface,
1399
+ completing a "6 s triple-axis PAIR" with R721 kicker (both at the
1400
+ fastest dual-axis cadence, both with sparse hover signatures, both
1401
+ read-target text — symmetric structural mirror).
1402
+
1403
+ The watermark's prior axes:
1404
+ R519 SMIL opacity (6 s, 0.32 ↔ 0.48)
1405
+ R712 SMIL letter-spacing (6 s, 0.45 ↔ 0.55)
1406
+ R722 adds a 3rd CSS-animated axis on the SAME `<text>` element:
1407
+ R722 CSS text-shadow (6 s, none ↔ 0 0 8 px rgba(34, 211, 238, 0.20))
1408
+
1409
+ The SMIL animations (opacity + letter-spacing) drive SVG attributes
1410
+ in their own clock; the CSS animation drives `text-shadow` as a CSS
1411
+ property. SVG <text> in modern browsers honours both vocabularies
1412
+ on the same element — no conflict. The 6 s cadence shared across
1413
+ all 3 axes keeps them in phase: at the dimmest+tightest moment the
1414
+ glow appears; at the brightest+widest moment the glow is gone. One
1415
+ coherent inhale-exhale.
1416
+
1417
+ Glow tuning vs kicker (R721):
1418
+ kicker blur 6 px, alpha 0.30
1419
+ watermark blur 8 px, alpha 0.20
1420
+ The watermark text sits at canvas bottom-left at fontSize 11 with
1421
+ a base opacity of 0.4 (R282) — the glow needs more spread (8 vs 6)
1422
+ to register at that low base opacity, but less alpha (0.20 vs 0.30)
1423
+ to stay proportional to the wordmark's quieter visual register.
1424
+
1425
+ Gating: piggybacks on the existing R519 reducedMotion JSX gate
1426
+ (the entire <animate> tree only mounts when !reducedMotion). When
1427
+ reducedMotion is true the class is still applied but the @media
1428
+ (prefers-reduced-motion: reduce) below neutralises the CSS
1429
+ animation. Belt-and-suspenders. */
1430
+ @keyframes anet-topo-brand-watermark-glow-breath-kf {
1431
+ 0%, 100% { text-shadow: none; }
1432
+ 50% { text-shadow: 0 0 8px rgba(34, 211, 238, 0.20); }
1433
+ }
1434
+ .anet-topo-brand-watermark-glow-breath {
1435
+ animation: anet-topo-brand-watermark-glow-breath-kf 6s ease-in-out infinite;
1436
+ }
1437
+ @media (prefers-reduced-motion: reduce) {
1438
+ .anet-topo-brand-watermark-glow-breath { animation: none; }
1439
+ }
1440
+
1441
+ /* Round 721 — kicker becomes the family's first TRIPLE-axis breath
1442
+ surface. R699 opacity (6 s) + R714 transform-scale (6 s) joined by
1443
+ R721 text-shadow (6 s) — all 3 axes share the 6 s cadence in phase.
1444
+
1445
+ At rest peak (0%, 100%) the kicker reads as a static title;
1446
+ at mid-breath (50%) it dims (0.78), retracts (scale 0.995), AND
1447
+ emits a soft cyan glow (text-shadow 0 0 6px rgba(34, 211, 238, 0.30)).
1448
+ The glow appears OUT-OF-PHASE with the dim — as the text shrinks
1449
+ slightly it gains a subtle aura. Reads as an "inhale glow": a small
1450
+ visible payoff at the bottom of the breath cycle.
1451
+
1452
+ Why kicker first (vs other dual-axis surfaces):
1453
+ - kicker has the SPARSEST hover signature in the family — being
1454
+ below H2 (the page heading), it's read-target text, not an
1455
+ interactive surface. The breath family's "if hover sig sparse,
1456
+ dual-axis; if hover sig rich, single-axis" budget rule extends
1457
+ naturally to "if hover sig SPARSE, can go triple-axis".
1458
+ - 6 s is the fastest dual-axis cadence in the rolodex — at fast
1459
+ cadence the 3rd axis (a glow appear+disappear cycle every 3 s
1460
+ on each half) registers as ambient rhythm, not a distraction.
1461
+
1462
+ text-shadow chosen over letter-spacing or font-size because:
1463
+ - text-shadow doesn't reflow text (no horizontal motion)
1464
+ - glow against the dark canvas reads clearly without competing
1465
+ with the opacity dim
1466
+ - cyan tint at 30% alpha + 6 px blur is below the brightness
1467
+ threshold of any node halo (R674/R675 nodes use 0.5+ alpha)
1468
+
1469
+ Composition note: the R29 prefers-reduced-motion guard already
1470
+ neutralizes the entire 6 s animation; no separate text-shadow
1471
+ reduced-motion logic needed. */
1472
+ @keyframes anet-topo-kicker-breath-kf {
1473
+ 0%, 100% { opacity: 1; transform: scale(1); text-shadow: none; }
1474
+ 50% { opacity: 0.78; transform: scale(0.995); text-shadow: 0 0 6px rgba(34, 211, 238, 0.30); }
1475
+ }
1476
+ .anet-topo-kicker-breath {
1477
+ animation: anet-topo-kicker-breath-kf 6s ease-in-out infinite;
1478
+ }
1479
+ @media (prefers-reduced-motion: reduce) {
1480
+ .anet-topo-kicker-breath { animation: none; }
1481
+ }
1482
+
1483
+ /* Round 702 — H2 "Command mesh" at-rest breathing fade, completing the
1484
+ title-block respiratory trio (brand-logo 5 s / kicker 6 s / H2 10 s).
1485
+ Tighter alpha range (0.88 ↔ 1, ~12%) vs the kicker (0.78 ↔ 1, ~22%):
1486
+ H2 carries more visual weight, so a gentler breath keeps it from
1487
+ looking flickery. Slowest in the trio — 10 s reads as calm anchoring,
1488
+ not anxious. prefers-reduced-motion: reduce → animation: none,
1489
+ sibling to the R699 kicker guard. */
1490
+ /* Round 702 + R711 — H2 "Command mesh" dual-axis breath. R702 introduced
1491
+ the 10s opacity breath (0.88 ↔ 1, ~12%); R711 adds a SECOND axis in
1492
+ the same @keyframes: a transform scale (0.997 ↔ 1, ~0.3%). The two
1493
+ axes share cadence (10s) so they breathe in PHASE — the dimmest moment
1494
+ is also the smallest moment, like a single coherent inhale-exhale.
1495
+
1496
+ Why scale 0.3%: the H2 is the section's primary text identity; scale
1497
+ changes affect glyph rasterization at sub-pixel level. 0.3% range
1498
+ keeps the visible change at fraction of a pixel for a 40-px-tall text,
1499
+ imperceptible per-frame but cumulatively reads as "the title gently
1500
+ pulses with the breath", reinforcing the opacity dimming without
1501
+ adding new gesture. Scale doesn't affect layout flow (CSS transform
1502
+ is paint-only) — flex parent stays stable, overlap test safe.
1503
+
1504
+ First DUAL-AXIS breath anchor in the 呼吸感 family — establishes that
1505
+ future anchors can layer multiple animation properties on a single
1506
+ keyframe block for "deeper aliveness" on a single surface, without
1507
+ needing a second class or animation. Pattern budget: prefer single-
1508
+ axis on most anchors (visual hierarchy) and reserve dual-axis for
1509
+ primary identity surfaces (H2 here = first primary-identity dual). */
1510
+ /* Round 725 — H2 section title becomes the 3RD triple-axis surface,
1511
+ FIRST triple-axis member at a NON-6 s cadence (10 s). Establishes
1512
+ that the triple-axis TIER is multi-cadence rather than 6 s-locked —
1513
+ the R724 `triple-axis-pair` pattern stays valid for kicker+watermark
1514
+ at 6 s; H2 joins the triple-axis TIER as a solo 10 s member.
1515
+
1516
+ H2's prior dual-axis (R702 opacity + R711 transform-scale @ 10 s)
1517
+ gains a 3rd CSS-animated axis: text-shadow glow at 10 s in phase.
1518
+ Reads as a slow inhale glow on the section heading — calmer than
1519
+ the 6 s pair (kicker/watermark) because H2's slower cadence keeps
1520
+ the glow appearance interval at 5 s (vs 3 s for the 6 s tier).
1521
+
1522
+ Glow tuning vs kicker (R721) and watermark (R722):
1523
+ kicker blur 6 px, alpha 0.30 @ 6 s
1524
+ watermark blur 8 px, alpha 0.20 @ 6 s
1525
+ H2 blur 8 px, alpha 0.22 @ 10 s ← this round
1526
+ H2 sits between the two at alpha; its larger fontSize (section
1527
+ heading, much bigger than kicker/watermark) needs a wider blur
1528
+ (8 px to match watermark) but a slightly higher alpha than
1529
+ watermark (0.22 vs 0.20) because at H2's slower 10 s cadence the
1530
+ glow gets a longer dwell time at peak — proportionally tighter
1531
+ alpha would feel under-emphasised vs the 6 s pair's snappier peaks.
1532
+
1533
+ The triple-axis tier now has 3 members across 2 cadences:
1534
+ 6 s kicker + watermark (R724 "triple-axis-pair" pattern)
1535
+ 10 s H2 (solo)
1536
+ R725 doesn't add a new R717 pattern entry — H2 is a solo, not
1537
+ a pair. R723 catalog (triple-axis-surfaces) extends to 3 entries.
1538
+
1539
+ prefers-reduced-motion guard already in place on the existing
1540
+ R702 H2 breath class; this round's text-shadow axis joins the
1541
+ same animation rule and is neutralised by the same @media block. */
1542
+ @keyframes anet-topo-section-title-breath-kf {
1543
+ 0%, 100% { opacity: 1; transform: scale(1); text-shadow: none; }
1544
+ 50% { opacity: 0.88; transform: scale(0.997); text-shadow: 0 0 8px rgba(34, 211, 238, 0.22); }
1545
+ }
1546
+ .anet-topo-section-title-breath {
1547
+ animation: anet-topo-section-title-breath-kf 10s ease-in-out infinite;
1548
+ /* transform-origin defaults to 50% 50% which is what we want — the H2
1549
+ scales around its own center, no glyph drift. */
1550
+ }
1551
+ @media (prefers-reduced-motion: reduce) {
1552
+ .anet-topo-section-title-breath { animation: none; }
1553
+ }
1554
+
1555
+ /* Round 703 — chrome zoom-level readout at-rest breath. 9 s cadence sits
1556
+ between the 8 s panel titles and the 10 s H2 in the respiratory
1557
+ rolodex. Tighter alpha range (0.85 ↔ 1, ~15%) than the kicker —
1558
+ readout carries tabular numeric data, so it shouldn't drift too far
1559
+ from full opacity. Hover gate via the data attribute: when
1560
+ data-topo-chrome-zoom-level-hover="true", animation: none, and the
1561
+ existing R347 ls + R420 fw + R517 color + R593 brightness + R668
1562
+ halo 4-axis lift takes precedence cleanly. prefers-reduced-motion:
1563
+ reduce neutralizes, sibling to R699/R702 guards. */
1564
+ /* Round 703 + R715 — chrome zoom-level readout dual-axis breath.
1565
+ R703 introduced 9s opacity breath (0.85 ↔ 1, ~15%); R715 adds a
1566
+ SECOND axis in the same @keyframes: a transform scale (0.996 ↔ 1,
1567
+ ~0.4%). Two axes share cadence (9s) so they breathe IN PHASE —
1568
+ dimmest = smallest, mirroring R711 H2 / R714 kicker pattern at the
1569
+ CHROME DATA TIER (vs title-block primary text tier).
1570
+
1571
+ Why scale 0.4% on zoom-level (vs H2's 0.3%, kicker's 0.5%): zoom-
1572
+ level's alpha range is between H2 (12%) and kicker (22%) at 15%
1573
+ — scale axis interpolated to 0.4% keeps the three dual-axis HTML
1574
+ text surfaces co-proportioned. Sub-pixel at xs font-size → ~0.04px
1575
+ swing at ~10px text height; imperceptible per-frame, accumulates
1576
+ as "the readout pulses with the breath".
1577
+
1578
+ Pattern budget extension — chrome data tier dual-axis:
1579
+ R699+R714 kicker 6s eyebrow tier
1580
+ R703+R715 zoom-level 9s chrome data tier ← this round
1581
+ R702+R711 H2 10s primary headline tier
1582
+ The 6/9/10 s cadences and the kicker/zoom-level/H2 scale ratios
1583
+ (0.5/0.4/0.3 %) form a tier-graded ladder: faster cadence + larger
1584
+ scale on secondary-tier text; slower cadence + smaller scale on
1585
+ primary-tier text. Each tier has its own "tempo + amplitude"
1586
+ coupled signature — kicker pulses quickly-and-noticeably, H2
1587
+ pulses slowly-and-subtly, zoom-level sits between.
1588
+
1589
+ Hover gate via `[data-topo-chrome-zoom-level-hover="true"]` →
1590
+ animation: none, so R347/R420/R517/R593 hover axes take precedence
1591
+ without animation underneath. transform-origin defaults to center
1592
+ — pill scales around its own midpoint. prefers-reduced-motion:
1593
+ reduce also neutralizes. */
1594
+ /* Round 727 — zoom-level readout becomes the 4TH triple-axis surface and
1595
+ FIRST chrome-tier (data-tier) member to join the multi-cadence triple-
1596
+ axis tier. R703 opacity (9 s) + R715 transform-scale (9 s) joined by
1597
+ R727 text-shadow (9 s) — all 3 axes share the 9 s cadence in phase.
1598
+
1599
+ Multi-cadence triple-axis tier post-R727 (4 members across 3 cadences):
1600
+ 6 s kicker + watermark (title-block + canvas-brand tiers)
1601
+ 9 s zoom-level readout (data tier) ← this round
1602
+ 10 s H2 section title (title-block tier)
1603
+ Pattern budget extension: prior triple-axis members were all read-target
1604
+ text in primary-identity tiers (title-block + canvas-brand). R727 extends
1605
+ to the DATA tier — a chrome readout, not pure text. Justified because:
1606
+ - zoom-level's hover sig (R703 data-attr gate) is sparse: only the
1607
+ hover-tracking attr; no rich tactile axes
1608
+ - the surface is a single-tone monospace digit pill — visually quiet
1609
+ enough that a glow pulse remains subordinate to node halos
1610
+ - the chrome strip's "data tier" sub-role becomes a structural mirror
1611
+ of the title-block tier in the triple-axis context
1612
+
1613
+ Glow tuning vs prior 3 triple-axis members:
1614
+ R721 kicker blur 6 px, alpha 0.30 @ 6 s (title-block)
1615
+ R722 watermark blur 8 px, alpha 0.20 @ 6 s (canvas-brand)
1616
+ R725 H2 blur 8 px, alpha 0.22 @ 10 s (title-block)
1617
+ R727 zoom-level blur 5 px, alpha 0.25 @ 9 s (data tier) ← this round
1618
+ Smaller blur (5 px) for the smaller pill surface; mid-range alpha
1619
+ (0.25) between kicker (sharp+bright at 0.30) and H2 (medium at 0.22).
1620
+ At 9 s the glow appearance interval is ~4.5 s on each half — between
1621
+ the 3 s 6 s-pair peak and the 5 s H2 peak, matching the cadence
1622
+ interpolation.
1623
+
1624
+ Hover gate preserved: the existing R703 [data-topo-chrome-zoom-level-
1625
+ hover="true"] selector still gates the entire animation off when user
1626
+ interacts — R727's text-shadow is part of the same @keyframes block
1627
+ so it gets gated together. */
1628
+ @keyframes anet-topo-chrome-zoom-level-breath-kf {
1629
+ 0%, 100% { opacity: 1; transform: scale(1); text-shadow: none; }
1630
+ 50% { opacity: 0.85; transform: scale(0.996); text-shadow: 0 0 5px rgba(34, 211, 238, 0.25); }
1631
+ }
1632
+ .anet-topo-chrome-zoom-level-breath {
1633
+ animation: anet-topo-chrome-zoom-level-breath-kf 9s ease-in-out infinite;
1634
+ }
1635
+ .anet-topo-chrome-zoom-level-breath[data-topo-chrome-zoom-level-hover="true"] {
1636
+ animation: none;
1637
+ }
1638
+ @media (prefers-reduced-motion: reduce) {
1639
+ .anet-topo-chrome-zoom-level-breath { animation: none; }
1640
+ }
1641
+
1642
+ /* Round 704 — brand watermark WRAPPER envelope breath at 15 s — slowest
1643
+ tier in the respiratory rolodex. Inner "sleep2agi" text already
1644
+ breathes at 6 s (R519); this adds an outer wrapper envelope so the
1645
+ brand area has nested respiration (fast inner / slow outer). 0.85 ↔ 1
1646
+ alpha range (~15%) matches the R703 tabular/decorative surface band
1647
+ — heavy visual register shouldn't drift too far from full opacity.
1648
+
1649
+ Focal-recede gate via data-attr selector — when the wrapper's
1650
+ data-topo-brand-watermark-recede attr flips to "true" (user is
1651
+ hovering a node/edge/group on the canvas), animation: none gates
1652
+ off so the R525 inline opacity={0.7} attr takes effect cleanly.
1653
+ Pattern sibling to R703 zoom-level data-attr selector gate.
1654
+ prefers-reduced-motion: reduce also neutralizes. */
1655
+ @keyframes anet-topo-brand-watermark-envelope-breath-kf {
1656
+ 0%, 100% { opacity: 1; }
1657
+ 50% { opacity: 0.85; }
1658
+ }
1659
+ .anet-topo-brand-watermark-envelope-breath {
1660
+ animation: anet-topo-brand-watermark-envelope-breath-kf 15s ease-in-out infinite;
1661
+ }
1662
+ .anet-topo-brand-watermark-envelope-breath[data-topo-brand-watermark-recede="true"] {
1663
+ animation: none;
1664
+ }
1665
+ @media (prefers-reduced-motion: reduce) {
1666
+ .anet-topo-brand-watermark-envelope-breath { animation: none; }
1667
+ }
1668
+
1669
+ /* Round 705 — canvas crescent wrapper envelope breath at 13 s. Mirror
1670
+ to R704 watermark wrapper, closing canvas-brand-pair envelope
1671
+ symmetry. Cadence 13 s coprime with R704 (15 s) so the two never
1672
+ beat together when both visible. Tighter alpha range (0.30 ↔ 0.35,
1673
+ ~14%) deliberately hugs the existing inline 0.35 baseline — preserves
1674
+ the visible-state intent while adding nested respiration.
1675
+
1676
+ Two gate-off rules instead of one (R704 had a single recede gate):
1677
+ - visible="false" → animation: none, so inline opacity={0} holds when
1678
+ the recent panel is shown (crescent must be invisible).
1679
+ - recede="true" → animation: none, so inline opacity={0.245} holds
1680
+ when canvas attention is elsewhere.
1681
+ Either gate flips → CSS releases control to inline opacity attr.
1682
+ prefers-reduced-motion: reduce also neutralizes. */
1683
+ @keyframes anet-topo-brand-canvas-mark-envelope-breath-kf {
1684
+ 0%, 100% { opacity: 0.35; }
1685
+ 50% { opacity: 0.30; }
1686
+ }
1687
+ .anet-topo-brand-canvas-mark-envelope-breath {
1688
+ animation: anet-topo-brand-canvas-mark-envelope-breath-kf 13s ease-in-out infinite;
1689
+ }
1690
+ .anet-topo-brand-canvas-mark-envelope-breath[data-topo-brand-canvas-mark-visible="false"] {
1691
+ animation: none;
1692
+ }
1693
+ .anet-topo-brand-canvas-mark-envelope-breath[data-topo-brand-canvas-mark-recede="true"] {
1694
+ animation: none;
1695
+ }
1696
+ @media (prefers-reduced-motion: reduce) {
1697
+ .anet-topo-brand-canvas-mark-envelope-breath { animation: none; }
1698
+ }
1699
+
1700
+ /* Round 706 — title-block wrapper envelope breath at 11s. Mirrors the
1701
+ canvas-brand-pair nested-envelope pattern (R704/R705) at the title-
1702
+ block scope. 11s coprime with all 3 inner trio cadences (5, 6, 10) —
1703
+ no common factor → no phase lock with inner anchors. Tighter alpha
1704
+ range (0.92 ↔ 1, ~8%) than canvas-brand-pair envelopes because the
1705
+ title-block carries primary text identity; even subtle dimming on
1706
+ the H2 + kicker headline reads as flicker if too aggressive. 8%
1707
+ range = "barely-perceptible aliveness". prefers-reduced-motion:
1708
+ reduce neutralizes. */
1709
+ @keyframes anet-topo-title-block-envelope-breath-kf {
1710
+ 0%, 100% { opacity: 1; }
1711
+ 50% { opacity: 0.92; }
1712
+ }
1713
+ .anet-topo-title-block-envelope-breath {
1714
+ animation: anet-topo-title-block-envelope-breath-kf 11s ease-in-out infinite;
1715
+ }
1716
+ @media (prefers-reduced-motion: reduce) {
1717
+ .anet-topo-title-block-envelope-breath { animation: none; }
1718
+ }
1719
+
1720
+ /* Round 742 — title-block entrance, 2nd member of the entrance family.
1721
+ Staggered choreography with R740 canvas entrance:
1722
+ R740 canvas 0 → 600 ms (scale 0.99 → 1, opacity 0.8 → 1)
1723
+ R742 title-block 200 → 700 ms (translateY -4px → 0, opacity 0.7 → 1)
1724
+ The 100ms gap (600 → 700 ms) between canvas settle and title-block
1725
+ settle creates a perceived "shake out" — canvas arrives, then the
1726
+ heading writes itself into place. Both done by ~700 ms.
1727
+
1728
+ CSS cascade detail: when an element has BOTH .anet-topo-title-block-
1729
+ envelope-breath (R706, infinite 11s breath) AND .anet-topo-title-
1730
+ block-entrance (R742, one-shot 500ms), the `animation` property
1731
+ doesn't merge — only one wins. So R742 declares a COMPOUND animation
1732
+ listing BOTH (entrance first as one-shot, breath second as the
1733
+ ongoing infinite). Placed AFTER the R706 envelope-breath block in
1734
+ source order so cascade gives R742 the win when both classes are
1735
+ applied. When ONLY envelope-breath is applied (reducedMotion strips
1736
+ the entrance class via JSX), R706 rule takes over with just the
1737
+ breath animation. */
1738
+ @keyframes anet-topo-title-block-entrance-kf {
1739
+ 0% { transform: translateY(-4px); opacity: 0.7; }
1740
+ 100% { transform: translateY(0); opacity: 1; }
1741
+ }
1742
+ .anet-topo-title-block-entrance {
1743
+ animation:
1744
+ anet-topo-title-block-entrance-kf 500ms ease-out 200ms backwards,
1745
+ anet-topo-title-block-envelope-breath-kf 11s ease-in-out infinite;
1746
+ }
1747
+ @media (prefers-reduced-motion: reduce) {
1748
+ .anet-topo-title-block-entrance { animation: none; }
1749
+ }
1750
+
1751
+ /* Round 743 — chrome strip entrance, 3rd member of the entrance family,
1752
+ completing the entrance TRIO. Three-stage cascade:
1753
+ R740 canvas 0 → 600 ms scale 0.99→1, opacity 0.8→1
1754
+ R742 title-block 200 → 700 ms translateY -4→0, opacity 0.7→1
1755
+ R743 chrome strip 400 → 900 ms translateX 8→0, opacity 0.7→1
1756
+ Each stage offset +200 ms. translateX (not translateY) because the
1757
+ chrome strip docks at the canvas right edge — sliding in from its
1758
+ own edge reads as "docking into place".
1759
+
1760
+ The chrome strip wrapper div has no other animation, so a plain
1761
+ single-animation class works here (no compound needed like R742's
1762
+ title-block which collided with R706 envelope-breath). One-shot —
1763
+ no `infinite`, runs once per mount. prefers-reduced-motion JSX gate
1764
+ + CSS @media guard. */
1765
+ @keyframes anet-topo-chrome-strip-entrance-kf {
1766
+ 0% { transform: translateX(8px); opacity: 0.7; }
1767
+ 100% { transform: translateX(0); opacity: 1; }
1768
+ }
1769
+ .anet-topo-chrome-strip-entrance {
1770
+ animation: anet-topo-chrome-strip-entrance-kf 500ms ease-out 400ms backwards;
1771
+ }
1772
+ @media (prefers-reduced-motion: reduce) {
1773
+ .anet-topo-chrome-strip-entrance { animation: none; }
1774
+ }
1775
+
1776
+ /* Round 707 — chrome Layout wrapper at-rest breath at 17 s. Slowest tier
1777
+ among HTML chrome respiratory anchors (sibling to R703 zoom-level 9 s
1778
+ in the chrome strip's data tier; this 17 s lands in the chrome strip's
1779
+ control tier). 17 is prime → coprime with every other cadence in the
1780
+ rolodex (3/4/5/6/7/8/9/10/11/13/15). Never phase-locks with any other
1781
+ anchor.
1782
+
1783
+ Tightest alpha range yet (0.94 ↔ 1, ~6%) — the Layout buttons are
1784
+ interactive controls with active-state cyan tint; even ~10% dimming
1785
+ on the inner button color would feel jarring. 6% = "barely-perceptible
1786
+ aliveness" on a control group.
1787
+
1788
+ Hover gate via :has() selector — when user hovers any inner Ring/Grid
1789
+ button, the R697 wrapper-level halo (cyan filter) takes precedence;
1790
+ animation: none on hover pauses the breath so the halo reads crisp
1791
+ without underlying alpha drift. Third gate-off mechanism in the family
1792
+ vocabulary, sibling to R703 hover data-attr gate + R704/R705 recede
1793
+ gates. */
1794
+ @keyframes anet-topo-chrome-layout-trailer-breath-kf {
1795
+ 0%, 100% { opacity: 1; }
1796
+ 50% { opacity: 0.94; }
1797
+ }
1798
+ .anet-topo-chrome-layout-trailer-breath {
1799
+ animation: anet-topo-chrome-layout-trailer-breath-kf 17s ease-in-out infinite;
1800
+ }
1801
+ .anet-topo-chrome-layout-trailer-breath:has(button:hover) {
1802
+ animation: none;
1803
+ }
1804
+ @media (prefers-reduced-motion: reduce) {
1805
+ .anet-topo-chrome-layout-trailer-breath { animation: none; }
1806
+ }
1807
+
1808
+ /* Round 708 — chrome nodeSize wrapper at-rest breath at 19 s. Sibling
1809
+ to R707 Layout 17 s — both chrome control-tier wrappers carry the
1810
+ same alpha range (6%) + the same :has(button:hover) gate. Two coprime
1811
+ prime cadences (17, 19) form a chrome-control respiratory pair,
1812
+ pattern-parallel to canvas-brand-pair (R704/R705) coprime envelope
1813
+ pair. */
1814
+ @keyframes anet-topo-chrome-fleet-group-trailer-breath-kf {
1815
+ 0%, 100% { opacity: 1; }
1816
+ 50% { opacity: 0.94; }
1817
+ }
1818
+ .anet-topo-chrome-fleet-group-trailer-breath {
1819
+ animation: anet-topo-chrome-fleet-group-trailer-breath-kf 19s ease-in-out infinite;
1820
+ }
1821
+ .anet-topo-chrome-fleet-group-trailer-breath:has(button:hover) {
1822
+ animation: none;
1823
+ }
1824
+ @media (prefers-reduced-motion: reduce) {
1825
+ .anet-topo-chrome-fleet-group-trailer-breath { animation: none; }
1826
+ }
1827
+
1828
+ /* Round 709 — chrome zoom wrapper at-rest breath at 23 s. Closes the
1829
+ chrome control trio (R707 Layout 17s + R708 nodeSize 19s + R709 zoom
1830
+ 23s) with three adjacent prime coprime cadences. 23s slowest in the
1831
+ chrome trio — reads as "calm anchor for the viewport-control cluster"
1832
+ since zoom is the most functional of the 3 wrappers (its inner buttons
1833
+ compound viewport math). Same alpha (6%) + :has(button:hover) gate
1834
+ as siblings. */
1835
+ @keyframes anet-topo-chrome-zoom-wrapper-breath-kf {
1836
+ 0%, 100% { opacity: 1; }
1837
+ 50% { opacity: 0.94; }
1838
+ }
1839
+ .anet-topo-chrome-zoom-wrapper-breath {
1840
+ animation: anet-topo-chrome-zoom-wrapper-breath-kf 23s ease-in-out infinite;
1841
+ }
1842
+ .anet-topo-chrome-zoom-wrapper-breath:has(button:hover) {
1843
+ animation: none;
1844
+ }
1845
+ @media (prefers-reduced-motion: reduce) {
1846
+ .anet-topo-chrome-zoom-wrapper-breath { animation: none; }
1847
+ }
1848
+
1849
+ /* Round 718 — chrome reset button joins the respiratory family at 21 s.
1850
+ 5th anchor on the chrome-strip pattern, extending it from
1851
+ "tiered-with-trio" → "tiered-with-quartet". The chrome strip now
1852
+ spans a data tier + a prime quartet across control surfaces:
1853
+ R703 zoom-level readout 9 s (data tier)
1854
+ R707 Layout wrapper 17 s (control wrapper tier)
1855
+ R708 nodeSize wrapper 19 s (control wrapper tier)
1856
+ R718 reset button 21 s (atomic control tier) ← this round
1857
+ R709 zoom wrapper 23 s (control wrapper tier)
1858
+
1859
+ 21 is composite (3 × 7), the ONE composite in the prime quartet —
1860
+ slots between the prime wrappers 19 and 23 to fill the 17/19/21/23
1861
+ odd-number ladder. Coprime with all rolodex cadences (the rolodex
1862
+ has no 3-multiples until 9 and no 7-multiples until 7 itself — but
1863
+ neither 9 nor 7 share factors with 21's other co-tier mates 17/19/23).
1864
+ Actually 21 IS divisible by 3 like 9 — gcd(21,9)=3 so 21 phase-locks
1865
+ with 9 every 63 s. That's deliberate: the data tier (9 s) and the
1866
+ atomic-control tier (21 s) RE-ALIGN every minute — a slow handshake
1867
+ between "what the chrome reads" and "the reset action". Aesthetic
1868
+ over arithmetic: a 1-per-minute alignment is sub-perceptible.
1869
+
1870
+ Atomic-control sub-tier rationale: the reset button is the only
1871
+ STANDALONE atomic chrome button with a 5-axis hover signature
1872
+ (R594 brightness + R400 hover-lift + R196 active-state + R350 icon
1873
+ spin + R184 release pop). The 5 hover axes already give it a rich
1874
+ interactive voice; a 6th REST axis at 7% alpha (slightly looser than
1875
+ the 6% wrappers, to compensate for the smaller icon-button surface)
1876
+ marks it as "alive" at rest without competing with the hover axes.
1877
+
1878
+ Hover gate via data-attr (R703 pattern, not R707/R708/R709 :has()
1879
+ pattern). The button itself exposes data-topo-chrome-reset-hover —
1880
+ already plumbed for the R350 icon-rotate cue and R594 brightness —
1881
+ so the breath gates off naturally on its own hover state. Sibling
1882
+ gate pattern to R703 zoom-level (the only other chrome anchor at
1883
+ the leaf-element tier; both gate via their own hover data-attr
1884
+ rather than parent :has()). */
1885
+ @keyframes anet-topo-chrome-reset-breath-kf {
1886
+ 0%, 100% { opacity: 1; }
1887
+ 50% { opacity: 0.93; }
1888
+ }
1889
+ .anet-topo-chrome-reset-breath {
1890
+ animation: anet-topo-chrome-reset-breath-kf 21s ease-in-out infinite;
1891
+ }
1892
+ .anet-topo-chrome-reset-breath[data-topo-chrome-reset-hover="true"] {
1893
+ animation: none;
1894
+ }
1895
+ @media (prefers-reduced-motion: reduce) {
1896
+ .anet-topo-chrome-reset-breath { animation: none; }
1897
+ }
1898
+
1899
+ /* Round 719 — chrome fullscreen button joins the respiratory family at
1900
+ 25 s. 6th anchor on the chrome-strip pattern, extending the shape
1901
+ from "tiered-with-quartet" → "tiered-with-quintet". Sibling to R718
1902
+ reset (21 s) — closes the ATOMIC-CONTROL DUO: both standalone
1903
+ chrome buttons (reset + fullscreen, the only non-segmented chrome
1904
+ buttons in the family per R400 doc) now breathe at parity alpha
1905
+ range with coprime cadences.
1906
+
1907
+ Chrome-strip pattern post-R719:
1908
+ R703 zoom-level readout 9 s (data tier)
1909
+ R707 Layout wrapper 17 s (control wrapper tier)
1910
+ R708 nodeSize wrapper 19 s (control wrapper tier)
1911
+ R718 reset button 21 s (atomic control tier)
1912
+ R709 zoom wrapper 23 s (control wrapper tier)
1913
+ R719 fullscreen button 25 s (atomic control tier) ← this round
1914
+
1915
+ 25 = 5² — coprime with every other rolodex cadence (no factor 5
1916
+ anywhere). Fills the 17/19/21/23/25 odd-number ladder perfectly
1917
+ and becomes the new slowest cadence on the rolodex (prior slowest:
1918
+ 23 s zoom wrapper). The chrome strip now spans a 16 s arc from
1919
+ 9 → 25, with its two atomic-control members at 21 s and 25 s
1920
+ bracketing the wrapper trio (17/19/23) — atomic controls breathe
1921
+ slower than wrappers, matching their role as terminal commits
1922
+ (reset wipes state; fullscreen flips viewport mode).
1923
+
1924
+ Same 7% alpha (0.93 ↔ 1) as R718 reset — atomic-control tier
1925
+ parity. The duo reads as a matched pair at rest. Hover gate via
1926
+ data-topo-chrome-fullscreen-hover (R703 leaf-element pattern,
1927
+ sibling to R718 reset's gate). */
1928
+ @keyframes anet-topo-chrome-fullscreen-breath-kf {
1929
+ 0%, 100% { opacity: 1; }
1930
+ 50% { opacity: 0.93; }
1931
+ }
1932
+ .anet-topo-chrome-fullscreen-breath {
1933
+ animation: anet-topo-chrome-fullscreen-breath-kf 25s ease-in-out infinite;
1934
+ }
1935
+ .anet-topo-chrome-fullscreen-breath[data-topo-chrome-fullscreen-hover="true"] {
1936
+ animation: none;
1937
+ }
1938
+ @media (prefers-reduced-motion: reduce) {
1939
+ .anet-topo-chrome-fullscreen-breath { animation: none; }
1940
+ }
1941
+
1103
1942
  /* ─────────────────────────────────────────────────────────────────────
1104
1943
  Round 29 — prefers-reduced-motion a11y sweep
1105
1944