@leanspec/ui 0.2.7 → 0.2.9

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 (262) hide show
  1. package/.next/standalone/packages/ui/.next/BUILD_ID +1 -1
  2. package/.next/standalone/packages/ui/.next/app-path-routes-manifest.json +4 -0
  3. package/.next/standalone/packages/ui/.next/build-manifest.json +4 -4
  4. package/.next/standalone/packages/ui/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/packages/ui/.next/routes-manifest.json +24 -0
  6. package/.next/standalone/packages/ui/.next/server/app/_global-error/page/build-manifest.json +2 -2
  7. package/.next/standalone/packages/ui/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/packages/ui/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/packages/ui/.next/server/app/_global-error.html +2 -2
  10. package/.next/standalone/packages/ui/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/packages/ui/.next/server/app/_not-found/page/build-manifest.json +2 -2
  16. package/.next/standalone/packages/ui/.next/server/app/_not-found/page.js +1 -1
  17. package/.next/standalone/packages/ui/.next/server/app/_not-found/page.js.nft.json +1 -1
  18. package/.next/standalone/packages/ui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/packages/ui/.next/server/app/_not-found.html +2 -2
  20. package/.next/standalone/packages/ui/.next/server/app/_not-found.rsc +19 -19
  21. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_full.segment.rsc +19 -19
  22. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  23. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +3 -3
  24. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_tree.segment.rsc +6 -6
  26. package/.next/standalone/packages/ui/.next/server/app/api/context/route/app-paths-manifest.json +3 -0
  27. package/.next/standalone/packages/ui/.next/server/app/api/context/route/build-manifest.json +11 -0
  28. package/.next/standalone/packages/ui/.next/server/app/api/context/route/server-reference-manifest.json +4 -0
  29. package/.next/standalone/packages/ui/.next/server/app/api/context/route.js +8 -0
  30. package/.next/standalone/packages/ui/.next/server/app/api/context/route.js.map +5 -0
  31. package/.next/standalone/packages/ui/.next/server/app/api/context/route.js.nft.json +1 -0
  32. package/.next/standalone/packages/ui/.next/server/app/api/context/route_client-reference-manifest.js +2 -0
  33. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route/app-paths-manifest.json +3 -0
  34. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route/build-manifest.json +11 -0
  35. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route/server-reference-manifest.json +4 -0
  36. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route.js +8 -0
  37. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route.js.map +5 -0
  38. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route.js.nft.json +1 -0
  39. package/.next/standalone/packages/ui/.next/server/app/api/dependencies/route_client-reference-manifest.js +2 -0
  40. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route.js.nft.json +1 -1
  41. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route.js.nft.json +1 -1
  42. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route.js.nft.json +1 -1
  43. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route.js.nft.json +1 -1
  44. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route.js.nft.json +1 -1
  45. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route.js.nft.json +1 -1
  46. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route.js.nft.json +1 -1
  47. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/route.js.nft.json +1 -1
  48. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route.js.nft.json +1 -1
  49. package/.next/standalone/packages/ui/.next/server/app/api/projects/route.js.nft.json +1 -1
  50. package/.next/standalone/packages/ui/.next/server/app/api/revalidate/route.js.nft.json +1 -1
  51. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/dependency-graph/route.js.nft.json +1 -1
  52. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/route.js.nft.json +1 -1
  53. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/status/route.js.nft.json +1 -1
  54. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/subspecs/[file]/route.js.nft.json +1 -1
  55. package/.next/standalone/packages/ui/.next/server/app/api/stats/route.js.nft.json +1 -1
  56. package/.next/standalone/packages/ui/.next/server/app/context/page/app-paths-manifest.json +3 -0
  57. package/.next/standalone/packages/ui/.next/server/app/context/page/build-manifest.json +18 -0
  58. package/.next/standalone/packages/ui/.next/server/app/context/page/next-font-manifest.json +6 -0
  59. package/.next/standalone/packages/ui/.next/server/app/context/page/react-loadable-manifest.json +1 -0
  60. package/.next/standalone/packages/ui/.next/server/app/context/page/server-reference-manifest.json +4 -0
  61. package/.next/standalone/packages/ui/.next/server/app/context/page.js +19 -0
  62. package/.next/standalone/packages/ui/.next/server/app/context/page.js.map +5 -0
  63. package/.next/standalone/packages/ui/.next/server/app/context/page.js.nft.json +1 -0
  64. package/.next/standalone/packages/ui/.next/server/app/context/page_client-reference-manifest.js +2 -0
  65. package/.next/standalone/packages/ui/.next/server/app/dependencies/page/app-paths-manifest.json +3 -0
  66. package/.next/standalone/packages/ui/.next/server/app/dependencies/page/build-manifest.json +18 -0
  67. package/.next/standalone/packages/ui/.next/server/app/dependencies/page/next-font-manifest.json +6 -0
  68. package/.next/standalone/packages/ui/.next/server/app/dependencies/page/react-loadable-manifest.json +1 -0
  69. package/.next/standalone/packages/ui/.next/server/app/dependencies/page/server-reference-manifest.json +4 -0
  70. package/.next/standalone/packages/ui/.next/server/app/dependencies/page.js +19 -0
  71. package/.next/standalone/packages/ui/.next/server/app/dependencies/page.js.map +5 -0
  72. package/.next/standalone/packages/ui/.next/server/app/dependencies/page.js.nft.json +1 -0
  73. package/.next/standalone/packages/ui/.next/server/app/dependencies/page_client-reference-manifest.js +2 -0
  74. package/.next/standalone/packages/ui/.next/server/app/page/build-manifest.json +2 -2
  75. package/.next/standalone/packages/ui/.next/server/app/page.js +1 -1
  76. package/.next/standalone/packages/ui/.next/server/app/page.js.nft.json +1 -1
  77. package/.next/standalone/packages/ui/.next/server/app/page_client-reference-manifest.js +1 -1
  78. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/build-manifest.json +2 -2
  79. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js +1 -1
  80. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js.nft.json +1 -1
  81. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page_client-reference-manifest.js +1 -1
  82. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/build-manifest.json +2 -2
  83. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js +1 -1
  84. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js.nft.json +1 -1
  85. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page_client-reference-manifest.js +1 -1
  86. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/build-manifest.json +2 -2
  87. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js +1 -1
  88. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js.nft.json +1 -1
  89. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page_client-reference-manifest.js +1 -1
  90. package/.next/standalone/packages/ui/.next/server/app/projects/page/build-manifest.json +2 -2
  91. package/.next/standalone/packages/ui/.next/server/app/projects/page.js +1 -1
  92. package/.next/standalone/packages/ui/.next/server/app/projects/page.js.nft.json +1 -1
  93. package/.next/standalone/packages/ui/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  94. package/.next/standalone/packages/ui/.next/server/app/projects.html +2 -2
  95. package/.next/standalone/packages/ui/.next/server/app/projects.rsc +24 -23
  96. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_full.segment.rsc +24 -23
  97. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_index.segment.rsc +9 -9
  98. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_tree.segment.rsc +3 -3
  99. package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +2 -2
  100. package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects.segment.rsc +1 -1
  101. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page/build-manifest.json +2 -2
  102. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page.js +1 -1
  103. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page.js.nft.json +1 -1
  104. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page_client-reference-manifest.js +1 -1
  105. package/.next/standalone/packages/ui/.next/server/app/specs/page/build-manifest.json +2 -2
  106. package/.next/standalone/packages/ui/.next/server/app/specs/page.js +1 -1
  107. package/.next/standalone/packages/ui/.next/server/app/specs/page.js.nft.json +1 -1
  108. package/.next/standalone/packages/ui/.next/server/app/specs/page_client-reference-manifest.js +1 -1
  109. package/.next/standalone/packages/ui/.next/server/app/stats/page/build-manifest.json +2 -2
  110. package/.next/standalone/packages/ui/.next/server/app/stats/page.js +1 -1
  111. package/.next/standalone/packages/ui/.next/server/app/stats/page.js.nft.json +1 -1
  112. package/.next/standalone/packages/ui/.next/server/app/stats/page_client-reference-manifest.js +1 -1
  113. package/.next/standalone/packages/ui/.next/server/app-paths-manifest.json +4 -0
  114. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__3559376c._.js +2 -2
  115. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__65667b70._.js +1 -1
  116. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__803d07f0._.js +1 -1
  117. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__84cdc14a._.js +1 -1
  118. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__8a9ab1a3._.js +3 -0
  119. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__b0969111._.js +3 -0
  120. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__bdc3963a._.js +1 -1
  121. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__f5c6d6b8._.js +1 -1
  122. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui__next-internal_server_app_api_context_route_actions_dead6daa.js +3 -0
  123. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui__next-internal_server_app_api_dependencies_route_actions_cf6b14c3.js +3 -0
  124. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__12b4eb41._.js +3 -0
  125. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__3c77d95b._.js +3 -0
  126. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__44b603f9._.js +3 -0
  127. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__69a0d63a._.js +3 -0
  128. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__daee3355._.js → [root-of-the-server]__8608a6fa._.js} +2 -2
  129. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__fd80e4dd._.js → [root-of-the-server]__a965a67b._.js} +2 -2
  130. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__daedd80e._.js +3 -0
  131. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__dc176c61._.js +3 -0
  132. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__5382b397._.js → [root-of-the-server]__ead1539c._.js} +2 -2
  133. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_000dd317._.js +1 -1
  134. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_03aa8d19._.js +7 -0
  135. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_28fe1532._.js +5 -0
  136. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_8cec504f._.js +3 -0
  137. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_959ad3d8._.js +4 -0
  138. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{_22274047._.js → _adb9d7cb._.js} +2 -2
  139. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_da18b655._.js +3 -0
  140. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_ea899b87._.js +3 -0
  141. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_f38e75b7._.js +4 -0
  142. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_fe120f8a._.js +3 -0
  143. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_015f83ca._.js +3 -0
  144. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_1120b57c._.js +3 -0
  145. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_151891de._.js +3 -0
  146. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_1c916fe3._.js +3 -0
  147. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_80605a06._.js +3 -0
  148. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_bb80de48._.js +3 -0
  149. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_e8075f9b._.js +3 -0
  150. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_f919ef4a._.js +3 -0
  151. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui__next-internal_server_app_context_page_actions_1a062d48.js +3 -0
  152. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui__next-internal_server_app_dependencies_page_actions_57387d47.js +3 -0
  153. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_context_context-client_tsx_4ba99a62._.js +12 -0
  154. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_dependencies_dependencies-client_tsx_0e82443a._.js +4 -0
  155. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_specs_specs-client_tsx_0bb8f8f8._.js +1 -1
  156. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_components_spec-detail-wrapper_tsx_fd35401c._.js +3 -0
  157. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_components_specs-nav-sidebar_tsx_8237ed13._.js +1 -1
  158. package/.next/standalone/packages/ui/.next/server/middleware-build-manifest.js +2 -2
  159. package/.next/standalone/packages/ui/.next/server/pages/404.html +2 -2
  160. package/.next/standalone/packages/ui/.next/server/pages/500.html +2 -2
  161. package/.next/standalone/packages/ui/.next/server/server-reference-manifest.js +1 -1
  162. package/.next/standalone/packages/ui/.next/server/server-reference-manifest.json +1 -1
  163. package/.next/standalone/packages/ui/.next/static/chunks/094cf9f4e3553261.js +1 -0
  164. package/.next/standalone/packages/ui/.next/static/chunks/1c015eb9eaaf9f9c.js +1 -0
  165. package/.next/standalone/packages/ui/.next/static/chunks/1d36660b2877d213.js +3 -0
  166. package/.next/standalone/packages/ui/.next/static/chunks/46275d9d67603bf5.js +1 -0
  167. package/.next/standalone/packages/ui/.next/static/chunks/4d29ca0fa6843070.js +2 -0
  168. package/.next/standalone/packages/ui/.next/static/chunks/59854b15bf046467.js +1 -0
  169. package/.next/standalone/packages/ui/.next/static/chunks/{cca4441cde342ae3.js → 5fd8101e32b076b1.js} +1 -1
  170. package/.next/standalone/packages/ui/.next/static/chunks/6d938a49daa10208.js +2 -0
  171. package/.next/standalone/packages/ui/.next/static/chunks/979625373d5474b6.js +1 -0
  172. package/.next/standalone/packages/ui/.next/static/chunks/a33f10af6abef4df.js +10 -0
  173. package/.next/{static/chunks/794f3931f1ca12d2.js → standalone/packages/ui/.next/static/chunks/a3d7e1be47de010b.js} +1 -1
  174. package/.next/standalone/packages/ui/.next/static/chunks/a5e25b9fa6b88eee.js +1 -0
  175. package/.next/standalone/packages/ui/.next/static/chunks/b53250480fde6816.js +1 -0
  176. package/.next/standalone/packages/ui/.next/static/chunks/b7f19087afe1d2c9.css +1 -0
  177. package/.next/standalone/packages/ui/.next/static/chunks/c658e22a605e0ed1.js +1 -0
  178. package/.next/standalone/packages/ui/.next/static/chunks/c92660d8d0c4763d.js +1 -0
  179. package/.next/standalone/packages/ui/.next/static/chunks/ddd87cd0d26bc2f5.js +1 -0
  180. package/.next/standalone/packages/ui/.next/static/chunks/eeec245955b3b600.js +5 -0
  181. package/.next/standalone/packages/ui/.next/static/chunks/ff11efb770d5a0bc.js +1 -0
  182. package/.next/{static/chunks/turbopack-5fa55215af0efb15.js → standalone/packages/ui/.next/static/chunks/turbopack-261c5dcdd873f310.js} +1 -1
  183. package/.next/standalone/packages/ui/package.json +5 -1
  184. package/.next/standalone/packages/ui/src/app/api/context/route.ts +22 -0
  185. package/.next/standalone/packages/ui/src/app/api/dependencies/route.ts +81 -0
  186. package/.next/standalone/packages/ui/src/app/context/context-client.tsx +393 -0
  187. package/.next/standalone/packages/ui/src/app/context/page.tsx +17 -0
  188. package/.next/standalone/packages/ui/src/app/dependencies/constants.ts +24 -0
  189. package/.next/standalone/packages/ui/src/app/dependencies/dependencies-client.tsx +625 -0
  190. package/.next/standalone/packages/ui/src/app/dependencies/index.ts +19 -0
  191. package/.next/standalone/packages/ui/src/app/dependencies/page.tsx +38 -0
  192. package/.next/standalone/packages/ui/src/app/dependencies/spec-node.tsx +80 -0
  193. package/.next/standalone/packages/ui/src/app/dependencies/spec-sidebar.tsx +198 -0
  194. package/.next/standalone/packages/ui/src/app/dependencies/types.ts +37 -0
  195. package/.next/standalone/packages/ui/src/app/dependencies/utils.ts +194 -0
  196. package/.next/standalone/packages/ui/src/app/globals.css +16 -16
  197. package/.next/standalone/packages/ui/src/app/layout.tsx +4 -7
  198. package/.next/standalone/packages/ui/src/components/context-file-detail.tsx +308 -0
  199. package/.next/standalone/packages/ui/src/components/context-file-viewer.tsx +385 -0
  200. package/.next/standalone/packages/ui/src/components/main-sidebar.tsx +19 -1
  201. package/.next/standalone/packages/ui/src/components/spec-detail-client.tsx +181 -134
  202. package/.next/standalone/packages/ui/src/components/spec-detail-wrapper.tsx +20 -0
  203. package/.next/standalone/packages/ui/src/components/specs-nav-sidebar.tsx +3 -2
  204. package/.next/standalone/packages/ui/src/components/ui/accordion.tsx +58 -0
  205. package/.next/standalone/packages/ui/src/lib/db/service-queries.ts +172 -3
  206. package/.next/standalone/packages/ui/src/lib/specs/types.ts +44 -0
  207. package/.next/standalone/packages/ui/tsconfig.tsbuildinfo +1 -1
  208. package/.next/static/chunks/094cf9f4e3553261.js +1 -0
  209. package/.next/static/chunks/1c015eb9eaaf9f9c.js +1 -0
  210. package/.next/static/chunks/1d36660b2877d213.js +3 -0
  211. package/.next/static/chunks/46275d9d67603bf5.js +1 -0
  212. package/.next/static/chunks/4d29ca0fa6843070.js +2 -0
  213. package/.next/static/chunks/59854b15bf046467.js +1 -0
  214. package/.next/static/chunks/{cca4441cde342ae3.js → 5fd8101e32b076b1.js} +1 -1
  215. package/.next/static/chunks/6d938a49daa10208.js +2 -0
  216. package/.next/static/chunks/979625373d5474b6.js +1 -0
  217. package/.next/static/chunks/a33f10af6abef4df.js +10 -0
  218. package/.next/{standalone/packages/ui/.next/static/chunks/794f3931f1ca12d2.js → static/chunks/a3d7e1be47de010b.js} +1 -1
  219. package/.next/static/chunks/a5e25b9fa6b88eee.js +1 -0
  220. package/.next/static/chunks/b53250480fde6816.js +1 -0
  221. package/.next/static/chunks/b7f19087afe1d2c9.css +1 -0
  222. package/.next/static/chunks/c658e22a605e0ed1.js +1 -0
  223. package/.next/static/chunks/c92660d8d0c4763d.js +1 -0
  224. package/.next/static/chunks/ddd87cd0d26bc2f5.js +1 -0
  225. package/.next/static/chunks/eeec245955b3b600.js +5 -0
  226. package/.next/static/chunks/ff11efb770d5a0bc.js +1 -0
  227. package/.next/{standalone/packages/ui/.next/static/chunks/turbopack-5fa55215af0efb15.js → static/chunks/turbopack-261c5dcdd873f310.js} +1 -1
  228. package/package.json +6 -2
  229. package/.next/standalone/node_modules/.pnpm/source-map@0.8.0-beta.0/node_modules/source-map/package.json +0 -95
  230. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__1d0c2012._.js +0 -3
  231. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__73f60f12._.js +0 -7
  232. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__a7ae8552._.js +0 -7
  233. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_0f9ffe32._.js +0 -3
  234. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_14118969._.js +0 -3
  235. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_4129cc0f._.js +0 -3
  236. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_497c8b73._.js +0 -3
  237. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_ac867463._.js +0 -3
  238. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_c2f54661._.js +0 -5
  239. package/.next/standalone/packages/ui/.next/static/chunks/16ff9833ae1bb3ae.js +0 -1
  240. package/.next/standalone/packages/ui/.next/static/chunks/2204c0f16b23ec4c.js +0 -3
  241. package/.next/standalone/packages/ui/.next/static/chunks/294dea6dbec43ca6.js +0 -1
  242. package/.next/standalone/packages/ui/.next/static/chunks/7590e65bcaa41e8b.js +0 -1
  243. package/.next/standalone/packages/ui/.next/static/chunks/b6976cf6c48996e5.js +0 -1
  244. package/.next/standalone/packages/ui/.next/static/chunks/b8353eb8c6fb895e.js +0 -1
  245. package/.next/standalone/packages/ui/.next/static/chunks/b845813463167db0.js +0 -5
  246. package/.next/standalone/packages/ui/.next/static/chunks/bd9893e28f8f6a9a.css +0 -1
  247. package/.next/standalone/packages/ui/.next/static/chunks/d784d84d5b880e48.js +0 -1
  248. package/.next/static/chunks/16ff9833ae1bb3ae.js +0 -1
  249. package/.next/static/chunks/2204c0f16b23ec4c.js +0 -3
  250. package/.next/static/chunks/294dea6dbec43ca6.js +0 -1
  251. package/.next/static/chunks/7590e65bcaa41e8b.js +0 -1
  252. package/.next/static/chunks/b6976cf6c48996e5.js +0 -1
  253. package/.next/static/chunks/b8353eb8c6fb895e.js +0 -1
  254. package/.next/static/chunks/b845813463167db0.js +0 -5
  255. package/.next/static/chunks/bd9893e28f8f6a9a.css +0 -1
  256. package/.next/static/chunks/d784d84d5b880e48.js +0 -1
  257. /package/.next/standalone/packages/ui/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_buildManifest.js +0 -0
  258. /package/.next/standalone/packages/ui/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_clientMiddlewareManifest.json +0 -0
  259. /package/.next/standalone/packages/ui/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_ssgManifest.js +0 -0
  260. /package/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_buildManifest.js +0 -0
  261. /package/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_clientMiddlewareManifest.json +0 -0
  262. /package/.next/static/{6nq7WNafPv5Bf_7mWgRQ- → 8PwFWS-09QjFSbDbfp15t}/_ssgManifest.js +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  import Link from 'next/link';
