@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.
- package/README.md +48 -2
- package/package.json +143 -4
- package/src/components/NavShell.tsx +776 -0
- package/src/components/SocialRow.tsx +87 -0
- package/src/components/Spinner.tsx +27 -0
- package/src/components/StackLogo.tsx +40 -0
- package/src/components/Terminal.tsx +110 -0
- package/src/components/TerminalManifest.tsx +212 -0
- package/src/components/ThemeProvider.tsx +271 -0
- package/src/components/account/AuthCard.tsx +309 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
- package/src/components/brand/BrandWordmark.tsx +32 -0
- package/src/components/changelog/ReleaseRail.tsx +81 -0
- package/src/components/changelog/index.ts +1 -0
- package/src/components/chat/ChatCodeBlock.tsx +67 -0
- package/src/components/chat/ChatMarkdown.tsx +66 -0
- package/src/components/chat/ChatMarkdownSource.tsx +203 -0
- package/src/components/chat/ChatMermaidBlock.tsx +202 -0
- package/src/components/chat/ChatMessage.tsx +77 -0
- package/src/components/chat/ChatPlayback.tsx +422 -0
- package/src/components/chat/ChatStreamCursor.tsx +25 -0
- package/src/components/chat/ChatThinking.tsx +113 -0
- package/src/components/chat/ChatToolCall.tsx +190 -0
- package/src/components/chat/ChatTranscript.tsx +60 -0
- package/src/components/chat/ChatWidgetFrame.tsx +107 -0
- package/src/components/chat/DigichatBootLoader.tsx +683 -0
- package/src/components/chat/DigichatLauncher.tsx +361 -0
- package/src/components/chat/DigichatThread.tsx +118 -0
- package/src/components/chat/DigichatThreadList.tsx +54 -0
- package/src/components/chat/DigichatWordmark.tsx +24 -0
- package/src/components/chat/DotMatrix.tsx +650 -0
- package/src/components/chat/boot-lab.tsx +766 -0
- package/src/components/chat/boot-signal.ts +144 -0
- package/src/components/chat/chat-surfaces.ts +52 -0
- package/src/components/chat/connection-status.ts +40 -0
- package/src/components/chat/digichat-wordmark.ts +355 -0
- package/src/components/chat/disclosure-chevron.tsx +49 -0
- package/src/components/chat/followable-href.ts +9 -0
- package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
- package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
- package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
- package/src/components/chat/gallery-thread/cn.ts +1 -0
- package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
- package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
- package/src/components/chat/gallery-thread/css.d.ts +6 -0
- package/src/components/chat/gallery-thread/file.tsx +238 -0
- package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
- package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
- package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
- package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
- package/src/components/chat/gallery-thread/image.tsx +519 -0
- package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
- package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
- package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
- package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
- package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
- package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
- package/src/components/chat/gallery-thread/source.tsx +76 -0
- package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
- package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
- package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
- package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
- package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
- package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
- package/src/components/chat/gallery-thread/work-status.ts +66 -0
- package/src/components/chat/overlay-scrollbar.tsx +86 -0
- package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
- package/src/components/chat/skins/SOURCE.md +36 -0
- package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
- package/src/components/chat/skins/base/aui-default/README.md +45 -0
- package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
- package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
- package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
- package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
- package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
- package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
- package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
- package/src/components/chat/skins/base/docs-model-options.ts +6 -0
- package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
- package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
- package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
- package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
- package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
- package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
- package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
- package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
- package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
- package/src/components/chat/skins/base/markdown-text.tsx +294 -0
- package/src/components/chat/skins/base/model.ts +1 -0
- package/src/components/chat/skins/base/thread.tsx +1050 -0
- package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
- package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
- package/src/components/chat/skins/base/ui/badge.tsx +51 -0
- package/src/components/chat/skins/base/ui/button.tsx +67 -0
- package/src/components/chat/skins/base/ui/command.tsx +185 -0
- package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
- package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
- package/src/components/chat/skins/base/ui/popover.tsx +97 -0
- package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
- package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
- package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
- package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
- package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
- package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
- package/src/components/chat/skins/chatgpt.tsx +448 -0
- package/src/components/chat/skins/claude.tsx +380 -0
- package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
- package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
- package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
- package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
- package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
- package/src/components/chat/skins/digichat.tsx +144 -0
- package/src/components/chat/skins/expo-react-native.tsx +29 -0
- package/src/components/chat/skins/gemini.tsx +322 -0
- package/src/components/chat/skins/grok-icon.tsx +34 -0
- package/src/components/chat/skins/grok.tsx +369 -0
- package/src/components/chat/skins/index.ts +46 -0
- package/src/components/chat/skins/perplexity.tsx +462 -0
- package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
- package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
- package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
- package/src/components/chat/skins/react-ink.tsx +97 -0
- package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
- package/src/components/chat/skins/thread-skin-view.tsx +156 -0
- package/src/components/chat/skins/thread-skins.ts +143 -0
- package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
- package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
- package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
- package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
- package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
- package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
- package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
- package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
- package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
- package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
- package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
- package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
- package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
- package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
- package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
- package/src/components/chat/stock/SOURCE.md +90 -0
- package/src/components/chat/stock/artifacts-panel.tsx +305 -0
- package/src/components/chat/stock/attachment.aui.tsx +280 -0
- package/src/components/chat/stock/chat-notice.tsx +143 -0
- package/src/components/chat/stock/chat-private-mode.tsx +64 -0
- package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
- package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
- package/src/components/chat/stock/file.tsx +265 -0
- package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
- package/src/components/chat/stock/image.tsx +531 -0
- package/src/components/chat/stock/index.ts +129 -0
- package/src/components/chat/stock/json-view.tsx +140 -0
- package/src/components/chat/stock/markdown-text.tsx +319 -0
- package/src/components/chat/stock/message-error.aui.tsx +96 -0
- package/src/components/chat/stock/message-export-menu.tsx +156 -0
- package/src/components/chat/stock/palette-row-preview.tsx +26 -0
- package/src/components/chat/stock/reasoning.aui.tsx +120 -0
- package/src/components/chat/stock/reasoning.tsx +335 -0
- package/src/components/chat/stock/skin-chrome.tsx +81 -0
- package/src/components/chat/stock/skin-credit.tsx +63 -0
- package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
- package/src/components/chat/stock/skin-palette-context.ts +16 -0
- package/src/components/chat/stock/skin-runtime.tsx +52 -0
- package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
- package/src/components/chat/stock/skin-types.ts +217 -0
- package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
- package/src/components/chat/stock/stock-send-gate.tsx +94 -0
- package/src/components/chat/stock/stock-shape.tsx +39 -0
- package/src/components/chat/stock/thread.aui.tsx +645 -0
- package/src/components/chat/stock/tool-display.ts +6 -0
- package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
- package/src/components/chat/stock/tool-group.aui.tsx +244 -0
- package/src/components/chat/stock/tool-surface.ts +120 -0
- package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
- package/src/components/chat/stock/ui/avatar.tsx +108 -0
- package/src/components/chat/stock/ui/button.tsx +81 -0
- package/src/components/chat/stock/ui/collapsible.tsx +21 -0
- package/src/components/chat/stock/ui/dialog.tsx +163 -0
- package/src/components/chat/stock/ui/skeleton.tsx +13 -0
- package/src/components/chat/stock/ui/textarea.tsx +20 -0
- package/src/components/chat/stock/ui/tooltip.tsx +68 -0
- package/src/components/chat/stock/use-attachment-src.ts +42 -0
- package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
- package/src/components/chat/strip-model-boilerplate.ts +42 -0
- package/src/components/chat/suggestion-cycle.tsx +230 -0
- package/src/components/chat/suggestion-scroll-row.tsx +81 -0
- package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
- package/src/components/chat/trace-grouping/chain-state.ts +141 -0
- package/src/components/chat/trace-grouping/index.ts +32 -0
- package/src/components/chat/trace-grouping/tool-row.ts +74 -0
- package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
- package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
- package/src/components/chat/trace-i18n/core.ts +48 -0
- package/src/components/chat/trace-i18n/index.tsx +23 -0
- package/src/components/chat/trace-i18n/locales/en.ts +24 -0
- package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
- package/src/components/chat/trace-i18n/types.ts +35 -0
- package/src/components/chat/trace-spacing.ts +249 -0
- package/src/components/chat/transcript/activity-view.ts +375 -0
- package/src/components/chat/transcript/chat-export.ts +133 -0
- package/src/components/chat/transcript/index.ts +10 -0
- package/src/components/chat/transcript/save-file.ts +209 -0
- package/src/components/chat/transcript/transcript-markdown.ts +428 -0
- package/src/components/chat/transcript/types.ts +81 -0
- package/src/components/chat/turn-outcome.ts +52 -0
- package/src/components/chat/use-warmup-phase.ts +18 -0
- package/src/components/chat/work-status-lead.tsx +49 -0
- package/src/components/chrome.tsx +264 -0
- package/src/components/command-palette/CommandPalette.tsx +404 -0
- package/src/components/command-palette/index.ts +6 -0
- package/src/components/contact/ContactMailto.tsx +112 -0
- package/src/components/contact/index.ts +5 -0
- package/src/components/conviction/ConvictionMeter.tsx +40 -0
- package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
- package/src/components/conviction/index.ts +7 -0
- package/src/components/data-layout/BentoGrid.tsx +52 -0
- package/src/components/data-layout/CardRail.tsx +150 -0
- package/src/components/data-layout/DotMatrixStat.tsx +65 -0
- package/src/components/data-layout/FeatureCell.tsx +80 -0
- package/src/components/data-layout/MediaFrame.tsx +125 -0
- package/src/components/data-layout/ModuleGrid.tsx +735 -0
- package/src/components/data-layout/Odometer.tsx +149 -0
- package/src/components/data-layout/ProductFrame.tsx +79 -0
- package/src/components/data-layout/TestimonialWall.tsx +139 -0
- package/src/components/data-layout/index.ts +19 -0
- package/src/components/data-layout/treemap.ts +368 -0
- package/src/components/deck/DeckStack.tsx +243 -0
- package/src/components/desk/DataTable.tsx +373 -0
- package/src/components/desk/KpiGrid.tsx +80 -0
- package/src/components/desk/Sparkline.tsx +63 -0
- package/src/components/desk/StateBlock.tsx +132 -0
- package/src/components/desk/index.ts +18 -0
- package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
- package/src/components/diagrams/ArchitectureTour.tsx +912 -0
- package/src/components/diagrams/TerminalSchematic.tsx +192 -0
- package/src/components/diagrams/architecture-svg.tsx +384 -0
- package/src/components/diagrams/index.ts +30 -0
- package/src/components/diagrams/mermaid-theme.ts +115 -0
- package/src/components/diagrams/tour-camera.ts +171 -0
- package/src/components/docs/CodeTabs.tsx +90 -0
- package/src/components/docs/CopyCommand.tsx +151 -0
- package/src/components/docs/DocsLayout.tsx +197 -0
- package/src/components/docs/DocsSearch.tsx +97 -0
- package/src/components/docs/Endpoint.tsx +135 -0
- package/src/components/document/DocumentFrame.tsx +43 -0
- package/src/components/document/GlyphList.tsx +51 -0
- package/src/components/document/PageTitle.tsx +44 -0
- package/src/components/document/Prose.tsx +38 -0
- package/src/components/document/Section.tsx +55 -0
- package/src/components/document/index.ts +13 -0
- package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
- package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
- package/src/components/effects-chrome/Pipeline.tsx +226 -0
- package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
- package/src/components/effects-chrome/StackingPanels.tsx +101 -0
- package/src/components/effects-chrome/TabStrip.tsx +232 -0
- package/src/components/effects-chrome/ToastStack.tsx +201 -0
- package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
- package/src/components/effects-chrome/index.ts +35 -0
- package/src/components/emblems.tsx +188 -0
- package/src/components/faviconTheme.ts +23 -0
- package/src/components/figure/Figure.tsx +38 -0
- package/src/components/figure/index.ts +2 -0
- package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
- package/src/components/finance-charts/EquityCurve.tsx +71 -0
- package/src/components/finance-charts/PriceChart.tsx +119 -0
- package/src/components/finance-charts/chart-host.tsx +236 -0
- package/src/components/finance-charts/chart-scale.ts +93 -0
- package/src/components/finance-charts/demo-data.ts +88 -0
- package/src/components/finance-charts/index.ts +46 -0
- package/src/components/finance-charts/lw-chart.tsx +292 -0
- package/src/components/finance-composites/MarketBar.tsx +243 -0
- package/src/components/finance-composites/OrderBook.tsx +133 -0
- package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
- package/src/components/finance-composites/SortableTable.tsx +144 -0
- package/src/components/finance-composites/StockTicker.tsx +65 -0
- package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
- package/src/components/finance-composites/index.ts +28 -0
- package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
- package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
- package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
- package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
- package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
- package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
- package/src/components/finance-tearsheet/charts.tsx +2624 -0
- package/src/components/finance-tearsheet/demo-data.ts +177 -0
- package/src/components/finance-tearsheet/format.ts +41 -0
- package/src/components/finance-tearsheet/index.ts +120 -0
- package/src/components/finance-tearsheet/print.ts +52 -0
- package/src/components/finance-tearsheet/risk-bands.ts +48 -0
- package/src/components/finance-tearsheet/stats.ts +35 -0
- package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
- package/src/components/finance-tearsheet/types.ts +58 -0
- package/src/components/footer/FooterCells.tsx +109 -0
- package/src/components/footer/index.ts +6 -0
- package/src/components/graph.tsx +158 -0
- package/src/components/icons.tsx +98 -0
- package/src/components/landing/PixelWordmark.tsx +36 -0
- package/src/components/logos.ts +39 -0
- package/src/components/marquee/Marquee.tsx +204 -0
- package/src/components/metrics/PerfMetrics.tsx +68 -0
- package/src/components/metrics/StatCounter.tsx +104 -0
- package/src/components/page-geometry.tsx +177 -0
- package/src/components/pricing/Pricing.tsx +174 -0
- package/src/components/pricing/PricingMatrix.tsx +219 -0
- package/src/components/prose/index.ts +2 -0
- package/src/components/prose/prose.tsx +86 -0
- package/src/components/repo-activity/RepoActivity.tsx +599 -0
- package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
- package/src/components/repo-activity/demo.ts +201 -0
- package/src/components/repo-activity/fetch.ts +211 -0
- package/src/components/repo-activity/heatmap.ts +123 -0
- package/src/components/repo-activity/index.ts +28 -0
- package/src/components/repo-activity/types.ts +99 -0
- package/src/components/stages/NumberedStages.tsx +116 -0
- package/src/components/symbols/marks.tsx +116 -0
- package/src/components/symbols/terminal-lockup.tsx +136 -0
- package/src/components/symbols/terminal-marks.tsx +226 -0
- package/src/components/terminal/ChatResponseLoader.tsx +67 -0
- package/src/components/terminal/ContainerBootLoader.tsx +82 -0
- package/src/components/terminal/TerminalStepCaret.tsx +202 -0
- package/src/components/themeInit.ts +24 -0
- package/src/components/typography/MotionReveal.tsx +108 -0
- package/src/components/typography/TypewriterReveal.tsx +101 -0
- package/src/components/typography/WordReveal.tsx +143 -0
- package/src/data/modules.ts +378 -0
- package/src/data/subsystems.ts +101 -0
- package/src/index.ts +587 -0
- package/src/lib/base-path.ts +60 -0
- package/src/lib/cx.ts +25 -0
- package/src/lib/gloomberb.ts +69 -0
- package/src/lib/record.ts +19 -0
- package/src/lib/stub-payload.ts +183 -0
- package/src/lib/useBodyScrollLock.ts +44 -0
- package/src/lib/utils.ts +6 -0
- package/src/motion/primitives.tsx +105 -0
- package/src/motion/scroll-glide.ts +62 -0
- package/src/motion/scrolly-core.ts +38 -0
- package/src/motion/scrolly.tsx +95 -0
- package/src/navigation/HashScrollManager.tsx +167 -0
- package/src/navigation/hashScroll.ts +78 -0
- package/src/replay/browser.ts +280 -0
- package/src/replay/chat-export-run.ts +121 -0
- package/src/replay/export-format.ts +25 -0
- package/src/replay/export-mount.ts +32 -0
- package/src/replay/filename.ts +54 -0
- package/src/replay/index.ts +21 -0
- package/src/replay/redact-dom.ts +178 -0
- package/src/replay/redact.ts +113 -0
- package/src/replay/snapshot.ts +659 -0
- package/src/styles/account-auth.css +339 -0
- package/src/styles/brand-wordmark.css +11 -0
- package/src/styles/card-rail.css +120 -0
- package/src/styles/chat-aui.css +1143 -0
- package/src/styles/chat-core.css +469 -0
- package/src/styles/chat-digichat.css +2531 -0
- package/src/styles/chat-math.css +70 -0
- package/src/styles/chat-skin-palette.css +138 -0
- package/src/styles/chat-stock-menu.css +37 -0
- package/src/styles/chat-widgets.css +190 -0
- package/src/styles/command-palette.css +372 -0
- package/src/styles/controls-core.css +2261 -0
- package/src/styles/controls-overlay.css +603 -0
- package/src/styles/data-layout.css +288 -0
- package/src/styles/deck.css +141 -0
- package/src/styles/diagrams.css +1860 -0
- package/src/styles/digichat-app-theme.css +250 -0
- package/src/styles/digichat-boot-loader.css +487 -0
- package/src/styles/digichat-launcher.css +377 -0
- package/src/styles/docs.css +165 -0
- package/src/styles/effects-chrome.css +888 -0
- package/src/styles/finance-composites.css +214 -0
- package/src/styles/finance-tearsheet-overlay.css +90 -0
- package/src/styles/finance-tearsheet.css +945 -0
- package/src/styles/marquee.css +168 -0
- package/src/styles/metrics.css +82 -0
- package/src/styles/nav-shell.css +551 -0
- package/src/styles/pricing.css +79 -0
- package/src/styles/repo-activity.css +575 -0
- package/src/styles/stages.css +69 -0
- package/src/styles/terminal-loaders.css +122 -0
- package/src/styles/terminal-manifest.css +228 -0
- package/src/styles/web-theme.css +1007 -0
- package/src/styles/word-reveal.css +204 -0
- package/src/theme/apply-theme.ts +214 -0
- package/src/theme/index.ts +27 -0
- package/src/theme/palette-registry.ts +855 -0
- package/src/theme/tui-prefs.ts +64 -0
- package/src/ui/alert.tsx +78 -0
- package/src/ui/avatar.tsx +104 -0
- package/src/ui/badge.tsx +75 -0
- package/src/ui/breadcrumb.tsx +61 -0
- package/src/ui/button.tsx +67 -0
- package/src/ui/card.tsx +139 -0
- package/src/ui/checkbox.tsx +27 -0
- package/src/ui/collapsible.tsx +32 -0
- package/src/ui/date-pager.tsx +325 -0
- package/src/ui/dialog.tsx +157 -0
- package/src/ui/dropdown-menu.tsx +267 -0
- package/src/ui/empty-state.tsx +165 -0
- package/src/ui/field.tsx +104 -0
- package/src/ui/form.tsx +36 -0
- package/src/ui/icon-button.tsx +36 -0
- package/src/ui/index.ts +34 -0
- package/src/ui/input.tsx +33 -0
- package/src/ui/kbd.tsx +30 -0
- package/src/ui/label.tsx +32 -0
- package/src/ui/pager.tsx +119 -0
- package/src/ui/pagination.tsx +126 -0
- package/src/ui/radio-group.tsx +51 -0
- package/src/ui/search-bar.tsx +85 -0
- package/src/ui/segmented-control.tsx +76 -0
- package/src/ui/select.tsx +257 -0
- package/src/ui/separator.tsx +24 -0
- package/src/ui/sheet.tsx +141 -0
- package/src/ui/skeleton.tsx +76 -0
- package/src/ui/slider.tsx +76 -0
- package/src/ui/switch.tsx +31 -0
- package/src/ui/table.tsx +179 -0
- package/src/ui/tabs.tsx +89 -0
- package/src/ui/tags-input.tsx +168 -0
- package/src/ui/textarea.tsx +17 -0
- package/src/ui/tooltip.tsx +71 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState, type ReactNode } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { AnimatePresence, m, useReducedMotion } from "motion/react";
|
|
6
|
+
import { Button } from "../../ui";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* ToastStack — the corner notification stack promoted from the design
|
|
10
|
+
* reference (chrome/toasts), as an imperative-free, props-driven primitive:
|
|
11
|
+
* the APP owns the toast list (push/update/remove in its own state — there is
|
|
12
|
+
* no global toast() singleton here) and passes `toasts` + `onDismiss`. The
|
|
13
|
+
* stack renders them sliding in at the corner; a toast with `ttlMs` retires
|
|
14
|
+
* itself on a watchable drain timer (the component fires `onDismiss(id)` at
|
|
15
|
+
* expiry — remove it from state there), one without holds open (the pending /
|
|
16
|
+
* spinner case) and resolves in place when the app swaps its tone and ttl.
|
|
17
|
+
*
|
|
18
|
+
* Status rides the up/down reads (success/error), never a livery. Reduced
|
|
19
|
+
* motion drops the slide and the progress bar but keeps the toast (ttl
|
|
20
|
+
* dismissal still runs). Renders into a document.body portal by default
|
|
21
|
+
* (mount-gated, so SSR/hydration are safe); `portal={false}` renders in
|
|
22
|
+
* place for contained demos.
|
|
23
|
+
*
|
|
24
|
+
* Wiring (in the consuming app):
|
|
25
|
+
* globals.css @import "@digithings-ai/ui/styles/effects-chrome.css";
|
|
26
|
+
* @source "<path-to>/packages/ui/src/components/effects-chrome";
|
|
27
|
+
*/
|
|
28
|
+
export type ToastTone = "success" | "error" | "info" | "loading";
|
|
29
|
+
|
|
30
|
+
export type ToastItem = {
|
|
31
|
+
id: string | number;
|
|
32
|
+
tone: ToastTone;
|
|
33
|
+
/** Mono headline — "Backtest complete". */
|
|
34
|
+
title: string;
|
|
35
|
+
/** Optional detail line — "PF 2.31 · saved to vault". */
|
|
36
|
+
message?: string;
|
|
37
|
+
/** Auto-dismiss after this many ms; omit or 0 to hold open. */
|
|
38
|
+
ttlMs?: number;
|
|
39
|
+
/** Optional one-click recovery control — e.g. "Reissue" on an
|
|
40
|
+
* expired-token error toast that names a fix but otherwise has no way to
|
|
41
|
+
* let the user actually perform it. Renders as a small text button under
|
|
42
|
+
* the message; omit for the current text-only rendering. */
|
|
43
|
+
action?: { label: string; onClick: () => void };
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type ToastStackProps = {
|
|
47
|
+
toasts: ToastItem[];
|
|
48
|
+
/** Remove the toast from app state — fired by the ✕ and by ttl expiry. */
|
|
49
|
+
onDismiss: (id: ToastItem["id"]) => void;
|
|
50
|
+
/** Render into a document.body portal (default) or in place. */
|
|
51
|
+
portal?: boolean;
|
|
52
|
+
ariaLabel?: string;
|
|
53
|
+
className?: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const ICONS: Record<ToastTone, ReactNode> = {
|
|
57
|
+
success: <path d="M5 12.5l4.5 4.5L19 7" />,
|
|
58
|
+
error: <path d="M12 8v5M12 16.5v.5M12 3l9 16H3z" />,
|
|
59
|
+
info: <path d="M12 11v6M12 7.5v.5" />,
|
|
60
|
+
loading: <path d="M12 4a8 8 0 1 0 8 8" />,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function ToastStack({
|
|
64
|
+
toasts,
|
|
65
|
+
onDismiss,
|
|
66
|
+
portal = true,
|
|
67
|
+
ariaLabel = "Notifications",
|
|
68
|
+
className,
|
|
69
|
+
}: ToastStackProps) {
|
|
70
|
+
const reduced = useReducedMotion();
|
|
71
|
+
const [mounted, setMounted] = useState(false);
|
|
72
|
+
const timers = useRef<Map<ToastItem["id"], { ttl: number; timer: number }>>(new Map());
|
|
73
|
+
const onDismissRef = useRef(onDismiss);
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
onDismissRef.current = onDismiss;
|
|
77
|
+
}, [onDismiss]);
|
|
78
|
+
|
|
79
|
+
useEffect(() => setMounted(true), []);
|
|
80
|
+
|
|
81
|
+
// Arm/re-arm ttl timers declaratively: a toast whose ttl changed (the
|
|
82
|
+
// loading → success resolve-in-place move) gets a fresh timer; departed
|
|
83
|
+
// toasts get theirs cleared.
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const map = timers.current;
|
|
86
|
+
const live = new Set(toasts.map((t) => t.id));
|
|
87
|
+
for (const [id, entry] of map) {
|
|
88
|
+
if (!live.has(id)) {
|
|
89
|
+
window.clearTimeout(entry.timer);
|
|
90
|
+
map.delete(id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const t of toasts) {
|
|
94
|
+
const ttl = t.ttlMs ?? 0;
|
|
95
|
+
const entry = map.get(t.id);
|
|
96
|
+
if (entry && entry.ttl === ttl) continue;
|
|
97
|
+
if (entry) window.clearTimeout(entry.timer);
|
|
98
|
+
if (ttl > 0) {
|
|
99
|
+
map.set(t.id, {
|
|
100
|
+
ttl,
|
|
101
|
+
timer: window.setTimeout(() => {
|
|
102
|
+
map.delete(t.id);
|
|
103
|
+
onDismissRef.current(t.id);
|
|
104
|
+
}, ttl),
|
|
105
|
+
});
|
|
106
|
+
} else {
|
|
107
|
+
map.delete(t.id);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, [toasts]);
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
const map = timers.current;
|
|
114
|
+
return () => {
|
|
115
|
+
map.forEach((entry) => window.clearTimeout(entry.timer));
|
|
116
|
+
map.clear();
|
|
117
|
+
};
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
const stack = (
|
|
121
|
+
<div
|
|
122
|
+
className={`toast-stack${className ? ` ${className}` : ""}`}
|
|
123
|
+
role="region"
|
|
124
|
+
aria-label={ariaLabel}
|
|
125
|
+
aria-live="polite"
|
|
126
|
+
>
|
|
127
|
+
<AnimatePresence initial={false}>
|
|
128
|
+
{toasts.map((t) => (
|
|
129
|
+
<m.div
|
|
130
|
+
key={t.id}
|
|
131
|
+
className={`toast toast-${t.tone}`}
|
|
132
|
+
initial={reduced ? { opacity: 0 } : { opacity: 0, x: 40, scale: 0.96 }}
|
|
133
|
+
animate={reduced ? { opacity: 1 } : { opacity: 1, x: 0, scale: 1 }}
|
|
134
|
+
exit={reduced ? { opacity: 0 } : { opacity: 0, x: 40, scale: 0.96 }}
|
|
135
|
+
transition={{ duration: 0.26 }}
|
|
136
|
+
>
|
|
137
|
+
<span className="toast-icon" aria-hidden="true">
|
|
138
|
+
<svg
|
|
139
|
+
viewBox="0 0 24 24"
|
|
140
|
+
width="16"
|
|
141
|
+
height="16"
|
|
142
|
+
fill="none"
|
|
143
|
+
stroke="currentColor"
|
|
144
|
+
strokeWidth="1.8"
|
|
145
|
+
strokeLinecap="round"
|
|
146
|
+
strokeLinejoin="round"
|
|
147
|
+
className={t.tone === "loading" ? "toast-spin" : undefined}
|
|
148
|
+
>
|
|
149
|
+
{ICONS[t.tone]}
|
|
150
|
+
</svg>
|
|
151
|
+
</span>
|
|
152
|
+
<div className="toast-body">
|
|
153
|
+
<p className="toast-title">{t.title}</p>
|
|
154
|
+
{t.message ? <p className="toast-msg">{t.message}</p> : null}
|
|
155
|
+
{t.action ? (
|
|
156
|
+
<Button
|
|
157
|
+
type="button"
|
|
158
|
+
variant="ghost"
|
|
159
|
+
className="toast-action h-auto inline-block border-0 bg-transparent p-0 text-[0.74rem] font-normal hover:bg-transparent hover:text-ink"
|
|
160
|
+
onClick={t.action.onClick}
|
|
161
|
+
>
|
|
162
|
+
{t.action.label}
|
|
163
|
+
</Button>
|
|
164
|
+
) : null}
|
|
165
|
+
</div>
|
|
166
|
+
<Button
|
|
167
|
+
type="button"
|
|
168
|
+
variant="ghost"
|
|
169
|
+
className="toast-close h-auto w-auto border-0 bg-transparent p-[0.15rem] hover:bg-transparent"
|
|
170
|
+
aria-label="Dismiss"
|
|
171
|
+
onClick={() => onDismiss(t.id)}
|
|
172
|
+
>
|
|
173
|
+
<svg
|
|
174
|
+
viewBox="0 0 24 24"
|
|
175
|
+
width="13"
|
|
176
|
+
height="13"
|
|
177
|
+
fill="none"
|
|
178
|
+
stroke="currentColor"
|
|
179
|
+
strokeWidth="1.8"
|
|
180
|
+
strokeLinecap="round"
|
|
181
|
+
>
|
|
182
|
+
<path d="M6 6l12 12M18 6L6 18" />
|
|
183
|
+
</svg>
|
|
184
|
+
</Button>
|
|
185
|
+
{t.ttlMs && !reduced ? (
|
|
186
|
+
<span
|
|
187
|
+
className="toast-progress"
|
|
188
|
+
style={{ animationDuration: `${t.ttlMs}ms` }}
|
|
189
|
+
aria-hidden="true"
|
|
190
|
+
/>
|
|
191
|
+
) : null}
|
|
192
|
+
</m.div>
|
|
193
|
+
))}
|
|
194
|
+
</AnimatePresence>
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
if (!portal) return stack;
|
|
199
|
+
if (!mounted) return null;
|
|
200
|
+
return createPortal(stack, document.body);
|
|
201
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure geometry for HorizontalScrollTrack — framework-free so it unit-tests
|
|
3
|
+
* without a DOM (the component wraps these with refs, observers and motion
|
|
4
|
+
* values). All x values are "distance the track has travelled left, in px".
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** The pin is active only at this width and up (with motion allowed). */
|
|
8
|
+
export const TRACK_MIN_WIDTH = 960;
|
|
9
|
+
|
|
10
|
+
/** Clamp a number into [lo, hi]. */
|
|
11
|
+
export function clamp(n: number, lo: number, hi: number): number {
|
|
12
|
+
return Math.min(hi, Math.max(lo, n));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** How far the track must travel: its content width minus the viewport. */
|
|
16
|
+
export function trackTravel(contentWidth: number, viewportWidth: number): number {
|
|
17
|
+
return Math.max(0, contentWidth - viewportWidth);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The runway's height: the pin's own height plus the horizontal travel, so one
|
|
22
|
+
* px of vertical scroll is exactly one px of horizontal travel and the runway
|
|
23
|
+
* always tracks the content width (the #1198 lesson — never a hardcoded vh).
|
|
24
|
+
*/
|
|
25
|
+
export function runwayHeight(pinHeight: number, travel: number): number {
|
|
26
|
+
return Math.round(pinHeight + travel);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Index of the item whose leading edge is nearest `x` (offsets ascending). */
|
|
30
|
+
export function nearestIndex(offsets: readonly number[], x: number): number {
|
|
31
|
+
if (offsets.length === 0) return 0;
|
|
32
|
+
let best = 0;
|
|
33
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
34
|
+
offsets.forEach((offset, i) => {
|
|
35
|
+
const d = Math.abs(offset - x);
|
|
36
|
+
if (d < bestDistance) {
|
|
37
|
+
bestDistance = d;
|
|
38
|
+
best = i;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return best;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Where the track should travel to so a focused item is revealed, or null when
|
|
46
|
+
* it is already fully inside the viewport (no scroll needed).
|
|
47
|
+
*/
|
|
48
|
+
export function focusTargetX(args: {
|
|
49
|
+
itemLeft: number;
|
|
50
|
+
itemWidth: number;
|
|
51
|
+
currentX: number;
|
|
52
|
+
viewportWidth: number;
|
|
53
|
+
travel: number;
|
|
54
|
+
}): number | null {
|
|
55
|
+
const { itemLeft, itemWidth, currentX, viewportWidth, travel } = args;
|
|
56
|
+
const visible = itemLeft >= currentX && itemLeft + itemWidth <= currentX + viewportWidth;
|
|
57
|
+
if (visible) return null;
|
|
58
|
+
return clamp(itemLeft, 0, travel);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Document scrollTop that puts the track at travel `x` (1px : 1px). */
|
|
62
|
+
export function scrollTopForX(args: {
|
|
63
|
+
runwayTopInDocument: number;
|
|
64
|
+
pinTop: number;
|
|
65
|
+
x: number;
|
|
66
|
+
travel: number;
|
|
67
|
+
}): number {
|
|
68
|
+
const { runwayTopInDocument, pinTop, x, travel } = args;
|
|
69
|
+
return runwayTopInDocument - pinTop + clamp(x, 0, travel);
|
|
70
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* effects-chrome family barrel — scroll set pieces + site-chrome primitives
|
|
3
|
+
* promoted from the design reference (#1450): Pipeline, RotatingPrompts,
|
|
4
|
+
* StackingPanels, AnnouncementBar, TabStrip, ToastStack.
|
|
5
|
+
*
|
|
6
|
+
* Structural CSS for the whole family ships in styles/effects-chrome.css
|
|
7
|
+
* (one sheet, imported plainly — it manages its own layering).
|
|
8
|
+
*/
|
|
9
|
+
export {
|
|
10
|
+
Pipeline,
|
|
11
|
+
type PipelineProps,
|
|
12
|
+
type PipelineColumn,
|
|
13
|
+
type PipelineNode,
|
|
14
|
+
type PipelineStatus,
|
|
15
|
+
type PipelineSummaryItem,
|
|
16
|
+
} from "./Pipeline";
|
|
17
|
+
export { RotatingPrompts, type RotatingPromptsProps } from "./RotatingPrompts";
|
|
18
|
+
export { StackingPanels, type StackingPanelsProps, type StackingPanel } from "./StackingPanels";
|
|
19
|
+
export { AnnouncementBar, type AnnouncementBarProps } from "./AnnouncementBar";
|
|
20
|
+
export {
|
|
21
|
+
TabStrip,
|
|
22
|
+
tabBaseId,
|
|
23
|
+
tabId,
|
|
24
|
+
tabPanelId,
|
|
25
|
+
type TabStripProps,
|
|
26
|
+
type TabItem,
|
|
27
|
+
} from "./TabStrip";
|
|
28
|
+
export {
|
|
29
|
+
HorizontalScrollTrack,
|
|
30
|
+
HorizontalTrackStepper,
|
|
31
|
+
useHorizontalTrack,
|
|
32
|
+
type HorizontalScrollTrackProps,
|
|
33
|
+
type HorizontalTrackState,
|
|
34
|
+
} from "./HorizontalScrollTrack";
|
|
35
|
+
export { ToastStack, type ToastStackProps, type ToastItem, type ToastTone } from "./ToastStack";
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module emblem family — one modern visual grammar across modules. Each mark
|
|
3
|
+
* is a single geometric idea representing what the module does, drawn on a
|
|
4
|
+
* 0 0 32 32 grid (centered at 16,16). The grammar is dual-tone but single-hue:
|
|
5
|
+
* a monoline silhouette in `currentColor`, one soft `currentColor` tint layer
|
|
6
|
+
* (fillOpacity ~0.15) for figure/ground depth, and at most one solid accent
|
|
7
|
+
* detail for focus. The `Emblem` wrapper sets `currentColor` to the module's
|
|
8
|
+
* own accent token, so each renders in its own colour while the set stays
|
|
9
|
+
* cohesive.
|
|
10
|
+
*/
|
|
11
|
+
import { type SVGProps } from "react";
|
|
12
|
+
|
|
13
|
+
type P = { size?: number } & SVGProps<SVGSVGElement>;
|
|
14
|
+
const Svg = ({ size = 32, children, ...rest }: P & { children: React.ReactNode }) => (
|
|
15
|
+
<svg
|
|
16
|
+
width={size}
|
|
17
|
+
height={size}
|
|
18
|
+
viewBox="0 0 32 32"
|
|
19
|
+
fill="none"
|
|
20
|
+
stroke="currentColor"
|
|
21
|
+
strokeWidth={2}
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
aria-hidden="true"
|
|
25
|
+
{...rest}
|
|
26
|
+
>
|
|
27
|
+
<g transform="translate(16 16)">{children}</g>
|
|
28
|
+
</svg>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
/** Soft same-hue fill for the depth layer — figure/ground without a 2nd colour. */
|
|
32
|
+
const TINT = 0.15;
|
|
33
|
+
|
|
34
|
+
// orchestration — a supervisor hub branching to three specialist nodes
|
|
35
|
+
const DigiGraph = (p: P) => (
|
|
36
|
+
<Svg {...p}>
|
|
37
|
+
<path d="M0 -6 -9 8M0 -6 0 8M0 -6 9 8" />
|
|
38
|
+
<circle cx="0" cy="-6" r="5.4" fill="currentColor" fillOpacity={TINT} stroke="none" />
|
|
39
|
+
<circle cx="0" cy="-6" r="4.4" fill="currentColor" stroke="none" />
|
|
40
|
+
<circle cx="-9" cy="9" r="2.7" />
|
|
41
|
+
<circle cx="0" cy="9" r="2.7" />
|
|
42
|
+
<circle cx="9" cy="9" r="2.7" />
|
|
43
|
+
</Svg>
|
|
44
|
+
);
|
|
45
|
+
// quant — ascending candlesticks with wicks, the leader filled (research → order)
|
|
46
|
+
const DigiQuant = (p: P) => (
|
|
47
|
+
<Svg {...p}>
|
|
48
|
+
<path d="M-9.5 0v13" />
|
|
49
|
+
<rect x="-12" y="3" width="5" height="9" rx="1.6" fill="currentColor" fillOpacity={TINT} />
|
|
50
|
+
<path d="M0 -7v19" />
|
|
51
|
+
<rect x="-2.5" y="-2" width="5" height="13" rx="1.6" fill="currentColor" fillOpacity={TINT} />
|
|
52
|
+
<path d="M9.5 -13v26" />
|
|
53
|
+
<rect x="7" y="-9" width="5" height="20" rx="1.6" fill="currentColor" stroke="none" />
|
|
54
|
+
</Svg>
|
|
55
|
+
);
|
|
56
|
+
// retrieval — a lens over a focal point (vector search)
|
|
57
|
+
const DigiSearch = (p: P) => (
|
|
58
|
+
<Svg {...p}>
|
|
59
|
+
<circle cx="-3" cy="-3" r="9.5" fill="currentColor" fillOpacity={TINT} />
|
|
60
|
+
<path d="M4.5 4.5 12.5 12.5" />
|
|
61
|
+
<circle cx="-3" cy="-3" r="2.6" fill="currentColor" stroke="none" />
|
|
62
|
+
</Svg>
|
|
63
|
+
);
|
|
64
|
+
// chat — a terminal prompt: a chevron and a solid block cursor (no bubble)
|
|
65
|
+
const DigiChat = (p: P) => (
|
|
66
|
+
<Svg {...p}>
|
|
67
|
+
<path d="M-9 -5.5 -2 0 -9 5.5" />
|
|
68
|
+
<rect x="2" y="-5" width="6.5" height="10" rx="1" fill="currentColor" stroke="none" />
|
|
69
|
+
</Svg>
|
|
70
|
+
);
|
|
71
|
+
// auth — a rounded key: soft-filled bow, notched shaft
|
|
72
|
+
const DigiKey = (p: P) => (
|
|
73
|
+
<Svg {...p}>
|
|
74
|
+
<circle cx="-6" cy="-6" r="6" fill="currentColor" fillOpacity={TINT} />
|
|
75
|
+
<circle cx="-6" cy="-6" r="2.2" fill="currentColor" stroke="none" />
|
|
76
|
+
<path d="M-1.7 -1.7 11 11M6.5 6.5 10.5 2.5M9 9 13 5" />
|
|
77
|
+
</Svg>
|
|
78
|
+
);
|
|
79
|
+
// observability — a trace waterfall, the lead span filled
|
|
80
|
+
const DigiTrace = (p: P) => (
|
|
81
|
+
<Svg {...p}>
|
|
82
|
+
<rect x="-13" y="-11" width="15" height="5" rx="2.5" fill="currentColor" stroke="none" />
|
|
83
|
+
<rect
|
|
84
|
+
x="-6"
|
|
85
|
+
y="-2.5"
|
|
86
|
+
width="19"
|
|
87
|
+
height="5"
|
|
88
|
+
rx="2.5"
|
|
89
|
+
fill="currentColor"
|
|
90
|
+
fillOpacity={TINT}
|
|
91
|
+
/>
|
|
92
|
+
<rect x="-10" y="6" width="12" height="5" rx="2.5" fill="currentColor" fillOpacity={TINT} />
|
|
93
|
+
</Svg>
|
|
94
|
+
);
|
|
95
|
+
// runtime — a heartbeat sealed in a ring (always-on, on an interval)
|
|
96
|
+
const DigiBot = (p: P) => (
|
|
97
|
+
<Svg {...p}>
|
|
98
|
+
<circle cx="0" cy="0" r="12" fill="currentColor" fillOpacity={TINT} />
|
|
99
|
+
<path d="M-8.5 0 -4 0 -1.5 -6 1.5 6 4 0 8.5 0" />
|
|
100
|
+
</Svg>
|
|
101
|
+
);
|
|
102
|
+
// library — stacked layers on a filled foundation (what everything builds on)
|
|
103
|
+
const DigiBase = (p: P) => (
|
|
104
|
+
<Svg {...p}>
|
|
105
|
+
<rect x="-13" y="-11.5" width="26" height="5.2" rx="2" fill="currentColor" fillOpacity={TINT} />
|
|
106
|
+
<rect x="-13" y="-3.5" width="26" height="5.2" rx="2" fill="currentColor" fillOpacity={TINT} />
|
|
107
|
+
<rect x="-13" y="4.5" width="26" height="5.2" rx="2" fill="currentColor" stroke="none" />
|
|
108
|
+
</Svg>
|
|
109
|
+
);
|
|
110
|
+
// storage (roadmap) — a database cylinder with a soft-filled cap
|
|
111
|
+
const DigiStore = (p: P) => (
|
|
112
|
+
<Svg {...p}>
|
|
113
|
+
<path
|
|
114
|
+
d="M-12 -9v18c0 2 5.4 3.5 12 3.5s12 -1.5 12 -3.5V-9"
|
|
115
|
+
fill="currentColor"
|
|
116
|
+
fillOpacity={TINT}
|
|
117
|
+
/>
|
|
118
|
+
<ellipse cx="0" cy="-9" rx="12" ry="3.5" fill="currentColor" fillOpacity={TINT} />
|
|
119
|
+
<path d="M-12 0c0 2 5.4 3.5 12 3.5s12 -1.5 12 -3.5" />
|
|
120
|
+
</Svg>
|
|
121
|
+
);
|
|
122
|
+
// markdown vault — a closed folio with a clasp: notes bound and secured
|
|
123
|
+
const DigiVault = (p: P) => (
|
|
124
|
+
<Svg {...p}>
|
|
125
|
+
<rect x="-10" y="-12" width="20" height="24" rx="3" fill="currentColor" fillOpacity={TINT} />
|
|
126
|
+
<path d="M-4 -12v24" />
|
|
127
|
+
<path d="M1 -5h5M1 1h5" />
|
|
128
|
+
<rect x="7" y="-3" width="6" height="6" rx="1.5" fill="currentColor" stroke="none" />
|
|
129
|
+
</Svg>
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// link (roadmap) — two interlocking chain links, one tinted (protocol bridge)
|
|
133
|
+
const DigiLink = (p: P) => (
|
|
134
|
+
<Svg {...p}>
|
|
135
|
+
<rect x="-13" y="-5.5" width="15" height="11" rx="5.5" fill="currentColor" fillOpacity={TINT} />
|
|
136
|
+
<rect x="-2" y="-5.5" width="15" height="11" rx="5.5" />
|
|
137
|
+
</Svg>
|
|
138
|
+
);
|
|
139
|
+
// research — research scheduler: a globe with meridian + equator
|
|
140
|
+
const research = (p: P) => (
|
|
141
|
+
<Svg {...p}>
|
|
142
|
+
<circle cx="0" cy="0" r="12" fill="currentColor" fillOpacity={TINT} />
|
|
143
|
+
<path d="M0 -12a5 12 0 0 0 0 24a5 12 0 0 0 0 -24" />
|
|
144
|
+
<path d="M-12 0 12 0" />
|
|
145
|
+
</Svg>
|
|
146
|
+
);
|
|
147
|
+
// portfolio — signal messenger: a paper-plane send mark, filled
|
|
148
|
+
const portfolio = (p: P) => (
|
|
149
|
+
<Svg {...p}>
|
|
150
|
+
<path
|
|
151
|
+
d="M13 -12 -12 -1 -1 3 3 12 13 -12z"
|
|
152
|
+
fill="currentColor"
|
|
153
|
+
fillOpacity={TINT}
|
|
154
|
+
/>
|
|
155
|
+
<path d="M13 -12 -1 3" />
|
|
156
|
+
<circle cx="-1" cy="3" r="1.7" fill="currentColor" stroke="none" />
|
|
157
|
+
</Svg>
|
|
158
|
+
);
|
|
159
|
+
// execution — execution timing: a clock, one tick struck to mark the moment
|
|
160
|
+
const execution = (p: P) => (
|
|
161
|
+
<Svg {...p}>
|
|
162
|
+
<circle cx="0" cy="0" r="12" fill="currentColor" fillOpacity={TINT} />
|
|
163
|
+
<path d="M0 -12 0 -9" stroke="currentColor" strokeWidth="2.6" />
|
|
164
|
+
<path d="M0 0 0 -6.5M0 0 4.5 2.5" />
|
|
165
|
+
<circle cx="0" cy="0" r="1.7" fill="currentColor" stroke="none" />
|
|
166
|
+
</Svg>
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
export const emblems: Record<string, (p: P) => React.ReactNode> = {
|
|
170
|
+
digigraph: DigiGraph, digiquant: DigiQuant, digisearch: DigiSearch, digichat: DigiChat,
|
|
171
|
+
digikey: DigiKey, digitrace: DigiTrace, digibot: DigiBot, digibase: DigiBase,
|
|
172
|
+
digivault: DigiVault,
|
|
173
|
+
digistore: DigiStore, digilink: DigiLink,
|
|
174
|
+
research: research, portfolio: portfolio, execution: execution,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export function Emblem({ id, size = 32, className }: { id: string; size?: number; className?: string }) {
|
|
178
|
+
const E = emblems[id];
|
|
179
|
+
if (!E) return null;
|
|
180
|
+
// Per-module accent (--accent-<id>, defined at :root in tokens.css), falling back
|
|
181
|
+
// to the page accent. The platform accent is neutralized on digithings.ai, but the
|
|
182
|
+
// per-module tokens keep their colour, so emblems carry the module's own hue.
|
|
183
|
+
return (
|
|
184
|
+
<span className={className} style={{ display: "inline-flex", color: `var(--accent-${id}, var(--accent))` }}>
|
|
185
|
+
{E({ size })}
|
|
186
|
+
</span>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swap the tab icon to the painted theme.
|
|
3
|
+
*
|
|
4
|
+
* `prefers-color-scheme` on `<link rel="icon">` follows the OS, not the
|
|
5
|
+
* site's `data-theme`. An SVG favicon also cannot read the page's theme.
|
|
6
|
+
* This script runs after the theme init and again whenever `data-theme`
|
|
7
|
+
* changes, and it rewrites the icon links the document already has.
|
|
8
|
+
*
|
|
9
|
+
* Baked light and dark files are required: a favicon does not inherit
|
|
10
|
+
* `currentColor` from the page.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type FaviconThemePaths = {
|
|
14
|
+
dark: string;
|
|
15
|
+
light: string;
|
|
16
|
+
touchDark: string;
|
|
17
|
+
touchLight: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function faviconThemeScript(paths: FaviconThemePaths): string {
|
|
21
|
+
const spec = JSON.stringify(paths);
|
|
22
|
+
return `try{var P=${spec};function applyFavicon(){var light=document.documentElement.getAttribute("data-theme")==="light";var icon=light?P.light:P.dark;var touch=light?P.touchLight:P.touchDark;document.querySelectorAll('link[rel="icon"],link[rel="shortcut icon"]').forEach(function(el){var type=el.getAttribute("type")||"";var href=el.getAttribute("href")||"";if(type==="image/svg+xml"||href.indexOf(".svg")!==-1){el.removeAttribute("media");el.setAttribute("href",icon);}});document.querySelectorAll('link[rel="apple-touch-icon"]').forEach(function(el){el.removeAttribute("media");el.setAttribute("href",touch);});}applyFavicon();new MutationObserver(applyFavicon).observe(document.documentElement,{attributes:true,attributeFilter:["data-theme"]});if(document.head){new MutationObserver(applyFavicon).observe(document.head,{childList:true});}}catch(e){}`;
|
|
23
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { cn } from "../../lib/utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Figure — the numbered `Fig N` figure grammar (D1, #4429): a `<figure>` whose
|
|
6
|
+
* content (a metric strip, a media block, a diagram) carries a mono
|
|
7
|
+
* `<figcaption>` that leads with `Fig <n>` in the accent tone. The opencode.ai
|
|
8
|
+
* language numbers its stat blocks this way, and both the landing metrics band
|
|
9
|
+
* and the quality page's counted figures use it.
|
|
10
|
+
*
|
|
11
|
+
* Generic on purpose: pass any content as `children`, the caption as `caption`,
|
|
12
|
+
* and the number/label as `n` (`1`, `2`, `"3a"` …). `n` is caller-controlled
|
|
13
|
+
* rather than auto-sequenced so a page can keep its own order explicit.
|
|
14
|
+
*
|
|
15
|
+
* Server component — no hooks, no state.
|
|
16
|
+
*/
|
|
17
|
+
export type FigureProps = {
|
|
18
|
+
/** The label rendered as `Fig <n>`. Caller-ordered. */
|
|
19
|
+
n: number | string;
|
|
20
|
+
/** The caption text after the `Fig <n>` label. */
|
|
21
|
+
caption: ReactNode;
|
|
22
|
+
/** The figure content — a stat strip, media block, diagram … */
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function Figure({ n, caption, children, className }: FigureProps) {
|
|
28
|
+
return (
|
|
29
|
+
<figure className={cn("m-0 grid gap-[0.7rem]", className)}>
|
|
30
|
+
{children}
|
|
31
|
+
<figcaption className="font-mono text-[0.72rem] leading-[1.5] text-ink-mute">
|
|
32
|
+
<span className="text-accent">Fig {n}</span>
|
|
33
|
+
<span aria-hidden="true"> — </span>
|
|
34
|
+
{caption}
|
|
35
|
+
</figcaption>
|
|
36
|
+
</figure>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DrawdownPlot — the underwater curve promoted from the design reference
|
|
5
|
+
* (finance/drawdown): percent below the running peak as a baseline series on
|
|
6
|
+
* TradingView Lightweight Charts, hanging under a zero baseline. It only
|
|
7
|
+
* ever reads negative, so it takes the `--down` money color — the depth and
|
|
8
|
+
* duration of the red is the risk story the CAGR hides. Re-themes live on
|
|
9
|
+
* `data-theme` flips.
|
|
10
|
+
*
|
|
11
|
+
* Data comes in via the required `data` prop (ISO-dated points, ascending,
|
|
12
|
+
* every value ≤ 0); `DRAWDOWN_DEMO` is the exported reference filler. The
|
|
13
|
+
* host fills its pane (`autoSize`) — give the pane a definite height.
|
|
14
|
+
* Client component — chart lifecycle effect; no motion/react surface.
|
|
15
|
+
*
|
|
16
|
+
* Wiring (consuming app): `lightweight-charts` dependency, plus
|
|
17
|
+
* globals.css @source "<path-to>/packages/ui/src/components/finance-charts";
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { useCallback } from "react";
|
|
21
|
+
import { BaselineSeries, type BaselineData, type IChartApi } from "lightweight-charts";
|
|
22
|
+
import {
|
|
23
|
+
toChartTime,
|
|
24
|
+
tokenAlpha,
|
|
25
|
+
useFinanceChart,
|
|
26
|
+
type FinanceChartPalette,
|
|
27
|
+
type FinanceSeriesPoint,
|
|
28
|
+
} from "./chart-host";
|
|
29
|
+
|
|
30
|
+
export type DrawdownPlotProps = {
|
|
31
|
+
/** Drawdown-% series (values ≤ 0), ISO `yyyy-mm-dd` ascending. */
|
|
32
|
+
data: FinanceSeriesPoint[];
|
|
33
|
+
/** Extra classes on the chart host (it is `h-full w-full` by default). */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Accessible name; omitted → decorative (`aria-hidden`). */
|
|
36
|
+
label?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function DrawdownPlot({ data, className, label }: DrawdownPlotProps) {
|
|
40
|
+
const setup = useCallback(
|
|
41
|
+
(chart: IChartApi, p: FinanceChartPalette) => {
|
|
42
|
+
const series = chart.addSeries(BaselineSeries, {
|
|
43
|
+
baseValue: { type: "price", price: 0 },
|
|
44
|
+
topLineColor: "transparent",
|
|
45
|
+
topFillColor1: "transparent",
|
|
46
|
+
topFillColor2: "transparent",
|
|
47
|
+
bottomLineColor: p.down,
|
|
48
|
+
bottomFillColor1: tokenAlpha(p.down, 0.05),
|
|
49
|
+
bottomFillColor2: tokenAlpha(p.down, 0.32),
|
|
50
|
+
lineWidth: 2,
|
|
51
|
+
priceLineVisible: false,
|
|
52
|
+
});
|
|
53
|
+
series.setData(
|
|
54
|
+
data.map((pt): BaselineData => ({ time: toChartTime(pt.time), value: pt.value }))
|
|
55
|
+
);
|
|
56
|
+
return (next: FinanceChartPalette) => {
|
|
57
|
+
series.applyOptions({
|
|
58
|
+
bottomLineColor: next.down,
|
|
59
|
+
bottomFillColor1: tokenAlpha(next.down, 0.05),
|
|
60
|
+
bottomFillColor2: tokenAlpha(next.down, 0.32),
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
[data]
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const hostRef = useFinanceChart(setup, "down");
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div
|
|
71
|
+
ref={hostRef}
|
|
72
|
+
className={`h-full w-full${className ? ` ${className}` : ""}`}
|
|
73
|
+
{...(label ? { role: "img", "aria-label": label } : { "aria-hidden": true })}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
}
|