six-degrees 0.6.0 → 0.7.0

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 (557) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +3 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +14 -14
  5. package/.next/standalone/.next/routes-manifest.json +18 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.rsc +26 -18
  16. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +26 -18
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +25 -16
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/api/admin-delete/route.js +2 -2
  20. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/admin-update/route.js +2 -2
  22. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/bridges/route.js +2 -2
  24. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/bulk-import/route.js +2 -2
  26. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +3 -3
  28. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -3
  30. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/connections/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/data/backup/route/app-paths-manifest.json +3 -0
  34. package/.next/standalone/.next/server/app/api/data/backup/route/build-manifest.json +12 -0
  35. package/.next/standalone/.next/server/app/api/data/backup/route/server-reference-manifest.json +4 -0
  36. package/.next/standalone/.next/server/app/api/data/backup/route.js +7 -0
  37. package/.next/standalone/.next/server/app/api/data/backup/route.js.map +5 -0
  38. package/.next/standalone/.next/server/app/api/data/backup/route.js.nft.json +1 -0
  39. package/.next/standalone/.next/server/app/api/data/backup/route_client-reference-manifest.js +3 -0
  40. package/.next/standalone/.next/server/app/api/data/csv/route/app-paths-manifest.json +3 -0
  41. package/.next/standalone/.next/server/app/api/data/csv/route/build-manifest.json +12 -0
  42. package/.next/standalone/.next/server/app/api/data/csv/route/server-reference-manifest.json +4 -0
  43. package/.next/standalone/.next/server/app/api/data/csv/route.js +8 -0
  44. package/.next/standalone/.next/server/app/api/data/csv/route.js.map +5 -0
  45. package/.next/standalone/.next/server/app/api/data/csv/route.js.nft.json +1 -0
  46. package/.next/standalone/.next/server/app/api/data/csv/route_client-reference-manifest.js +3 -0
  47. package/.next/standalone/.next/server/app/api/data/export/route.js +1 -1
  48. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/data/import/route.js +1 -1
  50. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/data/restart/route.js +1 -1
  52. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/data/restore/route/app-paths-manifest.json +3 -0
  54. package/.next/standalone/.next/server/app/api/data/restore/route/build-manifest.json +12 -0
  55. package/.next/standalone/.next/server/app/api/data/restore/route/server-reference-manifest.json +4 -0
  56. package/.next/standalone/.next/server/app/api/data/restore/route.js +7 -0
  57. package/.next/standalone/.next/server/app/api/data/restore/route.js.map +5 -0
  58. package/.next/standalone/.next/server/app/api/data/restore/route.js.nft.json +1 -0
  59. package/.next/standalone/.next/server/app/api/data/restore/route_client-reference-manifest.js +3 -0
  60. package/.next/standalone/.next/server/app/api/data/reveal/route.js +1 -1
  61. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/data/route.js +1 -1
  63. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/delete-cluster/route.js +2 -2
  65. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
  67. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/network/route.js +2 -2
  69. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/notifications/route.js +2 -2
  71. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/outreach/route.js +2 -2
  73. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/queue/route.js +2 -2
  75. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/scraper/route.js +4 -2
  77. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/settings/route.js +3 -3
  79. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +3 -3
  81. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +3 -3
  83. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/setup-profile/route.js +2 -2
  85. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/social/crm/route.js +1 -1
  87. package/.next/standalone/.next/server/app/api/social/crm/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/social/messages/route.js +1 -1
  89. package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/social/route.js +2 -2
  91. package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/unlock/route.js +2 -2
  93. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/update-images/route.js +2 -2
  96. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/users/route.js +2 -2
  98. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/avatars/[file]/route.js +1 -1
  100. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/import/page.js +1 -1
  102. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/import.html +1 -1
  105. package/.next/standalone/.next/server/app/import.rsc +32 -24
  106. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +32 -24
  107. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
  108. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +23 -18
  109. package/.next/standalone/.next/server/app/index.html +1 -1
  110. package/.next/standalone/.next/server/app/index.rsc +29 -22
  111. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +20 -15
  112. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +29 -22
  113. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  114. package/.next/standalone/.next/server/app/launch/page.js +1 -1
  115. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/launch.html +2 -2
  118. package/.next/standalone/.next/server/app/launch.rsc +32 -24
  119. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
  120. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  121. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +23 -18
  122. package/.next/standalone/.next/server/app/page.js +1 -1
  123. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/paths/page.js +1 -1
  126. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  127. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/paths.html +1 -1
  129. package/.next/standalone/.next/server/app/paths.rsc +32 -24
  130. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
  131. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  132. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +21 -18
  133. package/.next/standalone/.next/server/app/profile/page.js +1 -1
  134. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  135. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/profile.html +1 -1
  137. package/.next/standalone/.next/server/app/profile.rsc +32 -24
  138. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
  139. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  140. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +23 -18
  141. package/.next/standalone/.next/server/app/queue/page.js +1 -1
  142. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/queue.html +1 -1
  145. package/.next/standalone/.next/server/app/queue.rsc +32 -24
  146. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
  147. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  148. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +20 -18
  149. package/.next/standalone/.next/server/app/scores/page.js +1 -1
  150. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  151. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/scores.html +1 -1
  153. package/.next/standalone/.next/server/app/scores.rsc +32 -24
  154. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
  155. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  156. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +23 -18
  157. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  158. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  159. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  160. package/.next/standalone/.next/server/app/settings.html +1 -1
  161. package/.next/standalone/.next/server/app/settings.rsc +32 -24
  162. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
  163. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  164. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +20 -18
  165. package/.next/standalone/.next/server/app/setup/page.js +1 -1
  166. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  167. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  168. package/.next/standalone/.next/server/app/setup.html +1 -1
  169. package/.next/standalone/.next/server/app/setup.rsc +32 -24
  170. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
  171. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  172. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +21 -18
  173. package/.next/standalone/.next/server/app/social/page.js +1 -1
  174. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  175. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/social.html +1 -1
  177. package/.next/standalone/.next/server/app/social.rsc +32 -24
  178. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
  179. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  180. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
  181. package/.next/standalone/.next/server/app-paths-manifest.json +3 -0
  182. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
  183. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
  184. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__063s0x7._.js} +2 -2
  185. package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
  186. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
  187. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__13dx4sd._.js → [root-of-the-server]__0_4y8z7._.js} +3 -3
  188. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
  190. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
  193. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
  195. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20rwfdw._.js +1 -1
  213. package/.next/standalone/.next/server/chunks/_02twlca._.js +1 -1
  214. package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
  215. package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
  216. package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
  217. package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
  218. package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
  219. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  220. package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
  221. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
  222. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
  223. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
  224. package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
  225. package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
  226. package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
  227. package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
  228. package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
  229. package/.next/standalone/.next/server/chunks/lib_rpc_005abye.js +3 -0
  230. package/.next/standalone/.next/server/chunks/lib_rpc_0b17r6v.js +3 -0
  231. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
  232. package/.next/standalone/.next/server/chunks/lib_rpc_0doq0t-.js +3 -0
  233. package/.next/standalone/.next/server/chunks/lib_rpc_0fd2rlw.js +3 -0
  234. package/.next/standalone/.next/server/chunks/lib_rpc_0is4qoc.js +3 -0
  235. package/.next/standalone/.next/server/chunks/lib_rpc_0jnfp2e.js +3 -0
  236. package/.next/standalone/.next/server/chunks/lib_rpc_0nef_n7.js +3 -0
  237. package/.next/standalone/.next/server/chunks/lib_rpc_0plrzra.js +3 -0
  238. package/.next/standalone/.next/server/chunks/lib_rpc_13a4m0c.js +3 -0
  239. package/.next/standalone/.next/server/chunks/lib_rpc_1if17c-.js +3 -0
  240. package/.next/standalone/.next/server/chunks/lib_rpc_1j-zw7v.js +3 -0
  241. package/.next/standalone/.next/server/chunks/lib_rpc_1sngt-q.js +3 -0
  242. package/.next/standalone/.next/server/chunks/lib_rpc_1v2sgme.js +3 -0
  243. package/.next/standalone/.next/server/chunks/lib_rpc_1vh-tgx.js +3 -0
  244. package/.next/standalone/.next/server/chunks/lib_rpc_1zaubz7.js +3 -0
  245. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
  246. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
  247. package/.next/standalone/.next/server/chunks/ssr/_01o3i5y._.js +7 -0
  248. package/.next/standalone/.next/server/chunks/ssr/_02sband._.js +7 -0
  249. package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
  250. package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
  251. package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
  252. package/.next/standalone/.next/server/chunks/ssr/_0gy11ar._.js +3 -0
  253. package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
  254. package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
  255. package/.next/standalone/.next/server/chunks/ssr/_189g8lg._.js +3 -0
  256. package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +1 -1
  257. package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
  258. package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
  259. package/.next/standalone/.next/server/chunks/ssr/_1k9qfsk._.js +3 -0
  260. package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
  261. package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +1 -1
  262. package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
  263. package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
  264. package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
  265. package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
  266. package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
  267. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +25 -13
  268. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
  269. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  270. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
  271. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  272. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
  273. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
  274. package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
  275. package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
  276. package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
  277. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
  278. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  279. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  280. package/.next/standalone/.next/server/pages/404.html +1 -1
  281. package/.next/standalone/.next/server/pages/500.html +1 -1
  282. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  283. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  284. package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  285. package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
  286. package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  287. package/.next/standalone/.next/static/chunks/0an_b6zi1r_qq.js +5 -0
  288. package/.next/standalone/.next/static/chunks/0e3g0sil79cus.js +21 -0
  289. package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  290. package/.next/standalone/.next/static/chunks/0p3g5tfostsep.js +7 -0
  291. package/.next/standalone/.next/static/chunks/0zd0t7e60bn4z.js +1 -0
  292. package/.next/standalone/.next/static/chunks/163b-20vwa06i.js +34 -0
  293. package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  294. package/.next/standalone/.next/static/chunks/1pa-2v1ajvrko.js +1 -0
  295. package/.next/standalone/.next/static/chunks/1qbjermbf68xj.js +1 -0
  296. package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  297. package/.next/standalone/.next/static/chunks/23_1z47al92nz.js +57 -0
  298. package/.next/standalone/.next/static/chunks/260bomtr214m8.js +34 -0
  299. package/.next/standalone/.next/static/chunks/2eo9pqq9gay3r.js +34 -0
  300. package/.next/standalone/.next/static/chunks/2xk2ra4piiuod.js +34 -0
  301. package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  302. package/.next/standalone/.next/static/chunks/2zf4jmz9l3li2.js +1 -0
  303. package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
  304. package/.next/standalone/.next/static/chunks/3b0-14cxqsprt.js +1 -0
  305. package/.next/standalone/.next/static/chunks/3jarus1_38s2z.js +1 -0
  306. package/.next/standalone/.next/static/chunks/3ssu341hav_sq.css +3 -0
  307. package/.next/standalone/.next/static/chunks/3v1qd3sqhqn0d.js +1 -0
  308. package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
  309. package/.next/standalone/.next/static/chunks/44yn0tcd9dfk3.js +1 -0
  310. package/.next/standalone/CHANGELOG.md +143 -0
  311. package/.next/standalone/README.md +71 -49
  312. package/.next/standalone/SECURITY.md +17 -11
  313. package/.next/standalone/app/api/data/backup/route.js +25 -0
  314. package/.next/standalone/app/api/data/csv/route.js +74 -0
  315. package/.next/standalone/app/api/data/export/route.js +1 -1
  316. package/.next/standalone/app/api/data/restore/route.js +48 -0
  317. package/.next/standalone/app/api/data/reveal/route.js +19 -6
  318. package/.next/standalone/app/api/data/route.js +15 -4
  319. package/.next/standalone/app/api/ingest/route.js +1 -1
  320. package/.next/standalone/app/api/queue/route.js +1 -1
  321. package/.next/standalone/app/api/scraper/route.js +120 -32
  322. package/.next/standalone/app/api/social/crm/route.js +2 -1
  323. package/.next/standalone/app/components/AppHeader.js +20 -16
  324. package/.next/standalone/app/components/AppTabs.js +8 -8
  325. package/.next/standalone/app/components/AutoScanButton.js +2 -2
  326. package/.next/standalone/app/components/Avatar.js +1 -1
  327. package/.next/standalone/app/components/ChainView.js +184 -112
  328. package/.next/standalone/app/components/CirclePanel.js +16 -16
  329. package/.next/standalone/app/components/ClusterSpinner.js +64 -0
  330. package/.next/standalone/app/components/CompanyScores.js +20 -20
  331. package/.next/standalone/app/components/EmptyState.js +39 -18
  332. package/.next/standalone/app/components/FieldStep.js +15 -13
  333. package/.next/standalone/app/components/FilterPanel.js +17 -17
  334. package/.next/standalone/app/components/ForceGraph.js +49 -14
  335. package/.next/standalone/app/components/GalaxyLab.js +33 -33
  336. package/.next/standalone/app/components/GridView.js +18 -18
  337. package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
  338. package/.next/standalone/app/components/LinkedInLimits.js +24 -19
  339. package/.next/standalone/app/components/LiquidGlass.js +99 -0
  340. package/.next/standalone/app/components/ListView.js +20 -20
  341. package/.next/standalone/app/components/MapControls.js +5 -5
  342. package/.next/standalone/app/components/MappingProgress.js +16 -16
  343. package/.next/standalone/app/components/NoteDetail.js +13 -13
  344. package/.next/standalone/app/components/OnboardingGate.js +4 -4
  345. package/.next/standalone/app/components/OutlinkQuest.js +25 -25
  346. package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
  347. package/.next/standalone/app/components/PeopleMap.js +21 -21
  348. package/.next/standalone/app/components/RingsView.js +11 -11
  349. package/.next/standalone/app/components/ScanRadar.js +84 -39
  350. package/.next/standalone/app/components/ScanStatusBar.js +22 -18
  351. package/.next/standalone/app/components/ScanTrail.js +8 -5
  352. package/.next/standalone/app/components/SeparationView.js +168 -104
  353. package/.next/standalone/app/components/Sidebar.js +161 -161
  354. package/.next/standalone/app/components/StaleServerBanner.js +4 -4
  355. package/.next/standalone/app/components/TheirCircle.js +26 -26
  356. package/.next/standalone/app/components/ThemeDefs.js +42 -0
  357. package/.next/standalone/app/components/ThemeLoader.js +20 -1
  358. package/.next/standalone/app/components/UpdatePanel.js +22 -22
  359. package/.next/standalone/app/components/UserProvider.js +22 -15
  360. package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
  361. package/.next/standalone/app/components/settings/DataSection.js +276 -109
  362. package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
  363. package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
  364. package/.next/standalone/app/components/settings/SectorSection.js +13 -14
  365. package/.next/standalone/app/components/settings/TierSection.js +9 -9
  366. package/.next/standalone/app/components/settings/TitleSection.js +11 -11
  367. package/.next/standalone/app/components/settings/UsageSection.js +313 -0
  368. package/.next/standalone/app/components/ui.js +8 -8
  369. package/.next/standalone/app/globals.css +159 -2
  370. package/.next/standalone/app/import/page.js +94 -38
  371. package/.next/standalone/app/launch/page.js +5 -5
  372. package/.next/standalone/app/layout.js +6 -2
  373. package/.next/standalone/app/page.js +53 -37
  374. package/.next/standalone/app/paths/page.js +63 -63
  375. package/.next/standalone/app/profile/page.js +58 -58
  376. package/.next/standalone/app/queue/page.js +54 -54
  377. package/.next/standalone/app/scores/page.js +2 -2
  378. package/.next/standalone/app/settings/page.js +16 -13
  379. package/.next/standalone/app/setup/page.js +221 -125
  380. package/.next/standalone/app/social/Crm.js +63 -62
  381. package/.next/standalone/app/social/SocialHub.js +22 -22
  382. package/.next/standalone/app/social/Thread.js +7 -7
  383. package/.next/standalone/app/social/page.js +2 -2
  384. package/.next/standalone/lib/backups.js +458 -0
  385. package/.next/standalone/lib/chain-layout.js +32 -0
  386. package/.next/standalone/lib/csv-store.js +131 -0
  387. package/.next/standalone/lib/csv.js +137 -39
  388. package/.next/standalone/lib/data-folder.js +19 -3
  389. package/.next/standalone/lib/data-import.js +5 -2
  390. package/.next/standalone/lib/db-client.js +78 -20
  391. package/.next/standalone/lib/demo.js +5 -4
  392. package/.next/standalone/lib/galaxy-export.js +9 -2
  393. package/.next/standalone/lib/galaxy-lab.js +19 -5
  394. package/.next/standalone/lib/galaxy-layouts.js +43 -0
  395. package/.next/standalone/lib/gate.js +10 -4
  396. package/.next/standalone/lib/ingest.js +1 -1
  397. package/.next/standalone/lib/linkedin-limits.js +212 -11
  398. package/.next/standalone/lib/liquid-glass.js +59 -0
  399. package/.next/standalone/lib/notifications.js +13 -0
  400. package/.next/standalone/lib/scan-pace.js +11 -0
  401. package/.next/standalone/lib/scan-progress.js +20 -0
  402. package/.next/standalone/lib/scan-risk.js +44 -0
  403. package/.next/standalone/lib/scanner-setup.js +97 -15
  404. package/.next/standalone/lib/scraper-client.js +17 -3
  405. package/.next/standalone/lib/search-risk.js +7 -3
  406. package/.next/standalone/lib/settings-client.js +5 -3
  407. package/.next/standalone/lib/settings.js +10 -0
  408. package/.next/standalone/lib/social-store.js +3 -2
  409. package/.next/standalone/lib/synced-setting.js +46 -0
  410. package/.next/standalone/lib/theme-store.js +42 -10
  411. package/.next/standalone/lib/themes.js +111 -21
  412. package/.next/standalone/lib/usage.js +195 -0
  413. package/.next/standalone/package-lock.json +2 -2
  414. package/.next/standalone/package.json +1 -1
  415. package/.next/standalone/scripts/scrape.py +26 -2
  416. package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  417. package/.next/static/chunks/03-demj2iy-0p.js +44 -0
  418. package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  419. package/.next/static/chunks/0an_b6zi1r_qq.js +5 -0
  420. package/.next/static/chunks/0e3g0sil79cus.js +21 -0
  421. package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  422. package/.next/static/chunks/0p3g5tfostsep.js +7 -0
  423. package/.next/static/chunks/0zd0t7e60bn4z.js +1 -0
  424. package/.next/static/chunks/163b-20vwa06i.js +34 -0
  425. package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  426. package/.next/static/chunks/1pa-2v1ajvrko.js +1 -0
  427. package/.next/static/chunks/1qbjermbf68xj.js +1 -0
  428. package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  429. package/.next/static/chunks/23_1z47al92nz.js +57 -0
  430. package/.next/static/chunks/260bomtr214m8.js +34 -0
  431. package/.next/static/chunks/2eo9pqq9gay3r.js +34 -0
  432. package/.next/static/chunks/2xk2ra4piiuod.js +34 -0
  433. package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  434. package/.next/static/chunks/2zf4jmz9l3li2.js +1 -0
  435. package/.next/static/chunks/34g73qhayuevu.js +1 -0
  436. package/.next/static/chunks/3b0-14cxqsprt.js +1 -0
  437. package/.next/static/chunks/3jarus1_38s2z.js +1 -0
  438. package/.next/static/chunks/3ssu341hav_sq.css +3 -0
  439. package/.next/static/chunks/3v1qd3sqhqn0d.js +1 -0
  440. package/.next/static/chunks/43pg2sursiypz.js +1 -0
  441. package/.next/static/chunks/44yn0tcd9dfk3.js +1 -0
  442. package/CHANGELOG.md +143 -0
  443. package/README.md +71 -49
  444. package/SECURITY.md +17 -11
  445. package/lib/backups.js +458 -0
  446. package/lib/chain-layout.js +32 -0
  447. package/lib/csv-store.js +131 -0
  448. package/lib/csv.js +137 -39
  449. package/lib/data-folder.js +19 -3
  450. package/lib/data-import.js +5 -2
  451. package/lib/db-client.js +78 -20
  452. package/lib/demo.js +5 -4
  453. package/lib/galaxy-export.js +9 -2
  454. package/lib/galaxy-lab.js +19 -5
  455. package/lib/galaxy-layouts.js +43 -0
  456. package/lib/gate.js +10 -4
  457. package/lib/ingest.js +1 -1
  458. package/lib/linkedin-limits.js +212 -11
  459. package/lib/liquid-glass.js +59 -0
  460. package/lib/notifications.js +13 -0
  461. package/lib/scan-pace.js +11 -0
  462. package/lib/scan-progress.js +20 -0
  463. package/lib/scan-risk.js +44 -0
  464. package/lib/scanner-setup.js +97 -15
  465. package/lib/scraper-client.js +17 -3
  466. package/lib/search-risk.js +7 -3
  467. package/lib/settings-client.js +5 -3
  468. package/lib/settings.js +10 -0
  469. package/lib/social-store.js +3 -2
  470. package/lib/synced-setting.js +46 -0
  471. package/lib/theme-store.js +42 -10
  472. package/lib/themes.js +111 -21
  473. package/lib/usage.js +195 -0
  474. package/package.json +1 -1
  475. package/scripts/scrape.py +26 -2
  476. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
  477. package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
  478. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
  479. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
  480. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
  481. package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
  482. package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
  483. package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
  484. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
  485. package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
  486. package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
  487. package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
  488. package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
  489. package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
  490. package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
  491. package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
  492. package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
  493. package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
  494. package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
  495. package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
  496. package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
  497. package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
  498. package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
  499. package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
  500. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
  501. package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
  502. package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
  503. package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
  504. package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
  505. package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
  506. package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
  507. package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
  508. package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
  509. package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +0 -3
  510. package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  511. package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  512. package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
  513. package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  514. package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
  515. package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  516. package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  517. package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  518. package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
  519. package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  520. package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  521. package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  522. package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
  523. package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  524. package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
  525. package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  526. package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  527. package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  528. package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  529. package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  530. package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  531. package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  532. package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  533. package/.next/static/chunks/0i02yxppzds1o.js +0 -1
  534. package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  535. package/.next/static/chunks/0oyslj62jkubd.js +0 -1
  536. package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  537. package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  538. package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  539. package/.next/static/chunks/172e10mi-tpo_.js +0 -34
  540. package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  541. package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  542. package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  543. package/.next/static/chunks/1m3017gp790pw.js +0 -45
  544. package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  545. package/.next/static/chunks/2-ch9rm27eril.js +0 -11
  546. package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  547. package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  548. package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  549. package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  550. package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  551. package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  552. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_buildManifest.js +0 -0
  553. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_clientMiddlewareManifest.js +0 -0
  554. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_ssgManifest.js +0 -0
  555. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_buildManifest.js +0 -0
  556. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_clientMiddlewareManifest.js +0 -0
  557. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_ssgManifest.js +0 -0