4
4
  import { usePathname } from 'next/navigation';
5
- import { Home, FileText, BarChart3, ChevronLeft, ChevronRight, X } from 'lucide-react';
5
+ import { Home, FileText, BarChart3, BookOpen, Network, ChevronLeft, ChevronRight, X } from 'lucide-react';
6
6
  import { ProjectSwitcher } from '@/components/project-switcher';
7
7
  import { Button } from '@/components/ui/button';
8
8
  import { cn } from '@/lib/utils';
@@ -143,6 +143,15 @@ export function MainSidebar() {
143
143
  >
144
144
  Specs
145
145
  </SidebarLink>
146
+ <SidebarLink
147
+ href="/dependencies"
148
+ icon={Network}
149
+ currentPath={pathname}
150
+ description={(!isCollapsed || mobileOpen) ? "Dependency Graph" : undefined}
151
+ isCollapsed={isCollapsed && !mobileOpen}
152
+ >
153
+ Dependencies
154
+ </SidebarLink>
146
155
  <SidebarLink
147
156
  href="/stats"
148
157
  icon={BarChart3}
@@ -152,6 +161,15 @@ export function MainSidebar() {
152
161
  >
153
162
  Stats
154
163
  </SidebarLink>
164
+ <SidebarLink
165
+ href="/context"
166
+ icon={BookOpen}
167
+ currentPath={pathname}
168
+ description={(!isCollapsed || mobileOpen) ? "Project Context" : undefined}
169
+ isCollapsed={isCollapsed && !mobileOpen}
170
+ >
171
+ Context
172
+ </SidebarLink>
155
173
  </nav>}
156
174
 
157
175
  {/* Collapse Toggle (desktop only) */}
@@ -45,6 +45,7 @@ import {
45
45
  TrendingUp,
46
46
  Clock,
47
47
  Maximize2,
48
+ Minimize2,
48
49
  List as ListIcon
49
50
  } from 'lucide-react';
50
51
  import type { Plugin } from 'unified';
@@ -76,6 +77,8 @@ const SUB_SPEC_ICONS: Record<string, React.ComponentType<{ className?: string }>
76
77
  interface SpecDetailClientProps {
77
78
  initialSpec: SpecWithMetadata;
78
79
  initialSubSpec?: string;
80
+ isFocusMode?: boolean;
81
+ onToggleFocusMode?: () => void;
79
82
  }
80
83
 
81
84
  // SWR fetcher with error handling
@@ -86,7 +89,7 @@ const fetcher = (url: string) => fetch(url).then((res) => {
86
89
  return res.json();
87
90
  });
88
91
 
89
- export function SpecDetailClient({ initialSpec, initialSubSpec }: SpecDetailClientProps) {
92
+ export function SpecDetailClient({ initialSpec, initialSubSpec, isFocusMode = false, onToggleFocusMode }: SpecDetailClientProps) {
90
93
  const router = useRouter();
91
94
  const searchParams = useSearchParams();
92
95
  const currentSubSpec = searchParams.get('subspec') || initialSubSpec;
@@ -216,144 +219,188 @@ export function SpecDetailClient({ initialSpec, initialSubSpec }: SpecDetailClie
216
219
  <>
217
220
  {/* Compact Header - sticky on desktop, static on mobile */}
218
221
  <header ref={headerRef} className="lg:sticky lg:top-14 lg:z-20 border-b bg-card">
219
- <div className="px-3 sm:px-6 py-3 sm:py-4">
220
- {/* Line 1: Spec number + H1 Title */}
221
- <div className="flex items-start justify-between gap-2 mb-2 sm:mb-3">
222
- <h1 className="text-xl sm:text-2xl font-bold tracking-tight">
223
- {spec.specNumber && (
224
- <span className="text-muted-foreground">#{spec.specNumber.toString().padStart(3, '0')} </span>
225
- )}
226
- {displayTitle}
227
- </h1>
228
-
229
- {/* Mobile Specs List Toggle */}
230
- <Button
231
- variant="ghost"
232
- size="icon"
233
- className="lg:hidden h-8 w-8 -mr-2 shrink-0 text-muted-foreground"
234
- onClick={() => {
235
- if (typeof window !== 'undefined' && window.toggleSpecsSidebar) {
236
- window.toggleSpecsSidebar();
237
- }
238
- }}
239
- >
240
- <ListIcon className="h-5 w-5" />
241
- <span className="sr-only">Toggle specs list</span>
242
- </Button>
243
- </div>
244
-
245
- {/* Line 2: Status, Priority, Tags, Actions */}
246
- <div className="flex flex-wrap items-center gap-2">
247
- <StatusBadge status={spec.status || 'planned'} />
248
- <PriorityBadge priority={spec.priority || 'medium'} />
249
-
250
- {tags.length > 0 && (
251
- <>
252
- <div className="h-4 w-px bg-border mx-1 hidden sm:block" />
253
- <div className="flex flex-wrap gap-1">
254
- {tags.slice(0, 5).map((tag: string) => (
255
- <Badge key={tag} variant="secondary" className="text-xs">
256
- {tag}
257
- </Badge>
258
- ))}
259
- {tags.length > 5 && (
260
- <Badge variant="secondary" className="text-xs">
261
- +{tags.length - 5} more
262
- </Badge>
222
+ <div className={cn("px-3 sm:px-6", isFocusMode ? "py-1.5" : "py-2 sm:py-3")}>
223
+ {/* Focus mode: Single compact row */}
224
+ {isFocusMode ? (
225
+ <div className="flex items-center justify-between gap-3">
226
+ <div className="flex items-center gap-3 min-w-0">
227
+ <h1 className="text-base font-semibold tracking-tight truncate">
228
+ {spec.specNumber && (
229
+ <span className="text-muted-foreground">#{spec.specNumber.toString().padStart(3, '0')} </span>
263
230
  )}
264
- </div>
265
- </>
266
- )}
267
- </div>
268
-
269
- {/* Line 3: Small metadata row */}
270
- <div className="flex flex-wrap gap-2 sm:gap-4 text-xs text-muted-foreground mt-2 sm:mt-3">
271
- <span className="hidden sm:inline">Created: {formatDate(spec.createdAt)}</span>
272
- <span className="hidden sm:inline">•</span>
273
- <span>
274
- Updated: {formatDate(spec.updatedAt)}
275
- {spec.updatedAt && (
276
- <span className="ml-1 text-[11px] text-muted-foreground/80">({updatedRelative})</span>
277
- )}
278
- </span>
279
- <span className="hidden sm:inline">•</span>
280
- <span className="hidden md:inline">Name: {spec.specName}</span>
281
- {spec.assignee && (
282
- <>
283
- <span className="hidden sm:inline">•</span>
284
- <span className="hidden sm:inline">Assignee: {spec.assignee}</span>
285
- </>
286
- )}
287
- </div>
288
-
289
- <div className="flex flex-wrap items-center gap-2 mt-3">
290
- <Dialog open={timelineDialogOpen} onOpenChange={setTimelineDialogOpen}>
231
+ {displayTitle}
232
+ </h1>
233
+ <StatusBadge status={spec.status || 'planned'} />
234
+ <PriorityBadge priority={spec.priority || 'medium'} />
235
+ </div>
291
236
  <Button
292
237
  type="button"
293
- variant="outline"
238
+ variant="ghost"
294
239
  size="sm"
295
- aria-haspopup="dialog"
296
- aria-expanded={timelineDialogOpen}
297
- onClick={() => setTimelineDialogOpen(true)}
298
- className="h-8 rounded-full border px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground"
240
+ onClick={onToggleFocusMode}
241
+ className="h-7 px-2 text-xs text-muted-foreground hover:text-foreground shrink-0"
242
+ title="Exit focus mode"
299
243
  >
300
- <Clock className="mr-1.5 h-3.5 w-3.5" />
301
- View Timeline
302
- <Maximize2 className="ml-1.5 h-3.5 w-3.5" />
244
+ <Minimize2 className="h-4 w-4" />
303
245
  </Button>
304
- <DialogContent className="w-[min(900px,90vw)] max-w-3xl max-h-[90vh] overflow-y-auto">
305
- <DialogHeader>
306
- <DialogTitle>Spec Timeline</DialogTitle>
307
- <DialogDescription>Created, updated, and completion milestones.</DialogDescription>
308
- </DialogHeader>
309
- <div className="rounded-xl border border-border bg-muted/30 p-4">
310
- <SpecTimeline
311
- createdAt={spec.createdAt}
312
- updatedAt={spec.updatedAt}
313
- completedAt={spec.completedAt}
314
- status={spec.status || 'planned'}
315
- />
316
- </div>
317
- </DialogContent>
318
- </Dialog>
319
-
320
- <Dialog open={dependenciesDialogOpen} onOpenChange={setDependenciesDialogOpen}>
321
- <Button
322
- type="button"
323
- variant="outline"
324
- size="sm"
325
- aria-haspopup="dialog"
326
- aria-expanded={dependenciesDialogOpen}
327
- onClick={() => setDependenciesDialogOpen(true)}
328
- disabled={!hasRelationships}
329
- className={cn(
330
- 'h-8 rounded-full border px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground',
331
- !hasRelationships && 'cursor-not-allowed opacity-50'
246
+ </div>
247
+ ) : (
248
+ /* Normal mode: Full multi-line header */
249
+ <>
250
+ {/* Line 1: Spec number + H1 Title */}
251
+ <div className="flex items-start justify-between gap-2 mb-1.5 sm:mb-2">
252
+ <h1 className="text-lg sm:text-xl font-bold tracking-tight">
253
+ {spec.specNumber && (
254
+ <span className="text-muted-foreground">#{spec.specNumber.toString().padStart(3, '0')} </span>
255
+ )}
256
+ {displayTitle}
257
+ </h1>
258
+
259
+ {/* Mobile Specs List Toggle */}
260
+ <Button
261
+ variant="ghost"
262
+ size="icon"
263
+ className="lg:hidden h-8 w-8 -mr-2 shrink-0 text-muted-foreground"
264
+ onClick={() => {
265
+ if (typeof window !== 'undefined' && window.toggleSpecsSidebar) {
266
+ window.toggleSpecsSidebar();
267
+ }
268
+ }}
269
+ >
270
+ <ListIcon className="h-5 w-5" />
271
+ <span className="sr-only">Toggle specs list</span>
272
+ </Button>
273
+ </div>
274
+
275
+ {/* Line 2: Status, Priority, Tags, Actions */}
276
+ <div className="flex flex-wrap items-center gap-2">
277
+ <StatusBadge status={spec.status || 'planned'} />
278
+ <PriorityBadge priority={spec.priority || 'medium'} />
279
+
280
+ {tags.length > 0 && (
281
+ <>
282
+ <div className="h-4 w-px bg-border mx-1 hidden sm:block" />
283
+ <div className="flex flex-wrap gap-1">
284
+ {tags.slice(0, 5).map((tag: string) => (
285
+ <Badge key={tag} variant="secondary" className="text-xs">
286
+ {tag}
287
+ </Badge>
288
+ ))}
289
+ {tags.length > 5 && (
290
+ <Badge variant="secondary" className="text-xs">
291
+ +{tags.length - 5} more
292
+ </Badge>
293
+ )}
294
+ </div>
295
+ </>
332
296
  )}
333
- >
334
- <GitBranch className="mr-1.5 h-3.5 w-3.5" />
335
- View Dependencies
336
- <Maximize2 className="ml-1.5 h-3.5 w-3.5" />
337
- </Button>
338
- <DialogContent className="flex h-[85vh] w-[min(1200px,95vw)] max-w-6xl flex-col gap-4 overflow-hidden">
339
- <DialogHeader>
340
- <DialogTitle>Dependency Graph</DialogTitle>
341
- <DialogDescription>
342
- Precedence requirements and connected specs rendered with automatic layout.
343
- </DialogDescription>
344
- </DialogHeader>
345
- <div className="min-h-0 flex-1">
346
- {completeRelationships && (
347
- <SpecDependencyGraph
348
- relationships={completeRelationships}
349
- specNumber={spec.specNumber}
350
- specTitle={displayTitle}
351
- />
297
+ </div>
298
+
299
+ {/* Line 3: Small metadata row */}
300
+ <div className="flex flex-wrap gap-2 sm:gap-4 text-xs text-muted-foreground mt-1.5 sm:mt-2">
301
+ <span className="hidden sm:inline">Created: {formatDate(spec.createdAt)}</span>
302
+ <span className="hidden sm:inline">•</span>
303
+ <span>
304
+ Updated: {formatDate(spec.updatedAt)}
305
+ {spec.updatedAt && (
306
+ <span className="ml-1 text-[11px] text-muted-foreground/80">({updatedRelative})</span>
352
307
  )}
353
- </div>
354
- </DialogContent>
355
- </Dialog>
356
- </div>
308
+ </span>
309
+ <span className="hidden sm:inline">•</span>
310
+ <span className="hidden md:inline">Name: {spec.specName}</span>
311
+ {spec.assignee && (
312
+ <>
313
+ <span className="hidden sm:inline">•</span>
314
+ <span className="hidden sm:inline">Assignee: {spec.assignee}</span>
315
+ </>
316
+ )}
317
+ </div>
318
+
319
+ <div className="flex flex-wrap items-center gap-2 mt-2">
320
+ <Dialog open={timelineDialogOpen} onOpenChange={setTimelineDialogOpen}>
321
+ <Button
322
+ type="button"
323
+ variant="outline"
324
+ size="sm"
325
+ aria-haspopup="dialog"
326
+ aria-expanded={timelineDialogOpen}
327
+ onClick={() => setTimelineDialogOpen(true)}
328
+ className="h-8 rounded-full border px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground"
329
+ >
330
+ <Clock className="mr-1.5 h-3.5 w-3.5" />
331
+ View Timeline
332
+ <Maximize2 className="ml-1.5 h-3.5 w-3.5" />
333
+ </Button>
334
+ <DialogContent className="w-[min(900px,90vw)] max-w-3xl max-h-[90vh] overflow-y-auto">
335
+ <DialogHeader>
336
+ <DialogTitle>Spec Timeline</DialogTitle>
337
+ <DialogDescription>Created, updated, and completion milestones.</DialogDescription>
338
+ </DialogHeader>
339
+ <div className="rounded-xl border border-border bg-muted/30 p-4">
340
+ <SpecTimeline
341
+ createdAt={spec.createdAt}
342
+ updatedAt={spec.updatedAt}
343
+ completedAt={spec.completedAt}
344
+ status={spec.status || 'planned'}
345
+ />
346
+ </div>
347
+ </DialogContent>
348
+ </Dialog>
349
+
350
+ <Dialog open={dependenciesDialogOpen} onOpenChange={setDependenciesDialogOpen}>
351
+ <Button
352
+ type="button"
353
+ variant="outline"
354
+ size="sm"
355
+ aria-haspopup="dialog"
356
+ aria-expanded={dependenciesDialogOpen}
357
+ onClick={() => setDependenciesDialogOpen(true)}
358
+ disabled={!hasRelationships}
359
+ className={cn(
360
+ 'h-8 rounded-full border px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground',
361
+ !hasRelationships && 'cursor-not-allowed opacity-50'
362
+ )}
363
+ >
364
+ <GitBranch className="mr-1.5 h-3.5 w-3.5" />
365
+ View Dependencies
366
+ <Maximize2 className="ml-1.5 h-3.5 w-3.5" />
367
+ </Button>
368
+ <DialogContent className="flex h-[85vh] w-[min(1200px,95vw)] max-w-6xl flex-col gap-4 overflow-hidden">
369
+ <DialogHeader>
370
+ <DialogTitle>Dependency Graph</DialogTitle>
371
+ <DialogDescription>
372
+ Precedence requirements and connected specs rendered with automatic layout.
373
+ </DialogDescription>
374
+ </DialogHeader>
375
+ <div className="min-h-0 flex-1">
376
+ {completeRelationships && (
377
+ <SpecDependencyGraph
378
+ relationships={completeRelationships}
379
+ specNumber={spec.specNumber}
380
+ specTitle={displayTitle}
381
+ />
382
+ )}
383
+ </div>
384
+ </DialogContent>
385
+ </Dialog>
386
+
387
+ {/* Focus Mode Toggle - Desktop only */}
388
+ {onToggleFocusMode && (
389
+ <Button
390
+ type="button"
391
+ variant="outline"
392
+ size="sm"
393
+ onClick={onToggleFocusMode}
394
+ className="hidden lg:inline-flex h-8 rounded-full border px-3 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground"
395
+ title="Enter focus mode"
396
+ >
397
+ <Maximize2 className="mr-1.5 h-3.5 w-3.5" />
398
+ Focus
399
+ </Button>
400
+ )}
401
+ </div>
402
+ </>
403
+ )}
357
404
  </div>
358
405
 
359
406
  {/* Horizontal Tabs for Sub-specs (only if sub-specs exist) */}
@@ -401,8 +448,8 @@ export function SpecDetailClient({ initialSpec, initialSubSpec }: SpecDetailClie
401
448
 
402
449
  {/* Main content with Sidebar */}
403
450
  <div className="flex flex-col xl:flex-row xl:items-start">
404
- <main className="flex-1 px-3 sm:px-6 py-4 sm:py-8 min-w-0">
405
- <div className="space-y-6">
451
+ <main className="flex-1 px-3 sm:px-6 py-3 sm:py-6 min-w-0">
452
+ <div className="space-y-4">
406
453
  {isLoading && <div className="text-sm text-muted-foreground">Loading...</div>}
407
454
  {error && <div className="text-sm text-destructive">Error loading spec</div>}
408
455
 
@@ -442,7 +489,7 @@ export function SpecDetailClient({ initialSpec, initialSubSpec }: SpecDetailClie
442
489
  </main>
443
490
 
444
491
  {/* Right Sidebar for TOC (Desktop only) */}
445
- <aside className="hidden xl:block w-72 shrink-0 px-6 py-8 sticky top-40 h-[calc(100vh-10rem)] overflow-y-auto scrollbar-auto-hide">
492
+ <aside className="hidden xl:block w-72 shrink-0 px-6 py-6 sticky top-32 h-[calc(100vh-8rem)] overflow-y-auto scrollbar-auto-hide">
446
493
  <TableOfContentsSidebar content={displayContent} />
447
494
  </aside>
448
495
  </div>
@@ -9,6 +9,7 @@ import * as React from 'react';
9
9
  import { SpecsNavSidebar } from '@/components/specs-nav-sidebar';
10
10
  import { SpecDetailClient } from '@/components/spec-detail-client';
11
11
  import { primeSpecsSidebar, setActiveSidebarSpec } from '@/lib/stores/specs-sidebar-store';
12
+ import { cn } from '@/lib/utils';
12
13
  import type { SpecWithMetadata, SidebarSpec } from '@/types/specs';
13
14
  import type { ParsedSpec } from '@/lib/db/service-queries';
14
15
 
@@ -19,6 +20,22 @@ interface SpecDetailWrapperProps {
19
20
  }
20
21
 
21
22
  export function SpecDetailWrapper({ spec, allSpecs, currentSubSpec }: SpecDetailWrapperProps) {
23
+ const [isFocusMode, setIsFocusMode] = React.useState(() => {
24
+ if (typeof window !== 'undefined') {
25
+ return localStorage.getItem('spec-detail-focus-mode') === 'true';
26
+ }
27
+ return false;
28
+ });
29
+
30
+ // Persist focus mode preference
31
+ const handleToggleFocusMode = React.useCallback(() => {
32
+ setIsFocusMode(prev => {
33
+ const next = !prev;
34
+ localStorage.setItem('spec-detail-focus-mode', String(next));
35
+ return next;
36
+ });
37
+ }, []);
38
+
22
39
  const sidebarSpecs = React.useMemo<SidebarSpec[]>(() => (
23
40
  allSpecs.map((item) => ({
24
41
  id: item.id,
@@ -57,12 +74,15 @@ export function SpecDetailWrapper({ spec, allSpecs, currentSubSpec }: SpecDetail
57
74
  currentSpecId={spec.id}
58
75
  currentSubSpec={currentSubSpec}
59
76
  onSpecHover={handleSpecPrefetch}
77
+ className={cn(isFocusMode && 'hidden')}
60
78
  />
61
79
 
62
80
  <div className="flex-1 min-w-0">
63
81
  <SpecDetailClient
64
82
  initialSpec={spec}
65
83
  initialSubSpec={currentSubSpec}
84
+ isFocusMode={isFocusMode}
85
+ onToggleFocusMode={handleToggleFocusMode}
66
86
  />
67
87
  </div>
68
88
  </div>
@@ -48,9 +48,10 @@ interface SpecsNavSidebarProps {
48
48
  currentSpecId?: string;
49
49
  currentSubSpec?: string;
50
50
  onSpecHover?: (specId: string) => void;
51
+ className?: string;
51
52
  }
52
53
 
53
- export function SpecsNavSidebar({ initialSpecs = [], currentSpecId, currentSubSpec, onSpecHover }: SpecsNavSidebarProps) {
54
+ export function SpecsNavSidebar({ initialSpecs = [], currentSpecId, currentSubSpec, onSpecHover, className }: SpecsNavSidebarProps) {
54
55
  const [searchQuery, setSearchQuery] = React.useState('');
55
56
  const [statusFilter, setStatusFilter] = React.useState<string>('all');
56
57
  const [priorityFilter, setPriorityFilter] = React.useState<string>('all');
@@ -393,7 +394,7 @@ export function SpecsNavSidebar({ initialSpecs = [], currentSpecId, currentSubSp
393
394
  />
394
395
  )}
395
396
 
396
- <div className="relative flex-shrink-0">
397
+ <div className={cn("relative flex-shrink-0", className)}>
397
398
  <aside className={cn(
398
399
  "border-r border-border bg-background flex flex-col overflow-hidden transition-all duration-300",
399
400
  // Desktop behavior
@@ -0,0 +1,58 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as AccordionPrimitive from "@radix-ui/react-accordion"
5
+ import { ChevronDown } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ const Accordion = AccordionPrimitive.Root
10
+
11
+ const AccordionItem = React.forwardRef<
12
+ React.ElementRef<typeof AccordionPrimitive.Item>,
13
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
14
+ >(({ className, ...props }, ref) => (
15
+ <AccordionPrimitive.Item
16
+ ref={ref}
17
+ className={cn("border-b", className)}
18
+ {...props}
19
+ />
20
+ ))
21
+ AccordionItem.displayName = "AccordionItem"
22
+
23
+ const AccordionTrigger = React.forwardRef<
24
+ React.ElementRef<typeof AccordionPrimitive.Trigger>,
25
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
26
+ >(({ className, children, ...props }, ref) => (
27
+ <AccordionPrimitive.Header className="flex">
28
+ <AccordionPrimitive.Trigger
29
+ ref={ref}
30
+ className={cn(
31
+ "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
32
+ className
33
+ )}
34
+ {...props}
35
+ >
36
+ {children}
37
+ <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
38
+ </AccordionPrimitive.Trigger>
39
+ </AccordionPrimitive.Header>
40
+ ))
41
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
42
+
43
+ const AccordionContent = React.forwardRef<
44
+ React.ElementRef<typeof AccordionPrimitive.Content>,
45
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
46
+ >(({ className, children, ...props }, ref) => (
47
+ <AccordionPrimitive.Content
48
+ ref={ref}
49
+ className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
50
+ {...props}
51
+ >
52
+ <div className={cn("pb-4 pt-0", className)}>{children}</div>
53
+ </AccordionPrimitive.Content>
54
+ ))
55
+
56
+ AccordionContent.displayName = AccordionPrimitive.Content.displayName
57
+
58
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }