@digithings-ai/ui 0.0.0-stage → 0.1.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 (424) hide show
  1. package/README.md +48 -2
  2. package/package.json +143 -4
  3. package/src/components/NavShell.tsx +776 -0
  4. package/src/components/SocialRow.tsx +87 -0
  5. package/src/components/Spinner.tsx +27 -0
  6. package/src/components/StackLogo.tsx +40 -0
  7. package/src/components/Terminal.tsx +110 -0
  8. package/src/components/TerminalManifest.tsx +212 -0
  9. package/src/components/ThemeProvider.tsx +271 -0
  10. package/src/components/account/AuthCard.tsx +309 -0
  11. package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
  12. package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
  13. package/src/components/brand/BrandWordmark.tsx +32 -0
  14. package/src/components/changelog/ReleaseRail.tsx +81 -0
  15. package/src/components/changelog/index.ts +1 -0
  16. package/src/components/chat/ChatCodeBlock.tsx +67 -0
  17. package/src/components/chat/ChatMarkdown.tsx +66 -0
  18. package/src/components/chat/ChatMarkdownSource.tsx +203 -0
  19. package/src/components/chat/ChatMermaidBlock.tsx +202 -0
  20. package/src/components/chat/ChatMessage.tsx +77 -0
  21. package/src/components/chat/ChatPlayback.tsx +422 -0
  22. package/src/components/chat/ChatStreamCursor.tsx +25 -0
  23. package/src/components/chat/ChatThinking.tsx +113 -0
  24. package/src/components/chat/ChatToolCall.tsx +190 -0
  25. package/src/components/chat/ChatTranscript.tsx +60 -0
  26. package/src/components/chat/ChatWidgetFrame.tsx +107 -0
  27. package/src/components/chat/DigichatBootLoader.tsx +683 -0
  28. package/src/components/chat/DigichatLauncher.tsx +361 -0
  29. package/src/components/chat/DigichatThread.tsx +118 -0
  30. package/src/components/chat/DigichatThreadList.tsx +54 -0
  31. package/src/components/chat/DigichatWordmark.tsx +24 -0
  32. package/src/components/chat/DotMatrix.tsx +650 -0
  33. package/src/components/chat/boot-lab.tsx +766 -0
  34. package/src/components/chat/boot-signal.ts +144 -0
  35. package/src/components/chat/chat-surfaces.ts +52 -0
  36. package/src/components/chat/connection-status.ts +40 -0
  37. package/src/components/chat/digichat-wordmark.ts +355 -0
  38. package/src/components/chat/disclosure-chevron.tsx +49 -0
  39. package/src/components/chat/followable-href.ts +9 -0
  40. package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
  41. package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
  42. package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
  43. package/src/components/chat/gallery-thread/cn.ts +1 -0
  44. package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
  45. package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
  46. package/src/components/chat/gallery-thread/css.d.ts +6 -0
  47. package/src/components/chat/gallery-thread/file.tsx +238 -0
  48. package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
  49. package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
  50. package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
  51. package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
  52. package/src/components/chat/gallery-thread/image.tsx +519 -0
  53. package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
  54. package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
  55. package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
  56. package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
  57. package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
  58. package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
  59. package/src/components/chat/gallery-thread/source.tsx +76 -0
  60. package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
  61. package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
  62. package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
  63. package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
  64. package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
  65. package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
  66. package/src/components/chat/gallery-thread/work-status.ts +66 -0
  67. package/src/components/chat/overlay-scrollbar.tsx +86 -0
  68. package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
  69. package/src/components/chat/skins/SOURCE.md +36 -0
  70. package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
  71. package/src/components/chat/skins/base/aui-default/README.md +45 -0
  72. package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
  73. package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
  74. package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
  75. package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
  76. package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
  77. package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
  78. package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
  79. package/src/components/chat/skins/base/docs-model-options.ts +6 -0
  80. package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
  81. package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
  82. package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
  83. package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
  84. package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
  85. package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
  86. package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
  87. package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
  88. package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
  89. package/src/components/chat/skins/base/markdown-text.tsx +294 -0
  90. package/src/components/chat/skins/base/model.ts +1 -0
  91. package/src/components/chat/skins/base/thread.tsx +1050 -0
  92. package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
  93. package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
  94. package/src/components/chat/skins/base/ui/badge.tsx +51 -0
  95. package/src/components/chat/skins/base/ui/button.tsx +67 -0
  96. package/src/components/chat/skins/base/ui/command.tsx +185 -0
  97. package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
  98. package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
  99. package/src/components/chat/skins/base/ui/popover.tsx +97 -0
  100. package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
  101. package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
  102. package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
  103. package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
  104. package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
  105. package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
  106. package/src/components/chat/skins/chatgpt.tsx +448 -0
  107. package/src/components/chat/skins/claude.tsx +380 -0
  108. package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
  109. package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
  110. package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
  111. package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
  112. package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
  113. package/src/components/chat/skins/digichat.tsx +144 -0
  114. package/src/components/chat/skins/expo-react-native.tsx +29 -0
  115. package/src/components/chat/skins/gemini.tsx +322 -0
  116. package/src/components/chat/skins/grok-icon.tsx +34 -0
  117. package/src/components/chat/skins/grok.tsx +369 -0
  118. package/src/components/chat/skins/index.ts +46 -0
  119. package/src/components/chat/skins/perplexity.tsx +462 -0
  120. package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
  121. package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
  122. package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
  123. package/src/components/chat/skins/react-ink.tsx +97 -0
  124. package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
  125. package/src/components/chat/skins/thread-skin-view.tsx +156 -0
  126. package/src/components/chat/skins/thread-skins.ts +143 -0
  127. package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
  128. package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
  129. package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
  130. package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
  131. package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
  132. package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
  133. package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
  134. package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
  135. package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
  136. package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
  137. package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
  138. package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
  139. package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
  140. package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
  141. package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
  142. package/src/components/chat/stock/SOURCE.md +90 -0
  143. package/src/components/chat/stock/artifacts-panel.tsx +305 -0
  144. package/src/components/chat/stock/attachment.aui.tsx +280 -0
  145. package/src/components/chat/stock/chat-notice.tsx +143 -0
  146. package/src/components/chat/stock/chat-private-mode.tsx +64 -0
  147. package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
  148. package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
  149. package/src/components/chat/stock/file.tsx +265 -0
  150. package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
  151. package/src/components/chat/stock/image.tsx +531 -0
  152. package/src/components/chat/stock/index.ts +129 -0
  153. package/src/components/chat/stock/json-view.tsx +140 -0
  154. package/src/components/chat/stock/markdown-text.tsx +319 -0
  155. package/src/components/chat/stock/message-error.aui.tsx +96 -0
  156. package/src/components/chat/stock/message-export-menu.tsx +156 -0
  157. package/src/components/chat/stock/palette-row-preview.tsx +26 -0
  158. package/src/components/chat/stock/reasoning.aui.tsx +120 -0
  159. package/src/components/chat/stock/reasoning.tsx +335 -0
  160. package/src/components/chat/stock/skin-chrome.tsx +81 -0
  161. package/src/components/chat/stock/skin-credit.tsx +63 -0
  162. package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
  163. package/src/components/chat/stock/skin-palette-context.ts +16 -0
  164. package/src/components/chat/stock/skin-runtime.tsx +52 -0
  165. package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
  166. package/src/components/chat/stock/skin-types.ts +217 -0
  167. package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
  168. package/src/components/chat/stock/stock-send-gate.tsx +94 -0
  169. package/src/components/chat/stock/stock-shape.tsx +39 -0
  170. package/src/components/chat/stock/thread.aui.tsx +645 -0
  171. package/src/components/chat/stock/tool-display.ts +6 -0
  172. package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
  173. package/src/components/chat/stock/tool-group.aui.tsx +244 -0
  174. package/src/components/chat/stock/tool-surface.ts +120 -0
  175. package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
  176. package/src/components/chat/stock/ui/avatar.tsx +108 -0
  177. package/src/components/chat/stock/ui/button.tsx +81 -0
  178. package/src/components/chat/stock/ui/collapsible.tsx +21 -0
  179. package/src/components/chat/stock/ui/dialog.tsx +163 -0
  180. package/src/components/chat/stock/ui/skeleton.tsx +13 -0
  181. package/src/components/chat/stock/ui/textarea.tsx +20 -0
  182. package/src/components/chat/stock/ui/tooltip.tsx +68 -0
  183. package/src/components/chat/stock/use-attachment-src.ts +42 -0
  184. package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
  185. package/src/components/chat/strip-model-boilerplate.ts +42 -0
  186. package/src/components/chat/suggestion-cycle.tsx +230 -0
  187. package/src/components/chat/suggestion-scroll-row.tsx +81 -0
  188. package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
  189. package/src/components/chat/trace-grouping/chain-state.ts +141 -0
  190. package/src/components/chat/trace-grouping/index.ts +32 -0
  191. package/src/components/chat/trace-grouping/tool-row.ts +74 -0
  192. package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
  193. package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
  194. package/src/components/chat/trace-i18n/core.ts +48 -0
  195. package/src/components/chat/trace-i18n/index.tsx +23 -0
  196. package/src/components/chat/trace-i18n/locales/en.ts +24 -0
  197. package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
  198. package/src/components/chat/trace-i18n/types.ts +35 -0
  199. package/src/components/chat/trace-spacing.ts +249 -0
  200. package/src/components/chat/transcript/activity-view.ts +375 -0
  201. package/src/components/chat/transcript/chat-export.ts +133 -0
  202. package/src/components/chat/transcript/index.ts +10 -0
  203. package/src/components/chat/transcript/save-file.ts +209 -0
  204. package/src/components/chat/transcript/transcript-markdown.ts +428 -0
  205. package/src/components/chat/transcript/types.ts +81 -0
  206. package/src/components/chat/turn-outcome.ts +52 -0
  207. package/src/components/chat/use-warmup-phase.ts +18 -0
  208. package/src/components/chat/work-status-lead.tsx +49 -0
  209. package/src/components/chrome.tsx +264 -0
  210. package/src/components/command-palette/CommandPalette.tsx +404 -0
  211. package/src/components/command-palette/index.ts +6 -0
  212. package/src/components/contact/ContactMailto.tsx +112 -0
  213. package/src/components/contact/index.ts +5 -0
  214. package/src/components/conviction/ConvictionMeter.tsx +40 -0
  215. package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
  216. package/src/components/conviction/index.ts +7 -0
  217. package/src/components/data-layout/BentoGrid.tsx +52 -0
  218. package/src/components/data-layout/CardRail.tsx +150 -0
  219. package/src/components/data-layout/DotMatrixStat.tsx +65 -0
  220. package/src/components/data-layout/FeatureCell.tsx +80 -0
  221. package/src/components/data-layout/MediaFrame.tsx +125 -0
  222. package/src/components/data-layout/ModuleGrid.tsx +735 -0
  223. package/src/components/data-layout/Odometer.tsx +149 -0
  224. package/src/components/data-layout/ProductFrame.tsx +79 -0
  225. package/src/components/data-layout/TestimonialWall.tsx +139 -0
  226. package/src/components/data-layout/index.ts +19 -0
  227. package/src/components/data-layout/treemap.ts +368 -0
  228. package/src/components/deck/DeckStack.tsx +243 -0
  229. package/src/components/desk/DataTable.tsx +373 -0
  230. package/src/components/desk/KpiGrid.tsx +80 -0
  231. package/src/components/desk/Sparkline.tsx +63 -0
  232. package/src/components/desk/StateBlock.tsx +132 -0
  233. package/src/components/desk/index.ts +18 -0
  234. package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
  235. package/src/components/diagrams/ArchitectureTour.tsx +912 -0
  236. package/src/components/diagrams/TerminalSchematic.tsx +192 -0
  237. package/src/components/diagrams/architecture-svg.tsx +384 -0
  238. package/src/components/diagrams/index.ts +30 -0
  239. package/src/components/diagrams/mermaid-theme.ts +115 -0
  240. package/src/components/diagrams/tour-camera.ts +171 -0
  241. package/src/components/docs/CodeTabs.tsx +90 -0
  242. package/src/components/docs/CopyCommand.tsx +151 -0
  243. package/src/components/docs/DocsLayout.tsx +197 -0
  244. package/src/components/docs/DocsSearch.tsx +97 -0
  245. package/src/components/docs/Endpoint.tsx +135 -0
  246. package/src/components/document/DocumentFrame.tsx +43 -0
  247. package/src/components/document/GlyphList.tsx +51 -0
  248. package/src/components/document/PageTitle.tsx +44 -0
  249. package/src/components/document/Prose.tsx +38 -0
  250. package/src/components/document/Section.tsx +55 -0
  251. package/src/components/document/index.ts +13 -0
  252. package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
  253. package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
  254. package/src/components/effects-chrome/Pipeline.tsx +226 -0
  255. package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
  256. package/src/components/effects-chrome/StackingPanels.tsx +101 -0
  257. package/src/components/effects-chrome/TabStrip.tsx +232 -0
  258. package/src/components/effects-chrome/ToastStack.tsx +201 -0
  259. package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
  260. package/src/components/effects-chrome/index.ts +35 -0
  261. package/src/components/emblems.tsx +188 -0
  262. package/src/components/faviconTheme.ts +23 -0
  263. package/src/components/figure/Figure.tsx +38 -0
  264. package/src/components/figure/index.ts +2 -0
  265. package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
  266. package/src/components/finance-charts/EquityCurve.tsx +71 -0
  267. package/src/components/finance-charts/PriceChart.tsx +119 -0
  268. package/src/components/finance-charts/chart-host.tsx +236 -0
  269. package/src/components/finance-charts/chart-scale.ts +93 -0
  270. package/src/components/finance-charts/demo-data.ts +88 -0
  271. package/src/components/finance-charts/index.ts +46 -0
  272. package/src/components/finance-charts/lw-chart.tsx +292 -0
  273. package/src/components/finance-composites/MarketBar.tsx +243 -0
  274. package/src/components/finance-composites/OrderBook.tsx +133 -0
  275. package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
  276. package/src/components/finance-composites/SortableTable.tsx +144 -0
  277. package/src/components/finance-composites/StockTicker.tsx +65 -0
  278. package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
  279. package/src/components/finance-composites/index.ts +28 -0
  280. package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
  281. package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
  282. package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
  283. package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
  284. package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
  285. package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
  286. package/src/components/finance-tearsheet/charts.tsx +2624 -0
  287. package/src/components/finance-tearsheet/demo-data.ts +177 -0
  288. package/src/components/finance-tearsheet/format.ts +41 -0
  289. package/src/components/finance-tearsheet/index.ts +120 -0
  290. package/src/components/finance-tearsheet/print.ts +52 -0
  291. package/src/components/finance-tearsheet/risk-bands.ts +48 -0
  292. package/src/components/finance-tearsheet/stats.ts +35 -0
  293. package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
  294. package/src/components/finance-tearsheet/types.ts +58 -0
  295. package/src/components/footer/FooterCells.tsx +109 -0
  296. package/src/components/footer/index.ts +6 -0
  297. package/src/components/graph.tsx +158 -0
  298. package/src/components/icons.tsx +98 -0
  299. package/src/components/landing/PixelWordmark.tsx +36 -0
  300. package/src/components/logos.ts +39 -0
  301. package/src/components/marquee/Marquee.tsx +204 -0
  302. package/src/components/metrics/PerfMetrics.tsx +68 -0
  303. package/src/components/metrics/StatCounter.tsx +104 -0
  304. package/src/components/page-geometry.tsx +177 -0
  305. package/src/components/pricing/Pricing.tsx +174 -0
  306. package/src/components/pricing/PricingMatrix.tsx +219 -0
  307. package/src/components/prose/index.ts +2 -0
  308. package/src/components/prose/prose.tsx +86 -0
  309. package/src/components/repo-activity/RepoActivity.tsx +599 -0
  310. package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
  311. package/src/components/repo-activity/demo.ts +201 -0
  312. package/src/components/repo-activity/fetch.ts +211 -0
  313. package/src/components/repo-activity/heatmap.ts +123 -0
  314. package/src/components/repo-activity/index.ts +28 -0
  315. package/src/components/repo-activity/types.ts +99 -0
  316. package/src/components/stages/NumberedStages.tsx +116 -0
  317. package/src/components/symbols/marks.tsx +116 -0
  318. package/src/components/symbols/terminal-lockup.tsx +136 -0
  319. package/src/components/symbols/terminal-marks.tsx +226 -0
  320. package/src/components/terminal/ChatResponseLoader.tsx +67 -0
  321. package/src/components/terminal/ContainerBootLoader.tsx +82 -0
  322. package/src/components/terminal/TerminalStepCaret.tsx +202 -0
  323. package/src/components/themeInit.ts +24 -0
  324. package/src/components/typography/MotionReveal.tsx +108 -0
  325. package/src/components/typography/TypewriterReveal.tsx +101 -0
  326. package/src/components/typography/WordReveal.tsx +143 -0
  327. package/src/data/modules.ts +378 -0
  328. package/src/data/subsystems.ts +101 -0
  329. package/src/index.ts +587 -0
  330. package/src/lib/base-path.ts +60 -0
  331. package/src/lib/cx.ts +25 -0
  332. package/src/lib/gloomberb.ts +69 -0
  333. package/src/lib/record.ts +19 -0
  334. package/src/lib/stub-payload.ts +183 -0
  335. package/src/lib/useBodyScrollLock.ts +44 -0
  336. package/src/lib/utils.ts +6 -0
  337. package/src/motion/primitives.tsx +105 -0
  338. package/src/motion/scroll-glide.ts +62 -0
  339. package/src/motion/scrolly-core.ts +38 -0
  340. package/src/motion/scrolly.tsx +95 -0
  341. package/src/navigation/HashScrollManager.tsx +167 -0
  342. package/src/navigation/hashScroll.ts +78 -0
  343. package/src/replay/browser.ts +280 -0
  344. package/src/replay/chat-export-run.ts +121 -0
  345. package/src/replay/export-format.ts +25 -0
  346. package/src/replay/export-mount.ts +32 -0
  347. package/src/replay/filename.ts +54 -0
  348. package/src/replay/index.ts +21 -0
  349. package/src/replay/redact-dom.ts +178 -0
  350. package/src/replay/redact.ts +113 -0
  351. package/src/replay/snapshot.ts +659 -0
  352. package/src/styles/account-auth.css +339 -0
  353. package/src/styles/brand-wordmark.css +11 -0
  354. package/src/styles/card-rail.css +120 -0
  355. package/src/styles/chat-aui.css +1143 -0
  356. package/src/styles/chat-core.css +469 -0
  357. package/src/styles/chat-digichat.css +2531 -0
  358. package/src/styles/chat-math.css +70 -0
  359. package/src/styles/chat-skin-palette.css +138 -0
  360. package/src/styles/chat-stock-menu.css +37 -0
  361. package/src/styles/chat-widgets.css +190 -0
  362. package/src/styles/command-palette.css +372 -0
  363. package/src/styles/controls-core.css +2261 -0
  364. package/src/styles/controls-overlay.css +603 -0
  365. package/src/styles/data-layout.css +288 -0
  366. package/src/styles/deck.css +141 -0
  367. package/src/styles/diagrams.css +1860 -0
  368. package/src/styles/digichat-app-theme.css +250 -0
  369. package/src/styles/digichat-boot-loader.css +487 -0
  370. package/src/styles/digichat-launcher.css +377 -0
  371. package/src/styles/docs.css +165 -0
  372. package/src/styles/effects-chrome.css +888 -0
  373. package/src/styles/finance-composites.css +214 -0
  374. package/src/styles/finance-tearsheet-overlay.css +90 -0
  375. package/src/styles/finance-tearsheet.css +945 -0
  376. package/src/styles/marquee.css +168 -0
  377. package/src/styles/metrics.css +82 -0
  378. package/src/styles/nav-shell.css +551 -0
  379. package/src/styles/pricing.css +79 -0
  380. package/src/styles/repo-activity.css +575 -0
  381. package/src/styles/stages.css +69 -0
  382. package/src/styles/terminal-loaders.css +122 -0
  383. package/src/styles/terminal-manifest.css +228 -0
  384. package/src/styles/web-theme.css +1007 -0
  385. package/src/styles/word-reveal.css +204 -0
  386. package/src/theme/apply-theme.ts +214 -0
  387. package/src/theme/index.ts +27 -0
  388. package/src/theme/palette-registry.ts +855 -0
  389. package/src/theme/tui-prefs.ts +64 -0
  390. package/src/ui/alert.tsx +78 -0
  391. package/src/ui/avatar.tsx +104 -0
  392. package/src/ui/badge.tsx +75 -0
  393. package/src/ui/breadcrumb.tsx +61 -0
  394. package/src/ui/button.tsx +67 -0
  395. package/src/ui/card.tsx +139 -0
  396. package/src/ui/checkbox.tsx +27 -0
  397. package/src/ui/collapsible.tsx +32 -0
  398. package/src/ui/date-pager.tsx +325 -0
  399. package/src/ui/dialog.tsx +157 -0
  400. package/src/ui/dropdown-menu.tsx +267 -0
  401. package/src/ui/empty-state.tsx +165 -0
  402. package/src/ui/field.tsx +104 -0
  403. package/src/ui/form.tsx +36 -0
  404. package/src/ui/icon-button.tsx +36 -0
  405. package/src/ui/index.ts +34 -0
  406. package/src/ui/input.tsx +33 -0
  407. package/src/ui/kbd.tsx +30 -0
  408. package/src/ui/label.tsx +32 -0
  409. package/src/ui/pager.tsx +119 -0
  410. package/src/ui/pagination.tsx +126 -0
  411. package/src/ui/radio-group.tsx +51 -0
  412. package/src/ui/search-bar.tsx +85 -0
  413. package/src/ui/segmented-control.tsx +76 -0
  414. package/src/ui/select.tsx +257 -0
  415. package/src/ui/separator.tsx +24 -0
  416. package/src/ui/sheet.tsx +141 -0
  417. package/src/ui/skeleton.tsx +76 -0
  418. package/src/ui/slider.tsx +76 -0
  419. package/src/ui/switch.tsx +31 -0
  420. package/src/ui/table.tsx +179 -0
  421. package/src/ui/tabs.tsx +89 -0
  422. package/src/ui/tags-input.tsx +168 -0
  423. package/src/ui/textarea.tsx +17 -0
  424. package/src/ui/tooltip.tsx +71 -0