@@ -98,6 +98,9 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
98
98
  // The slider, 0 (rarest ways in first) to 100 (easiest first); 50 is power alone.
99
99
  // The list follows a deferred copy, so the thumb never waits for a sort.
100
100
  const [at, setAt] = useState(SLIDER_MIDDLE);
101
+ // The map's zoom: null fits the whole map in the window (Blake, 2026-10-03: "hard
102
+ // to see the whole graph on the single screen ... at least have a plus and minus").
103
+ const [zoom, setZoom] = useState(null);
101
104
  const atSlow = useDeferredValue(at);
102
105
  const [tier, setTier] = useState('all');
103
106
  // Rarity beside the tier (lib/rarity.js): any bands switched on; none is everyone.
@@ -244,9 +247,22 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
244
247
  : summitLayout(top, cw || 800, isMobile, { cards })),
245
248
  [single, target, top, cw, isMobile, cards, rarityBy],
246
249
  );
247
- const captionH = isMobile ? 58 : 28; // fixed, so HEAD is arithmetic; the phone legend takes two lines, a computer's is the tooltip
250
+ const captionH = isMobile ? 58 : 36; // fixed, so HEAD is arithmetic; the phone legend takes two lines, a computer's is the tooltip and the zoom
248
251
  const NEXT_H = nextUp.length ? 38 : 0;
249
- const mapH = single ? (target ? layout.height + NEXT_H : 0) : layout.height;
252
+ // Fit: as big as it can be with all of it in the window, never bigger than
253
+ // life. A phone scrolls instead, unless you zoom.
254
+ const fitZoom = isMobile ? 1 : Math.max(ZOOM_MIN, Math.min(1, (box.h - captionH - 22 - (single ? NEXT_H : 0)) / Math.max(1, layout.height)));
255
+ // Dynamic (Blake, 2026-10-03: "it should be dynamic"): what the map shows
256
+ // changes — the slider moves, you aim at someone else — and it fits again,
257
+ // whatever zoom you'd set. A new window size re-fits on its own.
258
+ const viewKey = single ? `aim:${target?.key ?? ''}` : `top:${top.map((t) => t.key).join(',')}`;
259
+ const [zoomFor, setZoomFor] = useState(viewKey);
260
+ if (zoomFor !== viewKey) {
261
+ setZoomFor(viewKey);
262
+ if (zoom != null) setZoom(null);
263
+ }
264
+ const scale = zoom ?? fitZoom;
265
+ const mapH = single ? (target ? Math.round(layout.height * scale) + NEXT_H : 0) : Math.round(layout.height * scale);
250
266
  const mapBlockH = mapH ? captionH + mapH + 12 : 0;
251
267
  const titleH = isMobile ? 0 : TITLE_ROW;
252
268
  const HEAD = mapBlockH + titleH + LABEL_ROW;
@@ -330,16 +346,16 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
330
346
  aria-label="Search people, companies, or who knows them"
331
347
  style={{
332
348
  width: isMobile ? '100%' : 300, flexShrink: 0, minWidth: 0, height: isMobile ? 44 : 32, boxSizing: 'border-box',
333
- padding: '0 12px', borderRadius: 8, outline: 'none', color: '#fff',
349
+ padding: '0 12px', borderRadius: 8, outline: 'none', color: 'var(--sd-fg-1, #fff)',
334
350
  fontSize: isMobile ? 16 : 13, // under 16px, iOS zooms the page on focus
335
- border: '1px solid rgba(255,255,255,0.12)', background: 'rgba(255,255,255,0.05)',
351
+ border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.12)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.05)',
336
352
  }}
337
353
  />
338
354
  );
339
355
  // "Only show": the rarity chips, beside the tiers on a computer, on their own row on a phone.
340
356
  const rarityChips = (
341
357
  <>
342
- <span title={RARITY_NOTE} style={{ fontSize: 10, color: '#666', whiteSpace: 'nowrap', flexShrink: 0, textTransform: 'uppercase', letterSpacing: 0.5, cursor: 'help' }}>Only show</span>
358
+ <span title={RARITY_NOTE} style={{ fontSize: 10, color: 'var(--sd-fg-4, #666)', whiteSpace: 'nowrap', flexShrink: 0, textTransform: 'uppercase', letterSpacing: 0.5, cursor: 'help' }}>Only show</span>
343
359
  {RARITY.map((r) => {
344
360
  const on = rarities.has(r.key);
345
361
  return (
@@ -347,12 +363,12 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
347
363
  title={`${r.label}: ${r.range} mutual connection${r.range === '1' ? '' : 's'}. ${RARITY_NOTE}`} style={{
348
364
  height: isMobile ? 40 : 28, padding: isMobile ? '0 10px' : '0 8px', borderRadius: 14, cursor: 'pointer', flexShrink: 0,
349
365
  fontSize: 11.5, fontWeight: 700, whiteSpace: 'nowrap',
350
- border: `1px solid ${on ? r.color : 'rgba(255,255,255,0.1)'}`,
351
- background: on ? `${r.color}22` : 'rgba(255,255,255,0.03)',
352
- color: on ? r.color : '#999',
366
+ border: `1px solid ${on ? r.color : 'rgba(var(--sd-ink, 255, 255, 255), 0.1)'}`,
367
+ background: on ? `${r.color}22` : 'rgba(var(--sd-ink, 255, 255, 255), 0.03)',
368
+ color: on ? r.color : 'var(--sd-fg-3, #999)',
353
369
  }}>
354
370
  {r.label}
355
- <span style={{ marginLeft: 5, fontWeight: 500, color: on ? r.color : '#666', opacity: 0.85 }}>{fmt(byRarity[r.key])}</span>
371
+ <span style={{ marginLeft: 5, fontWeight: 500, color: on ? r.color : 'var(--sd-fg-4, #666)', opacity: 0.85 }}>{fmt(byRarity[r.key])}</span>
356
372
  </button>
357
373
  );
358
374
  })}
@@ -362,7 +378,7 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
362
378
  return (
363
379
  <div style={{
364
380
  flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column',
365
- background: 'var(--sd-page)', color: '#fff', overflow: 'hidden',
381
+ background: 'var(--sd-page)', color: 'var(--sd-fg-1, #fff)', overflow: 'hidden',
366
382
  }}>
367
383
  {/* ── Header: what this is, how many, and what it can't say ── */}
368
384
  <div style={{ padding: `${notch ? 48 : 14}px ${SIDE}px 8px`, flexShrink: 0 }}>
@@ -372,7 +388,7 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
372
388
  background: 'linear-gradient(135deg, #FFD700, #FF6B35)',
373
389
  WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent',
374
390
  }}>Separation</h2>
375
- <span style={{ fontSize: 12, color: '#aaa', ...(isMobile ? {} : { flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }) }}>
391
+ <span style={{ fontSize: 12, color: 'var(--sd-fg-3, #aaa)', ...(isMobile ? {} : { flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }) }}>
376
392
  {isMobile
377
393
  ? `${plural(summary.people, 'person', 'people')} · ${fmt(summary.byTier.S)} S · ${fmt(summary.multi)} with 2+ ways`
378
394
  : `${plural(summary.people, 'person', 'people')} two steps away · ${fmt(summary.byTier.S)} S-tier · ${fmt(summary.multi)} reachable 2+ ways · through ${fmt(summary.bridges)} of your connections`}
@@ -380,18 +396,18 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
380
396
  {!isMobile && searchBox}
381
397
  </div>
382
398
  {/* The whole population at a glance: one segment per tier, to scale. */}