@@ -0,0 +1,888 @@
1
+ /* ==========================================================================
2
+ @digithings-ai/ui — effects/chrome family structural CSS
3
+ (components/effects-chrome/*: <Pipeline/>, <RotatingPrompts/>,
4
+ <StackingPanels/>, <AnnouncementBar/>, <TabStrip/>, <ToastStack/>).
5
+
6
+ Import AFTER the token bridge, in the app's globals.css:
7
+ @import "tailwindcss";
8
+ @import "@digithings-ai/design/tokens.css";
9
+ @import "@digithings-ai/ui/styles/web-theme.css";
10
+ @import "@digithings-ai/ui/styles/effects-chrome.css";
11
+ @source "<path-to>/packages/ui/src/components/effects-chrome";
12
+ The @source line is load-bearing (path relative to the app's globals.css):
13
+ the components carry token-backed utilities, and Tailwind does not scan
14
+ package sources on its own. Import this sheet PLAINLY (no layer(...)) —
15
+ it manages its own layering:
16
+
17
+ - single-class DEFAULT rules sit in `@layer components`, where the app's
18
+ `utilities` layer wins — call-site utilities (rounded-none, p-0 …) can
19
+ retune a default;
20
+ - STATE / STRUCTURAL rules (pseudo-classes, [aria-*], variant combinators,
21
+ descendant selectors, @keyframes hooks, media queries) stay UNLAYERED on
22
+ purpose so they keep beating plain call-site utilities — the cascade
23
+ contract from MIGRATION.md. Wrapping this import in layer(…) demotes the
24
+ state rules and breaks the rendered look.
25
+
26
+ Consumer-supplied custom props (fallbacks baked in):
27
+ --nav-h sticky-pin offset for <StackingPanels/> (falls back to 3.4rem)
28
+ ========================================================================== */
29
+
30
+ /* ── Pipeline — workflow viz (ported from the dashboard) ──────────
31
+ The components carry the outer boxes (summary strip, flow row, columns) as
32
+ token utilities; the classes stay on the elements for the combinator /
33
+ modifier rules here: node states, the running pulse, the detail grids. */
34
+
35
+ @layer components {
36
+ .pl-sum-k {
37
+ --pl-sum-k-font: 0.54rem;
38
+
39
+ font-family: var(--font-mono);
40
+ font-size: var(--pl-sum-k-font);
41
+ text-transform: uppercase;
42
+ letter-spacing: 0.1em;
43
+ color: var(--ink-mute);
44
+ }
45
+
46
+ .pl-sum-v {
47
+ --pl-sum-v-font: 0.95rem;
48
+
49
+ font-family: var(--font-mono);
50
+ font-size: var(--pl-sum-v-font);
51
+ color: var(--ink);
52
+ font-variant-numeric: tabular-nums;
53
+ }
54
+
55
+ .pl-col-tag {
56
+ --pl-col-tag-top: 0.4rem;
57
+ --pl-col-tag-inline: 0.7rem;
58
+ --pl-col-tag-font: 0.52rem;
59
+
60
+ position: absolute;
61
+ top: var(--pl-col-tag-top);
62
+ inset-inline-start: var(--pl-col-tag-inline);
63
+ font-family: var(--font-mono);
64
+ font-size: var(--pl-col-tag-font);
65
+ text-transform: uppercase;
66
+ letter-spacing: 0.1em;
67
+ color: var(--ink-mute);
68
+ }
69
+
70
+ .pl-node {
71
+ --pl-node-w: 9.5rem;
72
+ --pl-node-gap: 0.35rem;
73
+ --pl-node-pad-block: 0.6rem;
74
+ --pl-node-pad-inline: 0.7rem;
75
+ --pl-node-head-gap: 0.45rem;
76
+ --pl-node-font: 0.8rem;
77
+ --pl-node-diag-font: 0.6rem;
78
+
79
+ width: var(--pl-node-w);
80
+ display: flex;
81
+ flex-direction: column;
82
+ gap: var(--pl-node-gap);
83
+ padding: var(--pl-node-pad-block) var(--pl-node-pad-inline);
84
+ border: 1px solid var(--hair);
85
+ border-radius: 0;
86
+ background: var(--surface);
87
+ text-align: start;
88
+ cursor: pointer;
89
+ transition: border-color 0.18s var(--ease), transform 0.15s var(--ease);
90
+ /* Containing block for the node's own `.pl-sr` status text. `.pl-sr` is
91
+ absolutely positioned; without a positioned ancestor its containing
92
+ block is the initial containing block, so it escaped `.pl-flow`'s
93
+ `overflow-x: auto` scroller (an abspos box is only clipped by a scroll
94
+ ancestor that is in its containing-block chain) and folded its static
95
+ position — far right inside the row's min-content width — into the
96
+ ROOT scroller. That was the reference audit's /effects @390 critical:
97
+ documentElement.scrollWidth 785 against a 390 viewport. Anchoring it
98
+ to the node keeps the sr-only text inside the flow's own scroller. */
99
+ position: relative;
100
+ }
101
+
102
+ .pl-node-head {
103
+ display: flex;
104
+ align-items: center;
105
+ gap: var(--pl-node-head-gap, 0.45rem);
106
+ }
107
+
108
+ .pl-pip {
109
+ --pl-pip: 7px;
110
+
111
+ width: var(--pl-pip);
112
+ height: var(--pl-pip);
113
+ border-radius: 0;
114
+ background: var(--ink-soft);
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ .pl-node-label {
119
+ font-family: var(--font-mono);
120
+ font-size: var(--pl-node-font, 0.8rem);
121
+ color: var(--ink);
122
+ }
123
+
124
+ .pl-node-diag {
125
+ display: flex;
126
+ justify-content: space-between;
127
+ font-family: var(--font-mono);
128
+ font-size: var(--pl-node-diag-font, 0.6rem);
129
+ color: var(--ink-mute);
130
+ font-variant-numeric: tabular-nums;
131
+ }
132
+
133
+ /* Each node's screen-reader-only run-status text. Deliberately NOT
134
+ Tailwind's `.sr-only`: that utility is only emitted into an app whose
135
+ own source uses the class, so a shared component leaning on it renders
136
+ a plain visible span in any app that does not (see .tl-sr/.tm-sr for
137
+ the same fix, and the bug it fixed once already). */
138
+ .pl-sr {
139
+ position: absolute;
140
+ width: 1px;
141
+ height: 1px;
142
+ padding: 0;
143
+ margin: -1px;
144
+ overflow: hidden;
145
+ clip-path: inset(50%);
146
+ white-space: nowrap;
147
+ border-width: 0;
148
+ }
149
+
150
+ .pl-conn {
151
+ --pl-conn-pad: 0.4rem;
152
+
153
+ flex-shrink: 0;
154
+ padding: 0 var(--pl-conn-pad);
155
+ color: color-mix(in srgb, var(--ink-mute) 80%, transparent);
156
+ display: inline-flex;
157
+ }
158
+
159
+ .pl-detail {
160
+ --pl-detail-top: 1rem;
161
+ --pl-detail-gap: 0.6rem;
162
+ --pl-detail-pad-block: 0.85rem;
163
+ --pl-detail-pad-inline: 1.1rem;
164
+ --pl-detail-model-font: 0.62rem;
165
+ --pl-diag-k-font: 0.52rem;
166
+ --pl-diag-v-font: 0.86rem;
167
+ --pl-sum-k-font: 0.54rem;
168
+
169
+ margin-top: var(--pl-detail-top);
170
+ border: 1px solid var(--hair);
171
+ border-radius: 0;
172
+ background: var(--surface);
173
+ overflow: hidden;
174
+ }
175
+
176
+ .pl-detail-head {
177
+ --pl-detail-name-font: 0.9rem;
178
+
179
+ display: flex;
180
+ align-items: center;
181
+ gap: var(--pl-detail-gap);
182
+ padding: var(--pl-detail-pad-block) var(--pl-detail-pad-inline);
183
+ border-bottom: 1px solid var(--hair);
184
+ }
185
+
186
+ .pl-detail-name {
187
+ font-family: var(--font-mono);
188
+ font-size: var(--pl-detail-name-font, 0.9rem);
189
+ color: var(--ink);
190
+ }
191
+
192
+ .pl-detail-model {
193
+ --pl-detail-model-pad-block: 0.1rem;
194
+
195
+ font-family: var(--font-mono);
196
+ font-size: var(--pl-detail-model-font, 0.62rem);
197
+ color: var(--ink-mute);
198
+ border: 1px solid var(--hair);
199
+ border-radius: 0;
200
+ padding: var(--pl-detail-model-pad-block) var(--space-2);
201
+ }
202
+
203
+ .pl-detail-status {
204
+ margin-inline-start: auto;
205
+ font-family: var(--font-mono);
206
+ font-size: var(--pl-node-diag-font, 0.6rem);
207
+ text-transform: uppercase;
208
+ letter-spacing: 0.08em;
209
+ color: var(--ink-mute);
210
+ }
211
+
212
+ .pl-io {
213
+ display: grid;
214
+ grid-template-columns: 1fr 1fr;
215
+ gap: 1px;
216
+ margin: 0;
217
+ background: var(--hair);
218
+ }
219
+
220
+ /* What the selected stage does, in one line. Sits between the head and the
221
+ inputs/outputs because it is the sentence that makes the pair readable —
222
+ the run diagnostics below it are optional and often absent. */
223
+ .pl-note {
224
+ --pl-note-pad-block: 0.8rem;
225
+ --pl-note-pad-inline: 1.1rem;
226
+ --pl-note-font: 0.78rem;
227
+
228
+ margin: 0;
229
+ padding: var(--pl-note-pad-block) var(--pl-note-pad-inline) 0;
230
+ font-family: var(--font-mono);
231
+ font-size: var(--pl-note-font);
232
+ line-height: 1.6;
233
+ color: var(--ink-soft);
234
+ }
235
+
236
+ /* `auto-fit` rather than a fixed four, because a node may carry any subset of
237
+ the four diagnostics: a two-wide grid left two empty tracks when only two
238
+ were present, which reads as missing data. */
239
+ .pl-diag-grid {
240
+ /* 7rem is a content-measured track floor (one diagnostic label+value pair) */
241
+ --pl-diag-min: 7rem;
242
+ --pl-diag-top: 0.8rem;
243
+
244
+ display: grid;
245
+ grid-template-columns: repeat(auto-fit, minmax(var(--pl-diag-min), 1fr));
246
+ border-top: 1px solid var(--hair);
247
+ margin-top: var(--pl-diag-top);
248
+ }
249
+
250
+ .pl-diag-k {
251
+ font-family: var(--font-mono);
252
+ font-size: var(--pl-diag-k-font, 0.52rem);
253
+ text-transform: uppercase;
254
+ letter-spacing: 0.08em;
255
+ color: var(--ink-mute);
256
+ }
257
+
258
+ .pl-diag-v {
259
+ font-family: var(--font-mono);
260
+ font-size: var(--pl-diag-v-font, 0.86rem);
261
+ color: var(--ink);
262
+ font-variant-numeric: tabular-nums;
263
+ }
264
+ }
265
+
266
+ /* state / structural — unlayered on purpose (cascade contract) */
267
+
268
+ .pl-summary > span {
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 0.15rem;
272
+ }
273
+
274
+ .pl-running {
275
+ color: var(--accent);
276
+ }
277
+
278
+ .pl-col--par {
279
+ position: relative;
280
+ padding: 1.3rem var(--pl-node-pad-inline, 0.7rem) var(--pl-node-pad-inline, 0.7rem);
281
+ border: 1px dashed color-mix(in srgb, var(--ink) 26%, var(--hair));
282
+ border-radius: 0;
283
+ }
284
+
285
+ .pl-node:hover {
286
+ transform: translateY(-1px);
287
+ border-color: color-mix(in srgb, var(--ink) 30%, var(--hair));
288
+ }
289
+
290
+ /* .pl-flow (the horizontally-scrolling node row) computes overflow-x AND
291
+ overflow-y as auto once either axis is non-visible (CSS Overflow spec),
292
+ with only ~1.6px of horizontal padding — not enough clearance for the
293
+ global :focus-visible rule's positive outline-offset (3px) + width (2px)
294
+ on the first/last node in the row. Same fix as .ts-seg-btn
295
+ (finance-tearsheet.css): an inset ring draws entirely inside the node's
296
+ own border box, so it can never be clipped regardless of available
297
+ external clearance. */
298
+ .pl-node:focus-visible {
299
+ outline: 2px solid var(--accent);
300
+ outline-offset: -2px;
301
+ border-radius: 0;
302
+ }
303
+
304
+ .pl-node.is-sel {
305
+ border-color: var(--accent);
306
+ box-shadow: 0 0 0 1px var(--accent);
307
+ }
308
+
309
+ .pl-node--queued {
310
+ opacity: 0.55;
311
+ }
312
+
313
+ .pl-node--running .pl-pip,
314
+ .pl-pip--running {
315
+ background: var(--accent);
316
+ animation: pl-pulse 1.6s var(--ease) infinite;
317
+ }
318
+
319
+ .pl-node--queued .pl-pip,
320
+ .pl-pip--queued {
321
+ background: transparent;
322
+ border: 1px solid var(--ink-mute);
323
+ }
324
+
325
+ .pl-pip--done {
326
+ background: var(--ink-soft);
327
+ }
328
+
329
+ @keyframes pl-pulse {
330
+ 0% {
331
+ box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
332
+ }
333
+ 70% {
334
+ box-shadow: 0 0 0 5px transparent;
335
+ }
336
+ 100% {
337
+ box-shadow: 0 0 0 0 transparent;
338
+ }
339
+ }
340
+
341
+ .pl-detail-status--running {
342
+ color: var(--accent);
343
+ }
344
+
345
+ .pl-io > div {
346
+ background: var(--surface);
347
+ padding: var(--pl-detail-pad-block, 0.85rem) var(--pl-detail-pad-inline, 1.1rem);
348
+ }
349
+
350
+ .pl-io dt {
351
+ font-family: var(--font-mono);
352
+ font-size: var(--pl-sum-k-font, 0.54rem);
353
+ text-transform: uppercase;
354
+ letter-spacing: 0.1em;
355
+ color: var(--ink-mute);
356
+ margin-bottom: 0.3rem;
357
+ }
358
+
359
+ .pl-io dd {
360
+ margin: 0;
361
+ font-family: var(--font-mono);
362
+ font-size: var(--pl-node-font, 0.8rem);
363
+ color: var(--ink-soft);
364
+ }
365
+
366
+ .pl-diag-grid > div {
367
+ display: flex;
368
+ flex-direction: column;
369
+ gap: var(--space-1);
370
+ padding: var(--pl-note-pad-block, 0.8rem) var(--pl-detail-pad-inline, 1.1rem);
371
+ border-inline-start: 1px solid var(--hair);
372
+ }
373
+
374
+ .pl-diag-grid > div:first-child {
375
+ border-inline-start: none;
376
+ }
377
+
378
+ @media (prefers-reduced-motion: reduce) {
379
+ .pl-node--running .pl-pip,
380
+ .pl-pip--running {
381
+ animation: none;
382
+ }
383
+ }
384
+
385
+ @media (max-width: 640px) {
386
+ .pl-io {
387
+ grid-template-columns: 1fr;
388
+ }
389
+ .pl-diag-grid {
390
+ grid-template-columns: repeat(2, 1fr);
391
+ }
392
+ .pl-diag-grid > div:nth-child(3) {
393
+ border-inline-start: none;
394
+ }
395
+ }
396
+
397
+ /* ── RotatingPrompts — blinking caret ─────────────────────────────────────
398
+ The component carries the prompt shell as token utilities. Only the caret
399
+ stays CSS — it owns an @keyframes animation (migrate-vs-leave). */
400
+
401
+ @layer components {
402
+ .prompt-caret {
403
+ --prompt-caret-w: 7px;
404
+ --prompt-caret-h: 15px;
405
+
406
+ width: var(--prompt-caret-w);
407
+ height: var(--prompt-caret-h);
408
+ background: var(--accent);
409
+ align-self: center;
410
+ animation: prompt-blink 1.1s steps(1) infinite;
411
+ }
412
+
413
+ /* WCAG 2.2.2 pause control — borderless icon button, same resting/hover
414
+ tone as the house's other chrome icon buttons (theme toggle, nav
415
+ burger). */
416
+ .prompt-pause {
417
+ display: inline-flex;
418
+ align-items: center;
419
+ justify-content: center;
420
+ align-self: center;
421
+ /* WCAG 2.5.8: 24x24 CSS px minimum touch target. The 13px icon + 0.2rem
422
+ padding alone only reach ~19.4px; this pads the hit area out to the
423
+ floor without changing the icon's own visual size. */
424
+ min-width: var(--space-4);
425
+ min-height: var(--space-4);
426
+ padding: var(--space-1);
427
+ border: none;
428
+ background: transparent;
429
+ color: var(--ink-mute);
430
+ cursor: pointer;
431
+ transition: color 0.18s var(--ease);
432
+ }
433
+ }
434
+
435
+ .prompt-pause:hover {
436
+ color: var(--ink);
437
+ }
438
+
439
+ @keyframes prompt-blink {
440
+ 50% {
441
+ opacity: 0;
442
+ }
443
+ }
444
+
445
+ @media (prefers-reduced-motion: reduce) {
446
+ .prompt-caret {
447
+ animation: none;
448
+ }
449
+ }
450
+
451
+ /* ── StackingPanels — pinned layered panels ───────────────────────────────
452
+ Content type is token utilities in the component. The panel mechanics stay
453
+ CSS: sticky pin off the consumer's --nav-h, the layered seam shadow, and
454
+ transform-origin for the JS-driven scale-back. .stk-dim stays a class —
455
+ the scroll handler grabs it via querySelector and writes its opacity. */
456
+
457
+ @layer components {
458
+ .stk-panel {
459
+ /* component tokens — sticky panel offset / height / padding */
460
+ --stk-top-gap: 1.2rem;
461
+ --stk-min-h: 52vh;
462
+ --stk-pad: clamp(1.6rem, 5vw, 3.2rem);
463
+
464
+ position: sticky;
465
+ top: calc(var(--nav-h, 3.4rem) + var(--stk-top-gap));
466
+ min-height: var(--stk-min-h);
467
+ display: flex;
468
+ align-items: center;
469
+ padding: var(--stk-pad);
470
+ border: 1px solid var(--hair);
471
+ border-radius: 0;
472
+ background: var(--surface);
473
+ /* concrete black: cast-shadow ink, deliberately theme-invariant (no
474
+ shadow token) — same read as the reference specimen */
475
+ box-shadow: 0 -22px 46px -26px rgba(0, 0, 0, 0.6);
476
+ transform-origin: center top;
477
+ will-change: transform;
478
+ overflow: hidden;
479
+ }
480
+
481
+ /* darkening overlay as a panel is covered — JS drives opacity */
482
+ .stk-dim {
483
+ position: absolute;
484
+ inset: 0;
485
+ z-index: 2;
486
+ background: var(--bg);
487
+ opacity: 0;
488
+ pointer-events: none;
489
+ }
490
+ }
491
+
492
+ /* ── AnnouncementBar — whole-bar link chrome ──────────────────────────────
493
+ The frame is a components-layer default (production overrides the demo
494
+ radius/border with call-site utilities); the link keeps its class for the
495
+ parent-hover-descendant CTA rule, which has no single-element utility. */
496
+
497
+ @layer components {
498
+ .annc-bar {
499
+ --annc-bar-h: 48px;
500
+
501
+ display: flex;
502
+ min-height: var(--annc-bar-h);
503
+ align-items: center;
504
+ border: 1px solid var(--hair);
505
+ border-radius: 0;
506
+ background: var(--surface);
507
+ }
508
+
509
+ .annc-link {
510
+ --annc-link-font: 0.8rem;
511
+
512
+ flex: 1;
513
+ display: flex;
514
+ flex-wrap: wrap;
515
+ align-items: center;
516
+ justify-content: center;
517
+ gap: var(--space-1) var(--space-2);
518
+ padding: 0.55rem var(--space-3);
519
+ font-size: var(--annc-link-font);
520
+ color: var(--ink);
521
+ text-decoration: none;
522
+ }
523
+ }
524
+
525
+ /* state / structural — unlayered on purpose (cascade contract) */
526
+
527
+ .annc-link:hover b {
528
+ text-decoration: underline;
529
+ }
530
+
531
+ .annc-link b {
532
+ font-weight: 400;
533
+ color: var(--accent);
534
+ }
535
+
536
+ /* ── TabStrip — sliding active indicator, three dresses ───────────────────
537
+ Base strip/button/ink defaults are components-layer; the variant
538
+ combinators, aria/hover/focus states, and the ink (whose transform +
539
+ width — and height for the box dresses — are written from a ref and
540
+ animated by this transition) stay unlayered — they must keep beating
541
+ call-site utilities. Box-dress inks (pill/chip) anchor top + inline-start
542
+ and take translate(x, y) + measured height from the component, so a `chip`
543
+ strip may flex-wrap and the ink still lands on the active row. The
544
+ component measures from that same inline-start edge and negates x under
545
+ dir=rtl, since `transform` has no logical form. */
546
+
547
+ @layer components {
548
+ .tab-strip {
549
+ --tab-strip-gap: 0.2rem;
550
+ --tab-btn-font: 0.76rem;
551
+ --tab-btn-pad-block: 0.55rem;
552
+ --tab-btn-pad-inline: 0.7rem;
553
+ --tab-btn-pad-bottom: 0.7rem;
554
+ --tab-btn-pill-pad-block: 0.4rem;
555
+ --tab-btn-pill-pad-inline: 0.95rem;
556
+
557
+ position: relative;
558
+ display: inline-flex;
559
+ gap: var(--tab-strip-gap);
560
+ }
561
+
562
+ .tab-btn {
563
+ position: relative;
564
+ z-index: 1;
565
+ border: none;
566
+ background: transparent;
567
+ color: var(--ink-mute);
568
+ font-family: var(--font-mono);
569
+ font-size: var(--tab-btn-font);
570
+ letter-spacing: 0.02em;
571
+ cursor: pointer;
572
+ transition: color 0.2s var(--ease);
573
+ }
574
+
575
+ .tab-ink {
576
+ position: absolute;
577
+ transition:
578
+ transform 0.28s var(--ease),
579
+ width 0.28s var(--ease);
580
+ pointer-events: none;
581
+ }
582
+ }
583
+
584
+ /* state / structural — unlayered on purpose (cascade contract) */
585
+
586
+ .tab-strip.underline {
587
+ --tab-strip-gap-underline: 0.4rem;
588
+
589
+ display: flex;
590
+ gap: var(--tab-strip-gap-underline);
591
+ border-bottom: 1px solid var(--hair);
592
+ /* The strip must never force the page wider than the viewport: tabs
593
+ scroll inside the strip (the ink is absolutely positioned, so it
594
+ scrolls with them) instead of pushing the document to 545px on phones. */
595
+ min-width: 0;
596
+ max-width: 100%;
597
+ overflow-x: auto;
598
+ }
599
+
600
+ .tab-strip.pill {
601
+ --tab-strip-pad: 0.25rem;
602
+
603
+ padding: var(--tab-strip-pad);
604
+ border: 1px solid var(--hair);
605
+ border-radius: 0;
606
+ background: color-mix(in srgb, var(--surface) 90%, var(--bg));
607
+ }
608
+
609
+ .tab-strip.underline .tab-btn {
610
+ padding: var(--tab-btn-pad-block, 0.55rem) var(--tab-btn-pad-inline, 0.7rem) var(--tab-btn-pad-bottom, 0.7rem);
611
+ }
612
+
613
+ .tab-strip.pill .tab-btn {
614
+ padding: var(--tab-btn-pill-pad-block, 0.4rem) var(--tab-btn-pill-pad-inline, 0.95rem);
615
+ }
616
+
617
+ .tab-btn:hover {
618
+ color: var(--ink-soft);
619
+ }
620
+
621
+ .tab-btn[aria-selected="true"] {
622
+ color: var(--ink);
623
+ }
624
+
625
+ .tab-btn:focus-visible {
626
+ outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
627
+ outline-offset: 2px;
628
+ border-radius: 0;
629
+ }
630
+
631
+ .tab-ink.underline {
632
+ inset-inline-start: 0;
633
+ bottom: -1px;
634
+ height: 2px;
635
+ background: var(--accent);
636
+ }
637
+
638
+ /* pill/chip inks: top/left origin — transform + height come from the ref */
639
+ .tab-ink.pill {
640
+ z-index: 0;
641
+ top: 0;
642
+ inset-inline-start: 0;
643
+ border-radius: 0;
644
+ background: color-mix(in srgb, var(--accent) 16%, transparent);
645
+ border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
646
+ }
647
+
648
+ /* chip — the dashboard sub-nav dress: wrapping row of bordered
649
+ chips, sans face, accent-tinted active chip (parity with the app's
650
+ `subpageTabButtonClass` active/inactive reads). */
651
+ .tab-strip.chip {
652
+ --tab-strip-gap-chip: 0.5rem;
653
+
654
+ display: flex;
655
+ flex-wrap: wrap;
656
+ gap: var(--tab-strip-gap-chip);
657
+ }
658
+
659
+ .tab-strip.chip .tab-btn {
660
+ display: flex;
661
+ align-items: center;
662
+ gap: var(--tab-strip-gap-chip, 0.5rem);
663
+ padding: var(--space-2) var(--space-3);
664
+ border: 1px solid transparent;
665
+ border-radius: 0;
666
+ font-family: var(--font-mono);
667
+ font-size: 0.875rem;
668
+ font-weight: 500;
669
+ letter-spacing: 0.02em;
670
+ color: var(--ink-soft);
671
+ transition:
672
+ color 0.2s var(--ease),
673
+ background-color 0.2s var(--ease);
674
+ }
675
+
676
+ .tab-strip.chip .tab-btn:hover:not([aria-selected="true"]) {
677
+ background: color-mix(in srgb, var(--ink) 4%, transparent);
678
+ color: var(--ink);
679
+ }
680
+
681
+ .tab-strip.chip .tab-btn[aria-selected="true"] {
682
+ color: var(--accent);
683
+ }
684
+
685
+ .tab-ink.chip {
686
+ z-index: 0;
687
+ top: 0;
688
+ inset-inline-start: 0;
689
+ border-radius: 0;
690
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
691
+ border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
692
+ }
693
+
694
+ @media (prefers-reduced-motion: reduce) {
695
+ .tab-ink {
696
+ transition: none;
697
+ }
698
+ }
699
+
700
+ /* ── ToastStack — corner stack, per-tone reads, drain timer ───────────────
701
+ Base card/part defaults are components-layer; the per-tone border/icon/
702
+ progress states, the spin/drain keyframes, and the reduced-motion guard
703
+ stay unlayered. Success/error ride --up/--down (money-read semantics),
704
+ info rides the accent — never a livery. */
705
+
706
+ @layer components {
707
+ .toast-stack {
708
+ --toast-stack-inset: 1.25rem;
709
+ --toast-stack-gap: 0.6rem;
710
+ --toast-stack-w: 22rem;
711
+
712
+ position: fixed;
713
+ inset: auto var(--toast-stack-inset) var(--toast-stack-inset) auto;
714
+ z-index: 40;
715
+ display: flex;
716
+ flex-direction: column;
717
+ gap: var(--toast-stack-gap);
718
+ width: min(var(--toast-stack-w), calc(100vw - (2 * var(--toast-stack-inset))));
719
+ pointer-events: none;
720
+ }
721
+
722
+ .toast {
723
+ --toast-gap: 0.7rem;
724
+ --toast-pad-block: 0.8rem;
725
+ --toast-pad-inline: 0.85rem;
726
+ --toast-title-font: 0.8rem;
727
+ --toast-msg-font: 0.76rem;
728
+ --toast-action-font: 0.74rem;
729
+ --toast-close-pad: 0.15rem;
730
+
731
+ position: relative;
732
+ display: grid;
733
+ grid-template-columns: auto 1fr auto;
734
+ gap: var(--toast-gap);
735
+ align-items: start;
736
+ padding: var(--toast-pad-block) var(--toast-pad-inline);
737
+ border: 1px solid var(--hair);
738
+ border-inline-start-width: 2px;
739
+ border-radius: 0;
740
+ background: color-mix(in srgb, var(--surface) 96%, var(--bg));
741
+ /* concrete black: cast-shadow ink, deliberately theme-invariant (no
742
+ shadow token) — same read as the reference specimen */
743
+ box-shadow: 0 16px 40px -20px rgba(0, 0, 0, 0.6);
744
+ overflow: hidden;
745
+ pointer-events: auto;
746
+ }
747
+
748
+ .toast-icon {
749
+ display: inline-flex;
750
+ margin-top: 0.05rem;
751
+ }
752
+
753
+ .toast-body {
754
+ min-width: 0;
755
+ }
756
+
757
+ .toast-title {
758
+ margin: 0;
759
+ font-family: var(--font-mono);
760
+ font-size: var(--toast-title-font);
761
+ color: var(--ink);
762
+ }
763
+
764
+ .toast-msg {
765
+ margin: 0.15rem 0 0;
766
+ font-size: var(--toast-msg-font);
767
+ line-height: 1.45;
768
+ color: var(--ink-mute);
769
+ }
770
+
771
+ /* the optional one-click recovery control (ToastItem.action) — a plain
772
+ text button, not tone-colored (unlike the border/icon, which do ride
773
+ --up/--down per this file's own money-read convention above): the
774
+ action is "the thing you can click", independent of the toast's
775
+ success/error semantics. */
776
+ .toast-action {
777
+ display: inline-block;
778
+ margin: 0.35rem 0 0;
779
+ padding: 0;
780
+ border: none;
781
+ background: transparent;
782
+ font-family: var(--font-mono);
783
+ font-size: var(--toast-action-font);
784
+ color: var(--accent);
785
+ text-decoration: underline;
786
+ text-underline-offset: 2px;
787
+ cursor: pointer;
788
+ transition: color 0.2s var(--ease);
789
+ }
790
+
791
+ .toast-action:hover {
792
+ color: var(--ink);
793
+ }
794
+
795
+ .toast-close {
796
+ display: inline-flex;
797
+ padding: var(--toast-close-pad, 0.15rem);
798
+ border: none;
799
+ background: transparent;
800
+ color: var(--ink-mute);
801
+ cursor: pointer;
802
+ transition: color 0.2s var(--ease);
803
+ }
804
+
805
+ .toast-progress {
806
+ position: absolute;
807
+ inset-inline-start: 0;
808
+ bottom: 0;
809
+ width: 100%;
810
+ height: 2px;
811
+ transform-origin: left;
812
+ background: color-mix(in srgb, currentColor 55%, var(--hair));
813
+ animation: toast-drain linear forwards;
814
+ }
815
+
816
+ /* transform-origin has no logical keyword: the drain scales from the bar's
817
+ inline-start, which is the right edge under dir=rtl. */
818
+ [dir="rtl"] .toast-progress {
819
+ transform-origin: right;
820
+ }
821
+ }
822
+
823
+ /* state / structural — unlayered on purpose (cascade contract) */
824
+
825
+ .toast-success {
826
+ border-inline-start-color: var(--up);
827
+ }
828
+ .toast-error {
829
+ border-inline-start-color: var(--down);
830
+ }
831
+ .toast-info {
832
+ border-inline-start-color: var(--accent);
833
+ }
834
+ .toast-loading {
835
+ border-inline-start-color: var(--ink-mute);
836
+ }
837
+
838
+ .toast-success .toast-icon {
839
+ color: var(--up);
840
+ }
841
+ .toast-error .toast-icon {
842
+ color: var(--down);
843
+ }
844
+ .toast-info .toast-icon {
845
+ color: var(--accent);
846
+ }
847
+ .toast-loading .toast-icon {
848
+ color: var(--ink-mute);
849
+ }
850
+
851
+ .toast-spin {
852
+ animation: toast-spin 0.8s linear infinite;
853
+ }
854
+
855
+ @keyframes toast-spin {
856
+ to {
857
+ transform: rotate(360deg);
858
+ }
859
+ }
860
+
861
+ .toast-close:hover {
862
+ color: var(--ink);
863
+ }
864
+
865
+ .toast-success .toast-progress {
866
+ color: var(--up);
867
+ }
868
+ .toast-error .toast-progress {
869
+ color: var(--down);
870
+ }
871
+ .toast-info .toast-progress {
872
+ color: var(--accent);
873
+ }
874
+
875
+ @keyframes toast-drain {
876
+ from {
877
+ transform: scaleX(1);
878
+ }
879
+ to {
880
+ transform: scaleX(0);
881
+ }
882
+ }
883
+
884
+ @media (prefers-reduced-motion: reduce) {
885
+ .toast-spin {
886
+ animation: none;
887
+ }
888
+ }