383
- <div aria-hidden="true" style={{ display: 'flex', gap: 1, height: 6, borderRadius: 3, overflow: 'hidden', margin: '8px 0 6px', background: 'rgba(255,255,255,0.04)' }}>
399
+ <div aria-hidden="true" style={{ display: 'flex', gap: 1, height: 6, borderRadius: 3, overflow: 'hidden', margin: '8px 0 6px', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.04)' }}>
384
400
  {TIERS.filter((t) => summary.byTier[t] > 0).map((t) => (
385
401
  <div key={t} style={{ flex: summary.byTier[t], background: tierColors[t] || '#555' }} />
386
402
  ))}
387
403
  </div>
388
404
  {/* On a computer the line says it on its own; what it ranks is the title's tooltip (RANK_NOTE). */}
389
405
  {isMobile && (
390
- <div style={{ fontSize: 11, color: '#777', lineHeight: 1.4 }}>Ranks reachability, not people · lists scanned so far</div>
406
+ <div style={{ fontSize: 11, color: 'var(--sd-fg-4, #777)', lineHeight: 1.4 }}>Ranks reachability, not people · lists scanned so far</div>
391
407
  )}
392
408
  {summary.peopleOnlyUnresolved > 0 && (
393
409
  <div style={{
394
- marginTop: 8, padding: '8px 10px', borderRadius: 8, fontSize: 11.5, lineHeight: 1.5, color: '#e8d9a0',
410
+ marginTop: 8, padding: '8px 10px', borderRadius: 8, fontSize: 11.5, lineHeight: 1.5, color: 'var(--sd-fg-2, #e8d9a0)',
395
411
  background: 'rgba(255,215,0,0.06)', border: '1px solid rgba(255,215,0,0.25)',
396
412
  }}>
397
413
  {/* Worded without a cause on purpose: the one time this happened, the
@@ -406,12 +422,12 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
406
422
  </div>
407
423
 
408
424
  {/* ── Controls: search, then the slider with their tier and rarity ── */}
409
- <div style={{ padding: `0 ${SIDE}px 10px`, flexShrink: 0, borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
425
+ <div style={{ padding: `0 ${SIDE}px 10px`, flexShrink: 0, borderBottom: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.06)' }}>
410
426
  <style>{SLIDER_CSS}</style>
411
427
  {isMobile && searchBox}
412
428
  <div style={{
413
429
  marginTop: isMobile ? 8 : 2, padding: isMobile ? '8px 10px' : '8px 14px', borderRadius: 12, position: 'relative',
414
- border: '1px solid rgba(255,255,255,0.08)', background: 'rgba(255,255,255,0.025)',
430
+ border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.08)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.025)',
415
431
  }}>
416
432
  {pathOpen && (
417
433
  <PathPicker facets={facets} text={pathText} onText={setPathText} isMobile={isMobile}
@@ -420,21 +436,21 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
420
436
  <div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 8 : 6, flexWrap: isMobile ? 'nowrap' : 'wrap', minWidth: 0,
421
437
  // A phone scrolls this strip sideways, so the page itself never does.
422
438
  overflowX: isMobile ? 'auto' : 'visible', scrollbarWidth: 'thin' }}>
423
- <span style={{ fontSize: 10, color: '#666', whiteSpace: 'nowrap', flexShrink: 0, textTransform: 'uppercase', letterSpacing: 0.5 }}>Their tier</span>
439
+ <span style={{ fontSize: 10, color: 'var(--sd-fg-4, #666)', whiteSpace: 'nowrap', flexShrink: 0, textTransform: 'uppercase', letterSpacing: 0.5 }}>Their tier</span>
424
440
  {['all', ...TIERS].map((t) => {
425
441
  const on = tier === t;
426
- const c = t === 'all' ? '#fff' : tierColors[t] || '#888';
442
+ const c = t === 'all' ? 'var(--sd-fg-1, #fff)' : tierColors[t] || '#888';
427
443
  const n = t === 'all' ? summary.people : summary.byTier[t];
428
444
  return (
429
445
  <button key={t} type="button" aria-pressed={on} onClick={() => changeTier(t)} style={{
430
446
  height: isMobile ? 40 : 28, padding: isMobile ? '0 10px' : '0 8px', borderRadius: 14, cursor: 'pointer', flexShrink: 0,
431
447
  fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap',
432
- border: `1px solid ${on ? c : 'rgba(255,255,255,0.1)'}`,
433
- background: on ? `${c === '#fff' ? '#ffffff' : c}22` : 'rgba(255,255,255,0.03)',
434
- color: on ? c : '#999',
448
+ border: `1px solid ${on ? c : 'rgba(var(--sd-ink, 255, 255, 255), 0.1)'}`,
449
+ background: on ? (t === 'all' ? 'rgba(var(--sd-ink, 255, 255, 255), 0.13)' : `${c}22`) : 'rgba(var(--sd-ink, 255, 255, 255), 0.03)',
450
+ color: on ? c : 'var(--sd-fg-3, #999)',
435
451
  }}>
436
452
  {t === 'all' ? 'All' : t}
437
- <span style={{ marginLeft: 5, fontWeight: 500, color: on ? c : '#666', opacity: 0.85 }}>{fmt(n)}</span>
453
+ <span style={{ marginLeft: 5, fontWeight: 500, color: on ? c : 'var(--sd-fg-4, #666)', opacity: 0.85 }}>{fmt(n)}</span>
438
454
  </button>
439
455
  );
440
456
  })}
@@ -446,7 +462,7 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
446
462
  padding: path ? '0 6px 0 12px' : '0 12px', border: 'none', background: 'none', cursor: 'pointer',
447
463
  fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap', color: PATH, maxWidth: isMobile ? 200 : 300, overflow: 'hidden', textOverflow: 'ellipsis',
448
464
  }}>
449
- {path ? <>Path<span style={{ fontWeight: 500, color: '#cfe' }}> · {path.label}</span></> : 'Path ▾'}
465
+ {path ? <>Path<span style={{ fontWeight: 500, color: 'var(--sd-fg-1, #cfe)' }}> · {path.label}</span></> : 'Path ▾'}
450
466
  </button>
451
467
  {path && (
452
468
  <button type="button" aria-label={`Clear the path: ${path.label}`} onClick={() => pickPath(null)} style={{
@@ -455,7 +471,7 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
455
471
  )}
456
472
  </span>
457
473
  {!isMobile && <>
458
- <span aria-hidden="true" style={{ width: 1, height: 18, background: 'rgba(255,255,255,0.12)', margin: '0 2px' }} />
474
+ <span aria-hidden="true" style={{ width: 1, height: 18, background: 'rgba(var(--sd-ink, 255, 255, 255), 0.12)', margin: '0 2px' }} />
459
475
  {rarityChips}
460
476
  </>}
461
477
  {isMobile && pillEl}
@@ -464,9 +480,9 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
464
480
  {/* The slider: the rarest ways in at one end, the easiest at the other, power alone in the middle */}
465
481
  {/* On a computer the pill saying where the slider is sits over its middle, in place of "Power" */}
466
482
  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: isMobile ? 'baseline' : 'center', marginTop: 8, fontSize: 10.5, fontWeight: 800, letterSpacing: 0.5, textTransform: 'uppercase' }}>
467
- <span style={{ color: RARE, flex: isMobile ? undefined : 1 }}>Rare{isMobile ? '' : ' · one way in'}</span>
468
- {isMobile ? <span style={{ color: '#FFD700' }}>Power</span> : pillEl}
469
- <span style={{ color: EASY, flex: isMobile ? undefined : 1, textAlign: 'right' }}>Easy{isMobile ? '' : ' · many mutual connections'}</span>
483
+ <span style={{ color: 'var(--sd-cyan, #00E5FF)', flex: isMobile ? undefined : 1 }}>Rare{isMobile ? '' : ' · one way in'}</span>
484
+ {isMobile ? <span style={{ color: 'var(--sd-gold, #FFD700)' }}>Power</span> : pillEl}
485
+ <span style={{ color: 'var(--sd-coral, #FF7043)', flex: isMobile ? undefined : 1, textAlign: 'right' }}>Easy{isMobile ? '' : ' · many mutual connections'}</span>
470
486
  </div>
471
487
  <input
472
488
  className="sepslide" type="range" min={0} max={100} step={1} value={at}
@@ -480,13 +496,13 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
480
496
  {[[0, 'Rarest'], [25, ''], [SLIDER_MIDDLE, 'By power'], [75, ''], [100, 'Easiest']].map(([v, name]) => (
481
497
  <button key={v} type="button" onClick={() => changeAt(v)} aria-label={`Set the slider to ${v}${name ? `: ${name}` : ''}`} style={{
482
498
  padding: '2px 4px', border: 'none', background: 'none', cursor: 'pointer', fontSize: 10,
483
- color: at === v ? '#fff' : '#667', fontWeight: at === v ? 700 : 500, fontVariantNumeric: 'tabular-nums',
499
+ color: at === v ? 'var(--sd-fg-1, #fff)' : 'var(--sd-fg-4, #667)', fontWeight: at === v ? 700 : 500, fontVariantNumeric: 'tabular-nums',
484
500
  }}>{v}{name && !isMobile ? ` · ${name}` : ''}</button>
485
501
  ))}
486
502
  </div>
487
503
  {/* On a phone: the sentence, and the rarity chips on a row of their own */}
488
504
  {isMobile && <>
489
- <div style={{ marginTop: 4, fontSize: 11.5, lineHeight: 1.45, color: '#bbb' }}>
505
+ <div style={{ marginTop: 4, fontSize: 11.5, lineHeight: 1.45, color: 'var(--sd-fg-2, #bbb)' }}>
490
506
  <span style={{ color: slideColor, fontWeight: 700 }}>{slide.name}.</span>{' '}{slide.detail}
491
507
  </div>
492
508
  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8, minWidth: 0, flexWrap: 'nowrap',
@@ -505,25 +521,30 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
505
521
  >
506
522
  <div style={{ position: 'relative', maxWidth: 980, margin: '0 auto', height: total }}>
507
523
  {mapBlockH > 0 && (
508
- <div style={{ height: mapBlockH, boxSizing: 'border-box', paddingTop: 10 }}>
509
- <div style={{ height: captionH - 10, overflow: 'hidden' }}>
524
+ <div className="sepblock" style={{ height: mapBlockH, boxSizing: 'border-box', paddingTop: 10 }}>
525
+ <div style={{ height: captionH - 10, overflow: 'hidden', display: isMobile ? 'block' : 'flex', alignItems: 'flex-start', gap: 10 }}>
510
526
  <div title={isMobile ? undefined : `${!single && askedShown > 0 ? `${fmt(askedShown)} asked or connected, so it moved on. ` : ''}Solid orange: the top-scored bridge. Dashed: other routes.${single ? ' Pick anyone in the list to aim at them instead.' : cards ? ' A lit pill is someone’s best way in.' : ' Dot size: ways in.'}`}
511
- style={{ fontSize: 12, fontWeight: 700, color: '#ddd', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
527
+ style={{ flex: 1, minWidth: 0, fontSize: 12, fontWeight: 700, color: 'var(--sd-fg-1, #ddd)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
512
528
  {single
513
529
  ? <>Aiming at {target.person.name} · {layout.unscanned
514
530
  ? `${fmt(target.waysIn + layout.unscanned)} mutual connections: ${fmt(target.waysIn)} drawn, ${fmt(layout.unscanned)} in circles not scanned yet`
515
531
  : target.waysIn === 1 ? 'the one connection of yours who leads to them' : `all ${fmt(target.waysIn)} connections of yours who lead to them`}</>
516
532
  : <>Top {fmt(top.length)} you haven’t asked, of {fmt(visible.length)}{filtered ? ' shown' : ''}{at !== SLIDER_MIDDLE ? ` · ${slide.name.toLowerCase()}` : ''} · every way in drawn</>}
517
533
  </div>
518
- {isMobile && <div style={{ fontSize: 10, color: '#777', marginTop: 2, whiteSpace: 'normal', overflow: 'hidden', textOverflow: 'ellipsis', lineHeight: 1.35 }}>
519
- {!single && askedShown > 0 && <span style={{ color: '#FFD700' }}>{fmt(askedShown)} asked or connected, so it moved on · </span>}
520
- <span style={{ color: ORANGE }}>solid orange</span> = top-scored bridge · dashed = other routes
534
+ {!isMobile && <ZoomControl scale={scale} fitted={zoom == null}
535
+ onOut={() => setZoom(Math.max(ZOOM_MIN, Math.round((scale - 0.1) * 10) / 10))}
536
+ onFit={() => setZoom(null)}
537
+ onIn={() => setZoom(Math.min(ZOOM_MAX, Math.round((scale + 0.1) * 10) / 10))} />}
538
+ {isMobile && <div style={{ fontSize: 10, color: 'var(--sd-fg-4, #777)', marginTop: 2, whiteSpace: 'normal', overflow: 'hidden', textOverflow: 'ellipsis', lineHeight: 1.35 }}>
539
+ {!single && askedShown > 0 && <span style={{ color: 'var(--sd-gold, #FFD700)' }}>{fmt(askedShown)} asked or connected, so it moved on · </span>}
540
+ <span style={{ color: 'var(--sd-orange, #FF6B35)' }}>solid orange</span> = top-scored bridge · dashed = other routes
521
541
  {single ? ' · pick anyone in the list to aim at them instead' : cards ? ' · a lit pill is someone’s best way in' : ' · dot size = ways in'}
522
542
  </div>}
523
543
  </div>
524
544
  {cw > 0 && (
525
545
  <SummitMap
526
546
  layout={layout}
547
+ scale={scale}
527
548
  selectedKey={selectedKey}
528
549
  tierColors={tierColors}
529
550
  youLabel={youLabel}
@@ -540,17 +561,17 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
540
561
  <>
541
562
  {nextUp.length > 0 && (
542
563
  <div style={{ height: NEXT_H, display: 'flex', alignItems: 'center', gap: 6, overflow: 'hidden' }}>
543
- <span style={{ fontSize: 10, color: '#666', textTransform: 'uppercase', letterSpacing: 0.5, flexShrink: 0 }}>Next</span>
564
+ <span style={{ fontSize: 10, color: 'var(--sd-fg-4, #666)', textTransform: 'uppercase', letterSpacing: 0.5, flexShrink: 0 }}>Next</span>
544
565
  {nextUp.map((p) => (
545
566
  <button key={p.key} type="button" onClick={() => onPick(p)} title={`Aim at ${p.person.name}`} style={{
546
567
  height: 26, padding: '0 10px', borderRadius: 13, cursor: 'pointer', flexShrink: 1, minWidth: 0,
547
568
  fontSize: 11, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
548
- border: `1px solid ${(tierColors[p.tier] || '#888')}55`, background: 'rgba(255,255,255,0.03)', color: '#ccc',
569
+ border: `1px solid ${(tierColors[p.tier] || '#888')}55`, background: 'rgba(var(--sd-ink, 255, 255, 255), 0.03)', color: 'var(--sd-fg-2, #ccc)',
549
570
  }}>
550
571
  {shortName(p.person.name)}
551
572
  <span style={{ marginLeft: 5, color: tierColors[p.tier] || '#888', fontWeight: 700 }}>{p.score.toFixed(1)}</span>
552
573
  {/* The count they're ordered by: every mutual, scanned or not */}
553
- <span style={{ marginLeft: 5, color: '#667', fontWeight: 500 }}>
574
+ <span style={{ marginLeft: 5, color: 'var(--sd-fg-4, #667)', fontWeight: 500 }}>
554
575
  {(() => { const n = Math.max(rarityBy.get(p.key)?.count || 0, p.waysIn); return n === 1 ? '1 mutual' : `${fmt(n)} mutuals`; })()}
555
576
  </span>
556
577
  </button>
@@ -565,13 +586,13 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
565
586
  {visible.length > 0 && !isMobile && (
566
587
  <div style={{
567
588
  height: TITLE_ROW, display: 'flex', alignItems: 'center', gap: 10, padding: '0 12px 0 15px', boxSizing: 'border-box',
568
- borderTop: '1px solid rgba(255,255,255,0.06)',
589
+ borderTop: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.06)',
569
590
  }}>
570
591
  <span style={{ fontSize: 15, fontWeight: 800 }}>Ranked by reach</span>
571
592
  <span style={{ fontSize: 11, fontWeight: 800, color: '#000', background: '#FFD700', borderRadius: 10, padding: '2px 8px' }}>
572
593
  {fmt(visible.length)}{filtered ? ` of ${fmt(summary.people)}` : ''}
573
594
  </span>
574
- <span style={{ marginLeft: 'auto', fontSize: 11, color: '#777' }}>
595
+ <span style={{ marginLeft: 'auto', fontSize: 11, color: 'var(--sd-fg-4, #777)' }}>
575
596
  order follows the slider · <span style={{ color: slideColor }}>{slide.name.toLowerCase()}</span>
576
597
  </span>
577
598
  </div>
@@ -580,8 +601,8 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
580
601
  <div style={{
581
602
  height: LABEL_ROW, display: 'grid', alignItems: 'center', gap: 10, padding: '0 12px 0 15px',
582
603
  gridTemplateColumns: isMobile ? '44px 36px 1fr 44px' : COLUMNS,
583
- fontSize: 9, fontWeight: 700, color: '#555', textTransform: 'uppercase', letterSpacing: 0.5,
584
- borderBottom: '1px solid rgba(255,255,255,0.08)', boxSizing: 'border-box',
604
+ fontSize: 9, fontWeight: 700, color: 'var(--sd-fg-5, #555)', textTransform: 'uppercase', letterSpacing: 0.5,
605
+ borderBottom: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.08)', boxSizing: 'border-box',
585
606
  }}>
586
607
  <span title="Rank by score, then ways in. = means tied">#</span>
587
608
  <span />
@@ -607,14 +628,14 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
607
628
  ))}
608
629
 
609
630
  {visible.length === 0 && (
610
- <div style={{ position: 'absolute', top: 40, left: 0, right: 0, textAlign: 'center', color: '#888', fontSize: 13, padding: '0 16px' }}>
631
+ <div style={{ position: 'absolute', top: 40, left: 0, right: 0, textAlign: 'center', color: 'var(--sd-fg-3, #888)', fontSize: 13, padding: '0 16px' }}>
611
632
  {q
612
633
  ? <>No one matches ‘{query.trim()}’. Search covers names, headlines, companies and who knows them.</>
613
634
  : <>No one here with those filters.</>}
614
635
  <div style={{ marginTop: 12 }}>
615
636
  <button type="button" onClick={clearAll} style={{
616
637
  padding: '8px 16px', borderRadius: 8, cursor: 'pointer', fontSize: 12, fontWeight: 700,
617
- border: '1px solid rgba(255,255,255,0.15)', background: 'rgba(255,255,255,0.06)', color: '#fff',
638
+ border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.15)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.06)', color: 'var(--sd-fg-1, #fff)',
618
639
  }}>Clear</button>
619
640
  </div>
620
641
  </div>
@@ -625,6 +646,41 @@ export default function SeparationView({ connections = [], degree2 = [], fullDeg
625
646
  );
626
647
  }
627
648
 
649
+ // ── Zoom ───────────────────────────────────────────────────────────────────
650
+ // Low enough that even aiming at someone with dozens of ways in fits the window
651
+ // whole: the layout stays as it is, only smaller (Blake, 2026-10-03: "it should
652
+ // just be more zoomed out").
653
+ const ZOOM_MIN = 0.15;
654
+ const ZOOM_MAX = 1.5;
655
+
656
+ /** − | Fit | +, one segmented control as a Mac draws one. The middle says the zoom once you've changed it. */
657
+ function ZoomControl({ scale, fitted, onOut, onFit, onIn }) {
658
+ const seg = (extra = {}) => ({
659
+ height: 22, minWidth: 26, padding: '0 7px', border: 'none', background: 'none', color: 'var(--sd-fg-2, #c9cdd6)',
660
+ fontSize: 12, fontWeight: 600, lineHeight: 1, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
661
+ ...extra,
662
+ });
663
+ const line = { width: 1, alignSelf: 'stretch', margin: '4px 0', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.14)' };
664
+ return (
665
+ <div role="group" aria-label="Zoom the map" style={{
666
+ display: 'inline-flex', alignItems: 'center', flexShrink: 0, borderRadius: 7, overflow: 'hidden',
667
+ background: 'rgba(var(--sd-ink, 255, 255, 255), 0.07)', border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.13)',
668
+ boxShadow: '0 1px 0 rgba(var(--sd-ink, 255, 255, 255), 0.05) inset, 0 1px 2px rgba(0,0,0,0.35)',
669
+ }}>
670
+ <button type="button" onClick={onOut} disabled={scale <= ZOOM_MIN + 0.001} title="Zoom out" aria-label="Zoom out"
671
+ style={seg({ fontSize: 15, opacity: scale <= ZOOM_MIN + 0.001 ? 0.35 : 1 })}>−</button>
672
+ <span style={line} />
673
+ <button type="button" onClick={onFit} title={fitted ? 'The whole map fits the window' : 'Fit the whole map in the window'}
674
+ style={seg({ minWidth: 44, fontSize: 11, fontVariantNumeric: 'tabular-nums', color: fitted ? 'var(--sd-fg-3, #8f96a3)' : 'var(--sd-fg-1, #e6e9ef)' })}>
675
+ {fitted ? 'Fit' : `${Math.round(scale * 100)}%`}
676
+ </button>
677
+ <span style={line} />
678
+ <button type="button" onClick={onIn} disabled={scale >= ZOOM_MAX - 0.001} title="Zoom in" aria-label="Zoom in"
679
+ style={seg({ fontSize: 15, opacity: scale >= ZOOM_MAX - 0.001 ? 0.35 : 1 })}>+</button>
680
+ </div>
681
+ );
682
+ }
683
+
628
684
  // ── The summit map ─────────────────────────────────────────────────────────
629
685
  // A plain React <svg>: no d3, no canvas, no zoom — at most about 150 elements
630
686
  // whatever the network's size. Hover is pure CSS from the scoped <style>, so a
@@ -644,9 +700,13 @@ const MAP_CSS = `
644
700
  .sepmap .mv { transition: transform ${MOVE}; }
645
701
  .sepmap .rt, .sepmap .spk { transition: d ${MOVE}, stroke-opacity .12s; }
646
702
  .sepmap .in { animation: sepIn .3s ease-out both; }
703
+ /* The zoom glides too, and the list under the map with it. */
704
+ .sepmap { transition: width ${MOVE}, height ${MOVE}; }
705
+ .sepblock { transition: height ${MOVE}; }
706
+ .seprow { transition: top ${MOVE}; }
647
707
  @keyframes sepIn { from { opacity: 0; } to { opacity: 1; } }
648
708
  @media (prefers-reduced-motion: reduce) {
649
- .sepmap .mv, .sepmap .rt, .sepmap .spk { transition: none; }
709
+ .sepmap .mv, .sepmap .rt, .sepmap .spk, .sepmap, .sepblock, .seprow { transition: none; }
650
710
  .sepmap .in { animation: none; }
651
711
  }
652
712
  `;
@@ -666,7 +726,7 @@ function waysTag(p, mutuals) {
666
726
  return p.waysIn === 1 ? { text: 'only way in', rare: true, more: 0 } : { text: `${fmt(p.waysIn)} ways in`, rare: false, more: 0 };
667
727
  }
668
728
 
669
- const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, youLabel, isMobile, onPick, onPickBridge, mutualsBy, doors = false, cards = false }) {
729
+ const SummitMap = memo(function SummitMap({ layout, scale = 1, selectedKey, tierColors, youLabel, isMobile, onPick, onPickBridge, mutualsBy, doors = false, cards = false }) {
670
730
  const { width, height, you, people, bridges, links, spokes, ghosts = [], unscanned = 0, ghostLabel = null, drawn = 1 } = layout;
671
731
  const linksBy = useMemo(() => {
672
732
  const m = new Map();
@@ -677,7 +737,10 @@ const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, you
677
737
  const fs = isMobile ? 12 : 11;
678
738
 
679
739
  return (
680
- <svg className="sepmap" width={width} height={height} aria-hidden="true" style={{ display: 'block', overflow: 'visible' }}>
740
+ // Drawn at its own size and scaled whole by the viewBox, so zooming never
741
+ // lays it out again and everything stays sharp.
742
+ <svg className="sepmap" width={Math.round(width * scale)} height={Math.round(height * scale)} viewBox={`0 0 ${width} ${height}`} aria-hidden="true"
743
+ style={{ display: 'block', overflow: 'visible', margin: '0 auto', width: Math.round(width * scale), height: Math.round(height * scale) }}>
681
744
  <style>{MAP_CSS}</style>
682
745
  <defs>
683
746
  <linearGradient id="sepYouGrad" x1="0" y1="0" x2="1" y2="1">
@@ -709,7 +772,7 @@ const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, you
709
772
  })}
710
773
  {ghosts.map((g, i) => <circle key={`gd-${i}`} cx={g.x} cy={g.y} r={3.3} fill="#4a4f68" stroke="#6b7090" strokeWidth={0.6} strokeOpacity={0.6} />)}
711
774
  {ghostLabel && (
712
- <text x={ghostLabel.x} y={ghostLabel.y} fontSize={10.5} fontWeight={700} fill="#8a8fa8" style={HALO}>
775
+ <text x={ghostLabel.x} y={ghostLabel.y} fontSize={10.5} fontWeight={700} fill="var(--sd-fg-3, #8a8fa8)" style={HALO}>
713
776
  {`+${fmt(unscanned)} more mutual${unscanned === 1 ? '' : 's'}, in circles not scanned yet`}
714
777
  {unscanned > ghosts.length ? ` (${fmt(ghosts.length)} shown)` : ''}
715
778
  </text>
@@ -771,12 +834,12 @@ const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, you
771
834
  <>
772
835
  <circle r={pp.r} fill="var(--sd-bg)" stroke={c} strokeWidth={3} strokeOpacity={0.35 + 0.65 * drawn} />
773
836
  <text dy="0.35em" textAnchor="middle" fontSize={11} fontWeight={800} fill={c}>{initialsFor(p.person.name)}</text>
774
- <text x={lx} y={-20} fontSize={fs + 3} fontWeight={800} fill="#fff" style={HALO}>{clip(p.person.name)}</text>
775
- <text x={lx} y={-4} fontSize={fs} fill="#aaa" style={HALO}>{clip(subline(p.person))}</text>
837
+ <text x={lx} y={-20} fontSize={fs + 3} fontWeight={800} fill="var(--sd-fg-1, #fff)" style={HALO}>{clip(p.person.name)}</text>
838
+ <text x={lx} y={-4} fontSize={fs} fill="var(--sd-fg-3, #aaa)" style={HALO}>{clip(subline(p.person))}</text>
776
839
  <text x={lx} y={13} fontSize={fs} fontWeight={700} fill={c} style={HALO}>
777
840
  #{p.rank}{p.tied ? '=' : ''} · {p.tier}-tier · {p.score.toFixed(1)}
778
841
  </text>
779
- <text x={lx} y={29} fontSize={fs} fill="#ccc" style={HALO}>
842
+ <text x={lx} y={29} fontSize={fs} fill="var(--sd-fg-2, #ccc)" style={HALO}>
780
843
  {clip(tag.more
781
844
  ? `${fmt(tag.more)} mutual connections · ${fmt(p.waysIn)} drawn here`
782
845
  : p.waysIn === 1 ? '1 mutual connection: the only way in' : `${fmt(p.waysIn)} mutual connections, all drawn`)}
@@ -790,13 +853,13 @@ const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, you
790
853
  ) : (
791
854
  <>
792
855
  {sel && <circle r={pp.r + 3.5} fill="none" stroke="#fff" strokeWidth={1.5} />}
793
- <circle r={pp.r} fill={c} />
794
- <text x={14} dy="0.35em" fontSize={fs} fill="#ddd" style={HALO}>
856
+ <circle className="sd-dot" r={pp.r} fill={c} />
857
+ <text x={14} dy="0.35em" fontSize={fs} fill="var(--sd-fg-1, #ddd)" style={HALO}>
795
858
  {pp.label}
796
859
  <tspan dx={6} fill={c} fontWeight={700}>{p.score.toFixed(1)}</tspan>
797
860
  {/* How many mutual connections lead to them: one is the rare kind */}
798
861
  {doors && (
799
- <tspan dx={8} fontSize={fs - 2} fontWeight={700} fill={tag.rare ? RARE : '#778'}>{tag.text}</tspan>
862
+ <tspan dx={8} fontSize={fs - 2} fontWeight={700} fill={tag.rare ? 'var(--sd-cyan, #00E5FF)' : 'var(--sd-fg-4, #778)'}>{tag.text}</tspan>
800
863
  )}
801
864
  </text>
802
865
  </>
@@ -820,10 +883,10 @@ const SummitMap = memo(function SummitMap({ layout, selectedKey, tierColors, you
820
883
  : `${b.bridge.name} · ${b.bridge.tier}-tier${b.count > 1 ? ` · a way in to ${b.count} of these` : ''} · click to open`}</title>
821
884
  <g className="mv in" style={at(b.x, b.y)}>
822
885
  {cards ? <Pill b={b} c={c} big={people.length === 1 && people[0].big} /> : (<>
823
- <circle
886
+ <circle className="sd-dot"
824
887
  r={b.r}
825
888
  fill={b.unresolved ? 'none' : c}
826
- stroke={b.unresolved ? '#777' : 'var(--sd-bg)'}
889
+ stroke={b.unresolved ? 'var(--sd-fg-4, #777)' : 'var(--sd-bg)'}
827
890
  strokeWidth={b.unresolved ? 1 : 1.5}
828
891
  strokeDasharray={b.unresolved ? '2 2' : undefined}
829
892
  />
@@ -860,8 +923,8 @@ function Pill({ b, c, big }) {
860
923
  if (b.unresolved) {
861
924
  return (
862
925
  <g>
863
- <rect x={-PILL_W} y={-14} width={PILL_W} height={28} rx={14} fill="#11132a" stroke="#555" strokeDasharray="3 3" />
864
- <text x={-PILL_W + 14} dy="0.35em" fontSize={11.5} fontStyle="italic" fill="#888">{clipText(b.label, 30)}</text>
926
+ <rect x={-PILL_W} y={-14} width={PILL_W} height={28} rx={14} fill="var(--sd-card, #11132a)" stroke="#555" strokeDasharray="3 3" />
927
+ <text x={-PILL_W + 14} dy="0.35em" fontSize={11.5} fontStyle="italic" fill="var(--sd-fg-3, #888)">{clipText(b.label, 30)}</text>
865
928
  </g>
866
929
  );
867
930
  }
@@ -874,11 +937,11 @@ function Pill({ b, c, big }) {
874
937
  const tw = chipW(tag);
875
938
  return (
876
939
  <g>
877
- <rect x={-PILL_W} y={-14} width={PILL_W} height={28} rx={14} fill="#14172e"
878
- stroke={hot ? 'rgba(255,215,0,0.55)' : 'rgba(255,255,255,0.09)'} strokeWidth={hot ? 1.3 : 1} />
879
- <circle cx={-PILL_W + 15} r={10} fill={c} />
940
+ <rect x={-PILL_W} y={-14} width={PILL_W} height={28} rx={14} fill="var(--sd-card, #14172e)"
941
+ stroke={hot ? 'rgba(255,215,0,0.55)' : 'rgba(var(--sd-ink, 255, 255, 255), 0.09)'} strokeWidth={hot ? 1.3 : 1} />
942
+ <circle className="sd-dot" cx={-PILL_W + 15} r={10} fill={c} />
880
943
  <text x={-PILL_W + 15} dy="0.35em" textAnchor="middle" fontSize={8} fontWeight={800} fill="#000">{initialsFor(b.bridge.name)}</text>
881
- <text x={-PILL_W + 31} dy="0.35em" fontSize={12} fontWeight={600} fill="#e8e8f0">
944
+ <text x={-PILL_W + 31} dy="0.35em" fontSize={12} fontWeight={600} fill="var(--sd-fg-1, #e8e8f0)">
882
945
  {clipText(b.bridge.name, Math.max(6, Math.floor((PILL_W - 31 - tw - 10) / 6.4)))}
883
946
  </text>
884
947
  <rect x={-tw - 7} y={-9} width={tw} height={18} rx={9} fill={`${c}22`} />
@@ -892,14 +955,14 @@ function SmallCard({ p, c, tag, width, sel }) {
892
955
  const tw = chipW(tag.text);
893
956
  return (
894
957
  <g>
895
- <rect x={0} y={-20} width={width} height={40} rx={10} fill="#151830" stroke={sel ? '#fff' : 'rgba(255,255,255,0.09)'} strokeWidth={sel ? 1.5 : 1} />
896
- <text x={12} dy="0.35em" fontSize={11} fontWeight={800} fill="#FFD700">#{p.rank}{p.tied ? '=' : ''}</text>
897
- <text x={60} y={-3} fontSize={13} fontWeight={700} fill="#fff">{clipText(p.person.name, Math.floor((width - 60 - 70) / 7))}</text>
898
- <text x={60} y={12} fontSize={10.5} fill="#8a8fa8">{clipText(subline(p.person), Math.floor((width - 60 - tw - 20) / 5.6))}</text>
958
+ <rect x={0} y={-20} width={width} height={40} rx={10} fill="var(--sd-card, #151830)" stroke={sel ? 'var(--sd-fg-1, #fff)' : 'rgba(var(--sd-ink, 255, 255, 255), 0.09)'} strokeWidth={sel ? 1.5 : 1} />
959
+ <text x={12} dy="0.35em" fontSize={11} fontWeight={800} fill="var(--sd-gold, #FFD700)">#{p.rank}{p.tied ? '=' : ''}</text>
960
+ <text x={60} y={-3} fontSize={13} fontWeight={700} fill="var(--sd-fg-1, #fff)">{clipText(p.person.name, Math.floor((width - 60 - 70) / 7))}</text>
961
+ <text x={60} y={12} fontSize={10.5} fill="var(--sd-fg-3, #8a8fa8)">{clipText(subline(p.person), Math.floor((width - 60 - tw - 20) / 5.6))}</text>
899
962
  <text x={width - 12} y={-2} textAnchor="end" fontSize={14} fontWeight={800} fill={c}>{p.score.toFixed(1)}</text>
900
963
  <rect x={width - 12 - tw} y={4} width={tw} height={14} rx={7}
901
- fill={tag.rare ? 'rgba(0,229,255,0.1)' : 'rgba(255,255,255,0.06)'} stroke={tag.rare ? 'rgba(0,229,255,0.35)' : 'rgba(255,255,255,0.14)'} />
902
- <text x={width - 12 - tw / 2} y={11} dy="0.35em" textAnchor="middle" fontSize={9.5} fontWeight={800} fill={tag.rare ? RARE : '#cfd3e6'}>{tag.text}</text>
964
+ fill={tag.rare ? 'rgba(0,229,255,0.1)' : 'rgba(var(--sd-ink, 255, 255, 255), 0.06)'} stroke={tag.rare ? 'rgba(0,229,255,0.35)' : 'rgba(var(--sd-ink, 255, 255, 255), 0.14)'} />
965
+ <text x={width - 12 - tw / 2} y={11} dy="0.35em" textAnchor="middle" fontSize={9.5} fontWeight={800} fill={tag.rare ? 'var(--sd-cyan, #00E5FF)' : 'var(--sd-fg-2, #cfd3e6)'}>{tag.text}</text>
903
966
  </g>
904
967
  );
905
968
  }
@@ -915,16 +978,16 @@ function BigCard({ p, c, tag, width, fs }) {
915
978
  const room = Math.floor((width - tx - 14) / 6.6);
916
979
  return (
917
980
  <g>
918
- <rect x={0} y={-76} width={width} height={152} rx={16} fill="#151830" stroke="rgba(255,215,0,0.45)" />
981
+ <rect x={0} y={-76} width={width} height={152} rx={16} fill="var(--sd-card, #151830)" stroke="rgba(255,215,0,0.45)" />
919
982
  <circle cx={48} r={32} fill="var(--sd-bg)" stroke={c} strokeWidth={3} />
920
983
  <text x={48} dy="0.35em" textAnchor="middle" fontSize={18} fontWeight={800} fill={c}>{initialsFor(p.person.name)}</text>
921
- <text x={tx} y={-40} fontSize={11} fontWeight={800} fill="#FFD700">#{p.rank}{p.tied ? '=' : ''} · {p.tier}-tier · {p.score.toFixed(1)}</text>
922
- <text x={tx} y={-17} fontSize={fs + 8} fontWeight={800} fill="#fff">{clipText(p.person.name, Math.floor(room * 0.72))}</text>
923
- <text x={tx} y={1} fontSize={12} fill="#8a8fa8">{clipText(subline(p.person), room)}</text>
984
+ <text x={tx} y={-40} fontSize={11} fontWeight={800} fill="var(--sd-gold, #FFD700)">#{p.rank}{p.tied ? '=' : ''} · {p.tier}-tier · {p.score.toFixed(1)}</text>
985
+ <text x={tx} y={-17} fontSize={fs + 8} fontWeight={800} fill="var(--sd-fg-1, #fff)">{clipText(p.person.name, Math.floor(room * 0.72))}</text>
986
+ <text x={tx} y={1} fontSize={12} fill="var(--sd-fg-3, #8a8fa8)">{clipText(subline(p.person), room)}</text>
924
987
  <rect x={tx} y={12} width={w1} height={20} rx={10} fill="rgba(255,112,67,0.12)" stroke="rgba(255,112,67,0.4)" />
925
988
  <text x={tx + w1 / 2} y={22} dy="0.35em" textAnchor="middle" fontSize={10.5} fontWeight={800} fill={EASY}>{first}</text>
926
- <rect x={tx + w1 + 6} y={12} width={w2} height={20} rx={10} fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.14)" />
927
- <text x={tx + w1 + 6 + w2 / 2} y={22} dy="0.35em" textAnchor="middle" fontSize={10.5} fontWeight={800} fill="#cfd3e6">{second}</text>
989
+ <rect x={tx + w1 + 6} y={12} width={w2} height={20} rx={10} fill="rgba(var(--sd-ink, 255, 255, 255), 0.06)" stroke="rgba(var(--sd-ink, 255, 255, 255), 0.14)" />
990
+ <text x={tx + w1 + 6 + w2 / 2} y={22} dy="0.35em" textAnchor="middle" fontSize={10.5} fontWeight={800} fill="var(--sd-fg-2, #cfd3e6)">{second}</text>
928
991
  <text x={tx} y={50} fontSize={10.5} fill="#6b7090">
929
992
  {tag.more ? `The ${fmt(tag.more)} is LinkedIn’s count. The other ${fmt(tag.more - p.waysIn)}` : named === 1 ? 'Only one of your connections knows them.' : `${fmt(named)} of your connections know them.`}
930
993
  </text>
@@ -944,19 +1007,19 @@ const ellipsis = { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'no
944
1007
  function Via({ p, route, tierColors, compact }) {
945
1008
  if (!compact) return <WayIn p={p} route={route} tierColors={tierColors} />;
946
1009
  if (!route?.bridge) {
947
- return <span style={{ ...ellipsis, color: '#777', fontStyle: 'italic', fontSize: compact ? 11 : 12 }}>via {CANT_NAME}</span>;
1010
+ return <span style={{ ...ellipsis, color: 'var(--sd-fg-4, #777)', fontStyle: 'italic', fontSize: compact ? 11 : 12 }}>via {CANT_NAME}</span>;
948
1011
  }
949
1012
  const b = route.bridge;
950
1013
  const extra = p.waysIn - 1;
951
1014
  return (
952
1015
  <span style={{ display: 'flex', alignItems: 'center', gap: 5, minWidth: 0, fontSize: compact ? 11 : 12 }}>
953
- <span style={{ color: '#666', flexShrink: 0 }}>via</span>
1016
+ <span style={{ color: 'var(--sd-fg-4, #666)', flexShrink: 0 }}>via</span>
954
1017
  {!compact && <Avatar person={b} size={16} tierColors={tierColors} />}
955
1018
  <span style={{ ...ellipsis, color: tierColors[b.tier] || '#aaa', fontWeight: 600, minWidth: 0 }}>{compact ? shortName(b.name) : b.name}</span>
956
1019
  {extra > 0 && (
957
1020
  <span title={`Every way in:\n${everyRoute(p)}`} style={{
958
1021
  flexShrink: 0, padding: '1px 6px', borderRadius: 8, fontSize: 10, fontWeight: 800,
959
- color: ORANGE, background: 'rgba(255,107,53,0.15)',
1022
+ color: 'var(--sd-orange, #FF6B35)', background: 'rgba(255,107,53,0.15)',
960
1023
  }}>+{extra}</span>
961
1024
  )}
962
1025
  </span>
@@ -971,10 +1034,10 @@ function WayIn({ p, route, tierColors }) {
971
1034
  <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }} title={`Every way in:\n${everyRoute(p)}`}>
972
1035
  {b ? <Avatar person={b} size={26} tierColors={tierColors} /> : <span style={{ width: 26, height: 26, borderRadius: '50%', border: '1px dashed #666', flexShrink: 0 }} />}
973
1036
  <span style={{ minWidth: 0, display: 'flex', flexDirection: 'column' }}>
974
- <span style={{ ...ellipsis, fontSize: 13, fontWeight: 700, color: b ? tierColors[b.tier] || '#ddd' : '#777', fontStyle: b ? 'normal' : 'italic' }}>
1037
+ <span style={{ ...ellipsis, fontSize: 13, fontWeight: 700, color: b ? tierColors[b.tier] || 'var(--sd-fg-1, #ddd)' : 'var(--sd-fg-4, #777)', fontStyle: b ? 'normal' : 'italic' }}>
975
1038
  {b ? b.name : CANT_NAME}
976
1039
  </span>
977
- <span style={{ ...ellipsis, fontSize: 10.5, marginTop: 1, color: extra > 0 ? '#99a' : RARE, fontWeight: extra > 0 ? 500 : 700 }}>
1040
+ <span style={{ ...ellipsis, fontSize: 10.5, marginTop: 1, color: extra > 0 ? 'var(--sd-fg-3, #99a)' : RARE, fontWeight: extra > 0 ? 500 : 700 }}>
978
1041
  {extra > 0 ? `+${extra} more way${extra > 1 ? 's' : ''} in` : 'only way in'}
979
1042
  </span>
980
1043
  </span>
@@ -991,7 +1054,7 @@ function RarityBar({ p, rarity }) {
991
1054
  return (
992
1055
  <span style={{ display: 'flex', flexDirection: 'column', gap: 5, minWidth: 0 }}
993
1056
  title={`${rarity.count} mutual connection${rarity.count === 1 ? '' : 's'}${rarity.from === 'scans' ? ' (from your scans, so it can only go up)' : ' (LinkedIn’s count)'}. ${RARITY_NOTE}`}>
994
- <span style={{ height: 6, borderRadius: 3, background: 'rgba(255,255,255,0.07)', overflow: 'hidden' }}>
1057
+ <span style={{ height: 6, borderRadius: 3, background: 'rgba(var(--sd-ink, 255, 255, 255), 0.07)', overflow: 'hidden' }}>
995
1058
  <span style={{ display: 'block', height: '100%', width: `${fill * 100}%`, borderRadius: 3, background: info.color }} />
996
1059
  </span>
997
1060
  <span style={{ ...ellipsis, fontSize: 10.5, fontWeight: 700, color: info.color }}>
@@ -1008,12 +1071,12 @@ function Tags({ status, rarity }) {
1008
1071
  <>
1009
1072
  {status === 'asked' && (
1010
1073
  <span title="You sent a request. It shows everywhere in the app." style={{
1011
- flexShrink: 0, fontSize: 9, fontWeight: 800, color: '#FFD700', border: '1px dashed rgba(255,215,0,0.6)', borderRadius: 4, padding: '0 4px',
1074
+ flexShrink: 0, fontSize: 9, fontWeight: 800, color: 'var(--sd-gold, #FFD700)', border: '1px dashed rgba(255,215,0,0.6)', borderRadius: 4, padding: '0 4px',
1012
1075
  }}>Request sent</span>
1013
1076
  )}
1014
1077
  {status === 'connected' && (
1015
1078
  <span title="Already one of your connections" style={{
1016
- flexShrink: 0, fontSize: 9, fontWeight: 800, color: '#00ff88', border: '1px solid rgba(0,255,136,0.5)', borderRadius: 4, padding: '0 4px',
1079
+ flexShrink: 0, fontSize: 9, fontWeight: 800, color: 'var(--sd-green, #00ff88)', border: '1px solid rgba(0,255,136,0.5)', borderRadius: 4, padding: '0 4px',
1017
1080
  }}>Connected</span>
1018
1081
  )}
1019
1082
  {info && status !== 'connected' && (
@@ -1039,21 +1102,21 @@ function PathPicker({ facets, text, onText, onPick, onClose, isMobile }) {
1039
1102
  else if (companies.length === 1 && !sectors.length) onPick({ kind: 'company', key: companies[0].name, label: companies[0].name });
1040
1103
  }
1041
1104
  };
1042
- const sub = { fontSize: 9, fontWeight: 700, color: '#667', letterSpacing: 1, textTransform: 'uppercase', margin: '10px 0 6px' };
1105
+ const sub = { fontSize: 9, fontWeight: 700, color: 'var(--sd-fg-4, #667)', letterSpacing: 1, textTransform: 'uppercase', margin: '10px 0 6px' };
1043
1106
  return (
1044
1107
  <>
1045
1108
  <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 40 }} />
1046
1109
  <div role="dialog" aria-label="Pick a sector or a company" style={{
1047
1110
  position: 'absolute', zIndex: 41, top: isMobile ? 52 : 44, left: isMobile ? 6 : 14, width: isMobile ? 'calc(100% - 12px)' : 'min(560px, calc(100% - 28px))',
1048
1111
  maxHeight: 340, overflowY: 'auto', boxSizing: 'border-box', padding: 12, borderRadius: 12,
1049
- background: '#0c101e', border: `1px solid ${PATH}55`, boxShadow: '0 12px 40px rgba(0,0,0,0.6)',
1112
+ background: 'var(--sd-surface, #0c101e)', border: `1px solid ${PATH}55`, boxShadow: '0 12px 40px rgba(0,0,0,0.6)',
1050
1113
  }}>
1051
1114
  <input
1052
1115
  autoFocus type="search" value={text} onChange={(e) => onText(e.target.value)} onKeyDown={onKey}
1053
1116
  placeholder="Type a sector or a company" aria-label="Type a sector or a company"
1054
1117
  style={{
1055
1118
  width: '100%', height: isMobile ? 44 : 34, boxSizing: 'border-box', padding: '0 12px', borderRadius: 8, outline: 'none',
1056
- color: '#fff', fontSize: isMobile ? 16 : 13, border: '1px solid rgba(255,255,255,0.14)', background: 'rgba(255,255,255,0.06)',
1119
+ color: 'var(--sd-fg-1, #fff)', fontSize: isMobile ? 16 : 13, border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.14)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.06)',
1057
1120
  }}
1058
1121
  />
1059
1122
  {sectors.length > 0 && <div style={sub}>Sectors · inferred from company names and headlines</div>}
@@ -1061,11 +1124,11 @@ function PathPicker({ facets, text, onText, onPick, onClose, isMobile }) {
1061
1124
  {sectors.map((i) => (
1062
1125
  <button key={i.key} type="button" onClick={() => onPick({ kind: 'sector', key: i.key, label: i.label, color: i.color })} style={{
1063
1126
  height: 28, padding: '0 10px', borderRadius: 14, cursor: 'pointer', fontSize: 11.5, fontWeight: 700, whiteSpace: 'nowrap',
1064
- border: `1px solid ${i.color}66`, background: `${i.color}14`, color: '#ddd', display: 'inline-flex', alignItems: 'center', gap: 6,
1127
+ border: `1px solid ${i.color}66`, background: `${i.color}14`, color: 'var(--sd-fg-1, #ddd)', display: 'inline-flex', alignItems: 'center', gap: 6,
1065
1128
  }}>
1066
1129
  <span style={{ width: 7, height: 7, borderRadius: '50%', background: i.color }} />
1067
1130
  {i.label}
1068
- <span style={{ fontWeight: 500, color: '#889' }}>{fmt(i.count)}</span>
1131
+ <span style={{ fontWeight: 500, color: 'var(--sd-fg-3, #889)' }}>{fmt(i.count)}</span>
1069
1132
  </button>
1070
1133
  ))}
1071
1134
  </div>
@@ -1074,15 +1137,15 @@ function PathPicker({ facets, text, onText, onPick, onClose, isMobile }) {
1074
1137
  {companies.map((c) => (
1075
1138
  <button key={c.name} type="button" onClick={() => onPick({ kind: 'company', key: c.name, label: c.name })} style={{
1076
1139
  height: 28, padding: '0 10px', borderRadius: 14, cursor: 'pointer', fontSize: 11.5, fontWeight: 600, whiteSpace: 'nowrap',
1077
- border: '1px solid rgba(255,255,255,0.12)', background: 'rgba(255,255,255,0.04)', color: '#ccc',
1140
+ border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.12)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.04)', color: 'var(--sd-fg-2, #ccc)',
1078
1141
  }}>
1079
1142
  {c.name}
1080
- <span style={{ marginLeft: 6, fontWeight: 500, color: '#889' }}>{fmt(c.count)}</span>
1143
+ <span style={{ marginLeft: 6, fontWeight: 500, color: 'var(--sd-fg-3, #889)' }}>{fmt(c.count)}</span>
1081
1144
  </button>
1082
1145
  ))}
1083
1146
  </div>
1084
1147
  {!sectors.length && !companies.length && (
1085
- <div style={{ fontSize: 12, color: '#888', padding: '12px 2px 4px' }}>
1148
+ <div style={{ fontSize: 12, color: 'var(--sd-fg-3, #888)', padding: '12px 2px 4px' }}>
1086
1149
  {facets ? `Nothing matches ‘${text.trim()}’.` : 'Reading where everyone works…'}
1087
1150
  </div>
1088
1151
  )}
@@ -1098,10 +1161,10 @@ const EASY = '#FF7043';
1098
1161
  const SLIDER_CSS = `
1099
1162
  .sepslide { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 24px; margin: 4px 0 0; background: transparent; cursor: pointer; }
1100
1163
  .sepslide::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: linear-gradient(90deg, ${RARE} 0%, #FFD700 50%, ${EASY} 100%); }
1101
- .sepslide::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -7px; border-radius: 50%; background: var(--sd-bg); border: 3px solid #fff; box-shadow: 0 0 10px rgba(255,255,255,0.45); }
1164
+ .sepslide::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -7px; border-radius: 50%; background: var(--sd-bg); border: 3px solid #fff; box-shadow: 0 0 10px rgba(var(--sd-ink, 255, 255, 255), 0.45); }
1102
1165
  .sepslide::-moz-range-track { height: 6px; border-radius: 3px; background: linear-gradient(90deg, ${RARE} 0%, #FFD700 50%, ${EASY} 100%); }
1103
- .sepslide::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--sd-bg); border: 3px solid #fff; box-shadow: 0 0 10px rgba(255,255,255,0.45); }
1104
- .sepslide:focus-visible { outline: 2px solid rgba(255,255,255,0.7); outline-offset: 3px; border-radius: 6px; }
1166
+ .sepslide::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--sd-bg); border: 3px solid #fff; box-shadow: 0 0 10px rgba(var(--sd-ink, 255, 255, 255), 0.45); }
1167
+ .sepslide:focus-visible { outline: 2px solid rgba(var(--sd-ink, 255, 255, 255), 0.7); outline-offset: 3px; border-radius: 6px; }
1105
1168
  `;
1106
1169
  const RARITY_NOTE = 'Rarity is how many mutual connections lead to them: few is a rare way in, many is warm (likely to accept). It never changes a score or a tier.';
1107
1170
 
@@ -1126,47 +1189,48 @@ const Row = memo(function Row({ p, top, height, isMobile, selected, tierColors,
1126
1189
  aria-pressed={selected}
1127
1190
  onClick={() => onPick(p)}
1128
1191
  onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onPick(p); } }}
1129
- onMouseEnter={(e) => { if (!selected) e.currentTarget.style.background = 'rgba(255,255,255,0.04)'; }}
1192
+ onMouseEnter={(e) => { if (!selected) e.currentTarget.style.background = 'rgba(var(--sd-ink, 255, 255, 255), 0.04)'; }}
1130
1193
  onMouseLeave={(e) => { e.currentTarget.style.background = base; }}
1194
+ className="seprow"
1131
1195
  style={{
1132
1196
  position: 'absolute', top, left: 0, right: 0, height, boxSizing: 'border-box',
1133
1197
  display: 'grid', alignItems: 'center', gap: 10, padding: '0 12px',
1134
1198
  gridTemplateColumns: isMobile ? '44px 36px 1fr 44px' : COLUMNS,
1135
1199
  borderLeft: `3px solid ${selected ? ORANGE : 'transparent'}`,
1136
- borderBottom: '1px solid rgba(255,255,255,0.04)',
1200
+ borderBottom: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.04)',
1137
1201
  background: base, cursor: 'pointer',
1138
1202
  }}
1139
1203
  >
1140
- <span style={{ fontSize: isMobile ? 11 : 12, fontWeight: 800, color: podium ? c : '#555', whiteSpace: 'nowrap' }}>{rank}</span>
1204
+ <span style={{ fontSize: isMobile ? 11 : 12, fontWeight: 800, color: podium ? c : 'var(--sd-fg-5, #555)', whiteSpace: 'nowrap' }}>{rank}</span>
1141
1205
  <Avatar person={person} size={32} tierColors={tierColors} />
1142
1206
 
1143
1207
  {isMobile ? (
1144
1208
  <div style={{ minWidth: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
1145
1209
  <span style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 }}>
1146
- <span style={{ ...ellipsis, fontSize: 13, fontWeight: 600, color: member ? '#888' : '#fff', minWidth: 0 }}>
1147
- {person.name}{member && <span style={{ fontSize: 10, color: '#666', fontWeight: 400 }}> · out of network</span>}
1210
+ <span style={{ ...ellipsis, fontSize: 13, fontWeight: 600, color: member ? 'var(--sd-fg-3, #888)' : 'var(--sd-fg-1, #fff)', minWidth: 0 }}>
1211
+ {person.name}{member && <span style={{ fontSize: 10, color: 'var(--sd-fg-4, #666)', fontWeight: 400 }}> · out of network</span>}
1148
1212
  </span>
1149
1213
  <Tags status={status} rarity={rarity} />
1150
1214
  </span>
1151
1215
  <Via p={p} route={route} tierColors={tierColors} compact />
1152
- <span style={{ ...ellipsis, fontSize: 10, color: '#666' }}>{subline(person)}</span>
1216
+ <span style={{ ...ellipsis, fontSize: 10, color: 'var(--sd-fg-4, #666)' }}>{subline(person)}</span>
1153
1217
  </div>
1154
1218
  ) : (
1155
1219
  <>
1156
1220
  <div style={{ minWidth: 0 }}>
1157
1221
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>
1158
- <span style={{ ...ellipsis, fontSize: 13, fontWeight: 600, color: member ? '#888' : '#fff' }}>{person.name}</span>
1222
+ <span style={{ ...ellipsis, fontSize: 13, fontWeight: 600, color: member ? 'var(--sd-fg-3, #888)' : 'var(--sd-fg-1, #fff)' }}>{person.name}</span>
1159
1223
  <span style={{ flexShrink: 0, fontSize: 9, fontWeight: 800, color: c, border: `1px solid ${c}55`, borderRadius: 4, padding: '0 4px' }}>{p.tier}</span>
1160
1224
  {/* The rarity has its own column here */}
1161
1225
  <Tags status={status} rarity={null} />
1162
- {member && <span style={{ flexShrink: 0, fontSize: 10, color: '#666' }}>out of network</span>}
1226
+ {member && <span style={{ flexShrink: 0, fontSize: 10, color: 'var(--sd-fg-4, #666)' }}>out of network</span>}
1163
1227
  </div>
1164
- <div style={{ ...ellipsis, fontSize: 10, color: '#777', marginTop: 2 }}>{subline(person)}</div>
1228
+ <div style={{ ...ellipsis, fontSize: 10, color: 'var(--sd-fg-4, #777)', marginTop: 2 }}>{subline(person)}</div>
1165
1229
  </div>
1166
1230
  <Via p={p} route={route} tierColors={tierColors} />
1167
1231
  <RarityBar p={p} rarity={rarity} />
1168
1232
  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
1169
- <div style={{ flex: 1, height: 6, background: 'rgba(255,255,255,0.06)', borderRadius: 3 }}>
1233
+ <div style={{ flex: 1, height: 6, background: 'rgba(var(--sd-ink, 255, 255, 255), 0.06)', borderRadius: 3 }}>
1170
1234
  <div style={{ height: '100%', borderRadius: 3, background: c, width: `${Math.max(0, Math.min(1, p.score / 10)) * 100}%` }} />
1171
1235
  </div>
1172
1236
  <span style={{ fontSize: 15, fontWeight: 800, color: c, width: 30, textAlign: 'right' }}>{p.score.toFixed(1)}</span>
@@ -1177,7 +1241,7 @@ const Row = memo(function Row({ p, top, height, isMobile, selected, tierColors,
1177
1241
  {isMobile && (
1178
1242
  <div style={{ textAlign: 'right' }}>
1179
1243
  <div style={{ fontSize: 13, fontWeight: 800, color: c }}>{p.score.toFixed(1)}</div>
1180
- <div style={{ fontSize: 9, color: '#666', fontWeight: 700 }}>{p.tier}</div>
1244
+ <div style={{ fontSize: 9, color: 'var(--sd-fg-4, #666)', fontWeight: 700 }}>{p.tier}</div>
1181
1245
  </div>
1182
1246
  )}
1183
1247
  </div>