@heyramzi/ui 0.0.0-stage → 6.0.1
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/COMPONENTS.md +141 -0
- package/LICENSE +21 -0
- package/README.md +125 -2
- package/package.json +209 -3
- package/scripts/lib/sync-core.mjs +113 -0
- package/scripts/relative-imports.mjs +39 -0
- package/scripts/sf-symbol.mjs +93 -0
- package/scripts/sync-shadcn.mjs +341 -0
- package/scripts/sync-transitions.mjs +146 -0
- package/scripts/validate-apple-symbol-exports.mjs +45 -0
- package/src/ai/composer/Composer.css +108 -0
- package/src/ai/composer/Composer.svelte +111 -0
- package/src/ai/composer/index.ts +10 -0
- package/src/ai/confirmation/Confirmation.svelte +54 -0
- package/src/ai/confirmation/ConfirmationAccepted.svelte +23 -0
- package/src/ai/confirmation/ConfirmationAction.svelte +53 -0
- package/src/ai/confirmation/ConfirmationActions.svelte +24 -0
- package/src/ai/confirmation/ConfirmationFailed.svelte +23 -0
- package/src/ai/confirmation/ConfirmationRejected.svelte +23 -0
- package/src/ai/confirmation/ConfirmationRequest.svelte +25 -0
- package/src/ai/confirmation/ConfirmationTitle.svelte +25 -0
- package/src/ai/confirmation/confirmation-context.svelte.ts +22 -0
- package/src/ai/confirmation/index.ts +50 -0
- package/src/ai/conversation/Conversation.svelte +28 -0
- package/src/ai/conversation/ConversationContent.svelte +35 -0
- package/src/ai/conversation/ConversationEmptyState.svelte +46 -0
- package/src/ai/conversation/ConversationScrollButton.svelte +51 -0
- package/src/ai/conversation/index.ts +33 -0
- package/src/ai/conversation/stick-to-bottom-context.svelte.ts +131 -0
- package/src/ai/index.ts +119 -0
- package/src/ai/loading-state/PixelLoader.svelte +138 -0
- package/src/ai/loading-state/index.ts +5 -0
- package/src/ai/prompt-input/PromptInput.svelte +38 -0
- package/src/ai/prompt-input/PromptInputBody.svelte +19 -0
- package/src/ai/prompt-input/PromptInputSubmit.svelte +73 -0
- package/src/ai/prompt-input/PromptInputTextarea.svelte +74 -0
- package/src/ai/prompt-input/PromptInputToolbar.svelte +19 -0
- package/src/ai/prompt-input/index.ts +34 -0
- package/src/ai/reasoning/Reasoning.svelte +47 -0
- package/src/ai/reasoning/ReasoningContent.svelte +27 -0
- package/src/ai/reasoning/ReasoningTrigger.svelte +48 -0
- package/src/ai/reasoning/index.ts +22 -0
- package/src/ai/reasoning/reasoning-context.svelte.ts +20 -0
- package/src/ai/response/Response.css +32 -0
- package/src/ai/response/Response.svelte +130 -0
- package/src/ai/response/index.ts +5 -0
- package/src/ai/suggestion/Suggestion.svelte +43 -0
- package/src/ai/suggestion/Suggestions.svelte +25 -0
- package/src/ai/suggestion/index.ts +14 -0
- package/src/ai/thinking-dots/ThinkingDots.svelte +42 -0
- package/src/ai/thinking-dots/index.ts +5 -0
- package/src/ai/typing-dots/TypingDots.css +39 -0
- package/src/ai/typing-dots/TypingDots.svelte +27 -0
- package/src/ai/typing-dots/index.ts +10 -0
- package/src/ai/voice-waveform/VoiceWaveform.css +40 -0
- package/src/ai/voice-waveform/VoiceWaveform.svelte +46 -0
- package/src/ai/voice-waveform/index.ts +5 -0
- package/src/animations/README.md +84 -0
- package/src/animations/accordion.css +58 -0
- package/src/animations/avatar-group-hover.css +47 -0
- package/src/animations/card-tilt.css +74 -0
- package/src/animations/digit-pop-in.css +78 -0
- package/src/animations/dropdown.css +121 -0
- package/src/animations/icon-swap.css +43 -0
- package/src/animations/index.css +34 -0
- package/src/animations/input-clear-dissolve.css +86 -0
- package/src/animations/input-shake.css +114 -0
- package/src/animations/learn-more-hover.css +48 -0
- package/src/animations/like-button.css +93 -0
- package/src/animations/modal.css +75 -0
- package/src/animations/notification-badge.css +81 -0
- package/src/animations/page-side-by-side.css +63 -0
- package/src/animations/panel.css +86 -0
- package/src/animations/plus-menu-morph.css +97 -0
- package/src/animations/reasoning-stream.css +49 -0
- package/src/animations/resize.css +20 -0
- package/src/animations/shimmer-text.css +72 -0
- package/src/animations/skeleton-reveal.css +97 -0
- package/src/animations/spinning-counter.css +52 -0
- package/src/animations/streaming-text.css +31 -0
- package/src/animations/success-check.css +120 -0
- package/src/animations/tabs-sliding.css +83 -0
- package/src/animations/text-swap.css +40 -0
- package/src/animations/text-swap.ts +40 -0
- package/src/animations/texts-reveal.css +70 -0
- package/src/animations/thinking-states.css +65 -0
- package/src/animations/tooltip.css +72 -0
- package/src/animations/upstream-coverage.test.ts +65 -0
- package/src/animations/view-transition-reveal.ts +74 -0
- package/src/charts/animated-value.css +7 -0
- package/src/charts/animated-value.svelte +110 -0
- package/src/charts/area-chart.css +29 -0
- package/src/charts/area-chart.svelte +195 -0
- package/src/charts/bar-chart.css +119 -0
- package/src/charts/bar-chart.svelte +269 -0
- package/src/charts/charts.css +201 -0
- package/src/charts/crosshair.svelte +35 -0
- package/src/charts/donut-chart.css +56 -0
- package/src/charts/donut-chart.svelte +158 -0
- package/src/charts/edge-fade.svelte +43 -0
- package/src/charts/edge-fade.ts +16 -0
- package/src/charts/figure.css +100 -0
- package/src/charts/figure.svelte +122 -0
- package/src/charts/gauge-chart.css +94 -0
- package/src/charts/gauge-chart.svelte +303 -0
- package/src/charts/hover-band.test.ts +30 -0
- package/src/charts/hover-band.ts +21 -0
- package/src/charts/hover-focus.svelte +85 -0
- package/src/charts/index.ts +30 -0
- package/src/charts/legend.css +131 -0
- package/src/charts/legend.svelte +112 -0
- package/src/charts/line-chart.css +26 -0
- package/src/charts/line-chart.svelte +256 -0
- package/src/charts/motion.ts +19 -0
- package/src/charts/number-chart.css +168 -0
- package/src/charts/number-chart.svelte +177 -0
- package/src/charts/primitives/chart-container.svelte +57 -0
- package/src/charts/primitives/chart-style.svelte +36 -0
- package/src/charts/primitives/chart-tooltip.svelte +161 -0
- package/src/charts/primitives/chart-utils.ts +54 -0
- package/src/charts/primitives/index.ts +11 -0
- package/src/charts/reveal.svelte +61 -0
- package/src/charts/ring-chart.css +96 -0
- package/src/charts/ring-chart.svelte +158 -0
- package/src/charts/sparkline.css +45 -0
- package/src/charts/sparkline.svelte +140 -0
- package/src/charts/stat-card.css +103 -0
- package/src/charts/stat-card.svelte +267 -0
- package/src/charts/time-series-chart.css +28 -0
- package/src/charts/time-series-chart.svelte +179 -0
- package/src/charts/trend-pill.css +38 -0
- package/src/charts/trend-pill.svelte +48 -0
- package/src/design/index.css +270 -0
- package/src/design/polish.css +159 -0
- package/src/effects/animated-beam/AnimatedBeam.svelte +132 -0
- package/src/effects/animated-beam/diagrams/BeamSvg.svelte +91 -0
- package/src/effects/animated-beam/index.ts +2 -0
- package/src/effects/animated-beam/path-calculator.svelte.ts +70 -0
- package/src/effects/animated-beam/types.ts +23 -0
- package/src/effects/border-beam/BorderBeam.svelte +223 -0
- package/src/effects/border-beam/css.test.ts +46 -0
- package/src/effects/border-beam/css.ts +574 -0
- package/src/effects/border-beam/presets.ts +699 -0
- package/src/effects/border-beam/register-properties.test.ts +74 -0
- package/src/effects/border-beam/register-properties.ts +73 -0
- package/src/effects/border-beam/types.ts +38 -0
- package/src/effects/image-comparison/ImageComparison.css +66 -0
- package/src/effects/image-comparison/ImageComparison.svelte +92 -0
- package/src/effects/image-reveal/ImageReveal.css +10 -0
- package/src/effects/image-reveal/ImageReveal.svelte +357 -0
- package/src/effects/image-reveal/index.ts +2 -0
- package/src/effects/image-reveal/types.ts +35 -0
- package/src/effects/magnetic/magnetic.ts +81 -0
- package/src/effects/marquee/Marquee.css +52 -0
- package/src/effects/marquee/Marquee.svelte +96 -0
- package/src/effects/progressive-blur/ProgressiveBlur.css +9 -0
- package/src/effects/progressive-blur/ProgressiveBlur.svelte +63 -0
- package/src/effects/reveal/AnimatedGroup.svelte +101 -0
- package/src/effects/reveal/InView.svelte +77 -0
- package/src/effects/reveal/TextEffect.svelte +142 -0
- package/src/effects/reveal/index.ts +10 -0
- package/src/effects/reveal/observe.ts +33 -0
- package/src/effects/reveal/reveal.css +141 -0
- package/src/effects/reveal/types.ts +25 -0
- package/src/effects/shader-gradient/ShaderGradient.svelte +227 -0
- package/src/effects/shader-gradient/color.ts +44 -0
- package/src/effects/shader-gradient/index.ts +5 -0
- package/src/effects/shader-gradient/renderer.ts +456 -0
- package/src/effects/shader-gradient/shaders.ts +324 -0
- package/src/effects/shader-gradient/types.ts +68 -0
- package/src/effects/spotlight/Spotlight.css +14 -0
- package/src/effects/spotlight/Spotlight.svelte +61 -0
- package/src/effects/theme-toggle/ThemeToggle.css +21 -0
- package/src/effects/theme-toggle/ThemeToggle.svelte +101 -0
- package/src/icons/TradeIcon.svelte +16 -0
- package/src/icons/apple-symbol-exports.ts +135 -0
- package/src/icons/sf-symbols.ts +527 -0
- package/src/icons/trades.ts +89 -0
- package/src/index.ts +49 -0
- package/src/lib/arrive.ts +26 -0
- package/src/lib/hooks/is-mobile.svelte.ts +11 -0
- package/src/lib/icon-types.ts +17 -0
- package/src/lib/layout.ts +8 -0
- package/src/lib/panel.ts +15 -0
- package/src/lib/theme-transition.ts +51 -0
- package/src/lib/utils.ts +45 -0
- package/src/shadcn/accordion/accordion-content.svelte +22 -0
- package/src/shadcn/accordion/accordion-item.svelte +17 -0
- package/src/shadcn/accordion/accordion-trigger.svelte +35 -0
- package/src/shadcn/accordion/accordion.svelte +19 -0
- package/src/shadcn/accordion/index.ts +16 -0
- package/src/shadcn/alert/alert-description.svelte +23 -0
- package/src/shadcn/alert/alert-title.svelte +20 -0
- package/src/shadcn/alert/alert.svelte +44 -0
- package/src/shadcn/alert/index.ts +14 -0
- package/src/shadcn/alert-dialog/alert-dialog-action.svelte +18 -0
- package/src/shadcn/alert-dialog/alert-dialog-cancel.svelte +18 -0
- package/src/shadcn/alert-dialog/alert-dialog-content.svelte +29 -0
- package/src/shadcn/alert-dialog/alert-dialog-description.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-footer.svelte +20 -0
- package/src/shadcn/alert-dialog/alert-dialog-header.svelte +20 -0
- package/src/shadcn/alert-dialog/alert-dialog-overlay.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-portal.svelte +7 -0
- package/src/shadcn/alert-dialog/alert-dialog-title.svelte +17 -0
- package/src/shadcn/alert-dialog/alert-dialog-trigger.svelte +7 -0
- package/src/shadcn/alert-dialog/alert-dialog.svelte +7 -0
- package/src/shadcn/alert-dialog/index.ts +37 -0
- package/src/shadcn/attachment/attachment-action.svelte +23 -0
- package/src/shadcn/attachment/attachment-actions.svelte +23 -0
- package/src/shadcn/attachment/attachment-content.svelte +23 -0
- package/src/shadcn/attachment/attachment-description.svelte +23 -0
- package/src/shadcn/attachment/attachment-group.svelte +23 -0
- package/src/shadcn/attachment/attachment-media.svelte +44 -0
- package/src/shadcn/attachment/attachment-title.svelte +23 -0
- package/src/shadcn/attachment/attachment-trigger.svelte +29 -0
- package/src/shadcn/attachment/attachment.svelte +55 -0
- package/src/shadcn/attachment/index.ts +40 -0
- package/src/shadcn/avatar/avatar-badge.svelte +26 -0
- package/src/shadcn/avatar/avatar-fallback.svelte +20 -0
- package/src/shadcn/avatar/avatar-group-count.svelte +23 -0
- package/src/shadcn/avatar/avatar-group.svelte +23 -0
- package/src/shadcn/avatar/avatar-image.svelte +17 -0
- package/src/shadcn/avatar/avatar.svelte +26 -0
- package/src/shadcn/avatar/index.ts +22 -0
- package/src/shadcn/badge/badge.svelte +53 -0
- package/src/shadcn/badge/index.ts +2 -0
- package/src/shadcn/breadcrumb/breadcrumb-ellipsis.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-item.svelte +20 -0
- package/src/shadcn/breadcrumb/breadcrumb-link.svelte +31 -0
- package/src/shadcn/breadcrumb/breadcrumb-list.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-page.svelte +23 -0
- package/src/shadcn/breadcrumb/breadcrumb-separator.svelte +27 -0
- package/src/shadcn/breadcrumb/breadcrumb.svelte +21 -0
- package/src/shadcn/breadcrumb/index.ts +25 -0
- package/src/shadcn/bubble/bubble-content.svelte +31 -0
- package/src/shadcn/bubble/bubble-group.svelte +20 -0
- package/src/shadcn/bubble/bubble-reactions.svelte +52 -0
- package/src/shadcn/bubble/bubble.svelte +58 -0
- package/src/shadcn/bubble/index.ts +25 -0
- package/src/shadcn/button/button.svelte +121 -0
- package/src/shadcn/button/index.ts +17 -0
- package/src/shadcn/calendar/calendar-caption.svelte +76 -0
- package/src/shadcn/calendar/calendar-cell.svelte +19 -0
- package/src/shadcn/calendar/calendar-day.svelte +35 -0
- package/src/shadcn/calendar/calendar-grid-body.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-head.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid-row.svelte +12 -0
- package/src/shadcn/calendar/calendar-grid.svelte +16 -0
- package/src/shadcn/calendar/calendar-head-cell.svelte +19 -0
- package/src/shadcn/calendar/calendar-header.svelte +19 -0
- package/src/shadcn/calendar/calendar-heading.svelte +16 -0
- package/src/shadcn/calendar/calendar-month-select.svelte +44 -0
- package/src/shadcn/calendar/calendar-month.svelte +15 -0
- package/src/shadcn/calendar/calendar-months.svelte +19 -0
- package/src/shadcn/calendar/calendar-nav.svelte +19 -0
- package/src/shadcn/calendar/calendar-next-button.svelte +31 -0
- package/src/shadcn/calendar/calendar-prev-button.svelte +31 -0
- package/src/shadcn/calendar/calendar-year-select.svelte +43 -0
- package/src/shadcn/calendar/calendar.svelte +118 -0
- package/src/shadcn/calendar/index.ts +40 -0
- package/src/shadcn/card/card-action.svelte +23 -0
- package/src/shadcn/card/card-content.svelte +20 -0
- package/src/shadcn/card/card-description.svelte +20 -0
- package/src/shadcn/card/card-footer.svelte +23 -0
- package/src/shadcn/card/card-header.svelte +23 -0
- package/src/shadcn/card/card-title.svelte +29 -0
- package/src/shadcn/card/card.svelte +25 -0
- package/src/shadcn/card/index.ts +25 -0
- package/src/shadcn/checkbox/checkbox.svelte +38 -0
- package/src/shadcn/checkbox/index.ts +6 -0
- package/src/shadcn/collapsible/collapsible-content.svelte +7 -0
- package/src/shadcn/collapsible/collapsible-trigger.svelte +7 -0
- package/src/shadcn/collapsible/collapsible.svelte +11 -0
- package/src/shadcn/collapsible/index.ts +13 -0
- package/src/shadcn/command/command-dialog.svelte +66 -0
- package/src/shadcn/command/command-empty.svelte +17 -0
- package/src/shadcn/command/command-group.svelte +40 -0
- package/src/shadcn/command/command-input.svelte +64 -0
- package/src/shadcn/command/command-item.svelte +37 -0
- package/src/shadcn/command/command-link-item.svelte +20 -0
- package/src/shadcn/command/command-list.svelte +20 -0
- package/src/shadcn/command/command-loading.svelte +7 -0
- package/src/shadcn/command/command-separator.svelte +17 -0
- package/src/shadcn/command/command-shortcut.svelte +23 -0
- package/src/shadcn/command/command.svelte +28 -0
- package/src/shadcn/command/index.ts +37 -0
- package/src/shadcn/context-menu/context-menu-checkbox-item.svelte +41 -0
- package/src/shadcn/context-menu/context-menu-content.svelte +28 -0
- package/src/shadcn/context-menu/context-menu-group-heading.svelte +21 -0
- package/src/shadcn/context-menu/context-menu-group.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-item.svelte +27 -0
- package/src/shadcn/context-menu/context-menu-label.svelte +27 -0
- package/src/shadcn/context-menu/context-menu-portal.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-radio-group.svelte +16 -0
- package/src/shadcn/context-menu/context-menu-radio-item.svelte +35 -0
- package/src/shadcn/context-menu/context-menu-separator.svelte +17 -0
- package/src/shadcn/context-menu/context-menu-shortcut.svelte +23 -0
- package/src/shadcn/context-menu/context-menu-sub-content.svelte +25 -0
- package/src/shadcn/context-menu/context-menu-sub-trigger.svelte +29 -0
- package/src/shadcn/context-menu/context-menu-sub.svelte +7 -0
- package/src/shadcn/context-menu/context-menu-trigger.svelte +17 -0
- package/src/shadcn/context-menu/context-menu.svelte +7 -0
- package/src/shadcn/context-menu/index.ts +52 -0
- package/src/shadcn/dialog/dialog-close.svelte +11 -0
- package/src/shadcn/dialog/dialog-content.svelte +57 -0
- package/src/shadcn/dialog/dialog-description.svelte +20 -0
- package/src/shadcn/dialog/dialog-footer.svelte +32 -0
- package/src/shadcn/dialog/dialog-header.svelte +20 -0
- package/src/shadcn/dialog/dialog-overlay.svelte +20 -0
- package/src/shadcn/dialog/dialog-portal.svelte +7 -0
- package/src/shadcn/dialog/dialog-title.svelte +17 -0
- package/src/shadcn/dialog/dialog-trigger.svelte +11 -0
- package/src/shadcn/dialog/dialog.svelte +7 -0
- package/src/shadcn/dialog/index.ts +34 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +31 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-item.svelte +29 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-label.svelte +27 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-radio-item.svelte +34 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-shortcut.svelte +23 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/src/shadcn/dropdown-menu/dropdown-menu.svelte +7 -0
- package/src/shadcn/dropdown-menu/index.ts +56 -0
- package/src/shadcn/dropdown-menu/menu-item.ts +43 -0
- package/src/shadcn/empty/empty-content.svelte +23 -0
- package/src/shadcn/empty/empty-description.svelte +23 -0
- package/src/shadcn/empty/empty-header.svelte +20 -0
- package/src/shadcn/empty/empty-media.svelte +41 -0
- package/src/shadcn/empty/empty-title.svelte +20 -0
- package/src/shadcn/empty/empty.svelte +23 -0
- package/src/shadcn/empty/index.ts +22 -0
- package/src/shadcn/field/field-content.svelte +20 -0
- package/src/shadcn/field/field-description.svelte +25 -0
- package/src/shadcn/field/field-error.svelte +58 -0
- package/src/shadcn/field/field-group.svelte +23 -0
- package/src/shadcn/field/field-label.svelte +26 -0
- package/src/shadcn/field/field-legend.svelte +29 -0
- package/src/shadcn/field/field-separator.svelte +35 -0
- package/src/shadcn/field/field-set.svelte +24 -0
- package/src/shadcn/field/field-title.svelte +23 -0
- package/src/shadcn/field/field.svelte +53 -0
- package/src/shadcn/field/index.ts +33 -0
- package/src/shadcn/hooks/is-mobile.svelte.ts +9 -0
- package/src/shadcn/hover-card/hover-card-content.svelte +31 -0
- package/src/shadcn/hover-card/hover-card-portal.svelte +7 -0
- package/src/shadcn/hover-card/hover-card-trigger.svelte +7 -0
- package/src/shadcn/hover-card/hover-card.svelte +7 -0
- package/src/shadcn/hover-card/index.ts +15 -0
- package/src/shadcn/input/index.ts +9 -0
- package/src/shadcn/input/input.svelte +48 -0
- package/src/shadcn/input/secret-input.svelte +75 -0
- package/src/shadcn/input-otp/index.ts +15 -0
- package/src/shadcn/input-otp/input-otp-group.svelte +20 -0
- package/src/shadcn/input-otp/input-otp-separator.svelte +25 -0
- package/src/shadcn/input-otp/input-otp-slot.svelte +26 -0
- package/src/shadcn/input-otp/input-otp.svelte +22 -0
- package/src/shadcn/label/index.ts +7 -0
- package/src/shadcn/label/label.svelte +20 -0
- package/src/shadcn/marker/index.ts +15 -0
- package/src/shadcn/marker/marker-content.svelte +23 -0
- package/src/shadcn/marker/marker-icon.svelte +21 -0
- package/src/shadcn/marker/marker.svelte +52 -0
- package/src/shadcn/message/index.ts +22 -0
- package/src/shadcn/message/message-avatar.svelte +23 -0
- package/src/shadcn/message/message-content.svelte +23 -0
- package/src/shadcn/message/message-footer.svelte +23 -0
- package/src/shadcn/message/message-group.svelte +20 -0
- package/src/shadcn/message/message-header.svelte +23 -0
- package/src/shadcn/message/message.svelte +27 -0
- package/src/shadcn/popover/index.ts +28 -0
- package/src/shadcn/popover/popover-close.svelte +7 -0
- package/src/shadcn/popover/popover-content.svelte +38 -0
- package/src/shadcn/popover/popover-description.svelte +20 -0
- package/src/shadcn/popover/popover-header.svelte +20 -0
- package/src/shadcn/popover/popover-portal.svelte +7 -0
- package/src/shadcn/popover/popover-title.svelte +15 -0
- package/src/shadcn/popover/popover-trigger.svelte +17 -0
- package/src/shadcn/popover/popover.svelte +7 -0
- package/src/shadcn/progress/index.ts +7 -0
- package/src/shadcn/progress/progress.svelte +30 -0
- package/src/shadcn/radio-group/index.ts +10 -0
- package/src/shadcn/radio-group/radio-group-item.svelte +31 -0
- package/src/shadcn/radio-group/radio-group.svelte +19 -0
- package/src/shadcn/scroll-area/index.ts +10 -0
- package/src/shadcn/scroll-area/scroll-area-scrollbar.svelte +30 -0
- package/src/shadcn/scroll-area/scroll-area.svelte +43 -0
- package/src/shadcn/select/index.ts +37 -0
- package/src/shadcn/select/select-content.svelte +45 -0
- package/src/shadcn/select/select-group-heading.svelte +21 -0
- package/src/shadcn/select/select-group.svelte +17 -0
- package/src/shadcn/select/select-item.svelte +38 -0
- package/src/shadcn/select/select-label.svelte +20 -0
- package/src/shadcn/select/select-portal.svelte +7 -0
- package/src/shadcn/select/select-scroll-down-button.svelte +23 -0
- package/src/shadcn/select/select-scroll-up-button.svelte +23 -0
- package/src/shadcn/select/select-separator.svelte +18 -0
- package/src/shadcn/select/select-trigger.svelte +33 -0
- package/src/shadcn/select/select.svelte +11 -0
- package/src/shadcn/separator/index.ts +7 -0
- package/src/shadcn/separator/separator.svelte +23 -0
- package/src/shadcn/sheet/index.ts +34 -0
- package/src/shadcn/sheet/sheet-close.svelte +7 -0
- package/src/shadcn/sheet/sheet-content.svelte +72 -0
- package/src/shadcn/sheet/sheet-description.svelte +17 -0
- package/src/shadcn/sheet/sheet-footer.svelte +20 -0
- package/src/shadcn/sheet/sheet-header.svelte +20 -0
- package/src/shadcn/sheet/sheet-overlay.svelte +20 -0
- package/src/shadcn/sheet/sheet-portal.svelte +7 -0
- package/src/shadcn/sheet/sheet-title.svelte +17 -0
- package/src/shadcn/sheet/sheet-trigger.svelte +7 -0
- package/src/shadcn/sheet/sheet.svelte +7 -0
- package/src/shadcn/sidebar/constants.ts +6 -0
- package/src/shadcn/sidebar/context.svelte.ts +81 -0
- package/src/shadcn/sidebar/index.ts +75 -0
- package/src/shadcn/sidebar/sidebar-content.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-footer.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-action.svelte +33 -0
- package/src/shadcn/sidebar/sidebar-group-content.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-group-label.svelte +33 -0
- package/src/shadcn/sidebar/sidebar-group.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-header.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-input.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-inset.svelte +23 -0
- package/src/shadcn/sidebar/sidebar-menu-action.svelte +37 -0
- package/src/shadcn/sidebar/sidebar-menu-badge.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-menu-button.svelte +103 -0
- package/src/shadcn/sidebar/sidebar-menu-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-skeleton.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +39 -0
- package/src/shadcn/sidebar/sidebar-menu-sub-item.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-menu-sub.svelte +24 -0
- package/src/shadcn/sidebar/sidebar-menu.svelte +21 -0
- package/src/shadcn/sidebar/sidebar-provider.svelte +62 -0
- package/src/shadcn/sidebar/sidebar-rail.svelte +36 -0
- package/src/shadcn/sidebar/sidebar-separator.svelte +19 -0
- package/src/shadcn/sidebar/sidebar-trigger.svelte +37 -0
- package/src/shadcn/sidebar/sidebar.svelte +109 -0
- package/src/shadcn/skeleton/index.ts +7 -0
- package/src/shadcn/skeleton/skeleton.svelte +17 -0
- package/src/shadcn/slider/index.ts +7 -0
- package/src/shadcn/slider/slider.svelte +52 -0
- package/src/shadcn/sonner/index.ts +1 -0
- package/src/shadcn/sonner/sonner.svelte +34 -0
- package/src/shadcn/spinner/index.ts +1 -0
- package/src/shadcn/spinner/spinner.svelte +26 -0
- package/src/shadcn/switch/index.ts +7 -0
- package/src/shadcn/switch/switch.svelte +31 -0
- package/src/shadcn/table/index.ts +28 -0
- package/src/shadcn/table/table-body.svelte +20 -0
- package/src/shadcn/table/table-caption.svelte +20 -0
- package/src/shadcn/table/table-cell.svelte +20 -0
- package/src/shadcn/table/table-footer.svelte +20 -0
- package/src/shadcn/table/table-head.svelte +23 -0
- package/src/shadcn/table/table-header.svelte +20 -0
- package/src/shadcn/table/table-row.svelte +23 -0
- package/src/shadcn/table/table.svelte +25 -0
- package/src/shadcn/tabs/index.ts +16 -0
- package/src/shadcn/tabs/tabs-content.svelte +17 -0
- package/src/shadcn/tabs/tabs-list.svelte +25 -0
- package/src/shadcn/tabs/tabs-trigger.svelte +20 -0
- package/src/shadcn/tabs/tabs.svelte +19 -0
- package/src/shadcn/textarea/index.ts +7 -0
- package/src/shadcn/textarea/textarea.svelte +23 -0
- package/src/shadcn/toggle/index.ts +13 -0
- package/src/shadcn/toggle/toggle.svelte +53 -0
- package/src/shadcn/toggle-group/index.ts +10 -0
- package/src/shadcn/toggle-group/toggle-group-item.svelte +35 -0
- package/src/shadcn/toggle-group/toggle-group.svelte +59 -0
- package/src/shadcn/tooltip/context.ts +16 -0
- package/src/shadcn/tooltip/index.ts +19 -0
- package/src/shadcn/tooltip/tooltip-content.svelte +38 -0
- package/src/shadcn/tooltip/tooltip-portal.svelte +7 -0
- package/src/shadcn/tooltip/tooltip-provider.svelte +16 -0
- package/src/shadcn/tooltip/tooltip-trigger.svelte +7 -0
- package/src/shadcn/tooltip/tooltip.svelte +19 -0
- package/src/shadcn/utilities.css +549 -0
- package/src/showcase/AiSection.svelte +157 -0
- package/src/showcase/AnimationsSection.svelte +1658 -0
- package/src/showcase/ChartsSection.svelte +458 -0
- package/src/showcase/EffectsSection.svelte +152 -0
- package/src/showcase/ShadcnSection.svelte +27 -0
- package/src/showcase/ShowcaseImport.svelte +126 -0
- package/src/showcase/ShowcaseList.svelte +132 -0
- package/src/showcase/ShowcaseNav.svelte +247 -0
- package/src/showcase/ShowcaseSection.svelte +112 -0
- package/src/showcase/ShowcaseShell.svelte +55 -0
- package/src/showcase/ShowcaseStage.svelte +342 -0
- package/src/showcase/ShowcaseVariant.svelte +109 -0
- package/src/showcase/assets/image-reveal/art-1.jpg +0 -0
- package/src/showcase/assets/image-reveal/art-2.jpg +0 -0
- package/src/showcase/assets/image-reveal/art-3.jpg +0 -0
- package/src/showcase/check.svg +1 -0
- package/src/showcase/chevron-arms.svg +2 -0
- package/src/showcase/chevron-down.svg +1 -0
- package/src/showcase/copy.svg +2 -0
- package/src/showcase/demos/ai/confirmation.svelte +59 -0
- package/src/showcase/demos/ai/conversation.svelte +59 -0
- package/src/showcase/demos/ai/loading-state.svelte +19 -0
- package/src/showcase/demos/ai/prompt-input.svelte +57 -0
- package/src/showcase/demos/ai/reasoning.svelte +19 -0
- package/src/showcase/demos/ai/thinking-dots.svelte +15 -0
- package/src/showcase/demos/ai/voice-waveform.svelte +24 -0
- package/src/showcase/demos/effects/animated-beam.svelte +50 -0
- package/src/showcase/demos/effects/animated-group.svelte +47 -0
- package/src/showcase/demos/effects/border-beam-default.svelte +20 -0
- package/src/showcase/demos/effects/border-beam-line.svelte +20 -0
- package/src/showcase/demos/effects/border-beam-mono.svelte +20 -0
- package/src/showcase/demos/effects/border-beam-sunset.svelte +20 -0
- package/src/showcase/demos/effects/image-comparison.svelte +25 -0
- package/src/showcase/demos/effects/image-reveal.svelte +49 -0
- package/src/showcase/demos/effects/in-view.svelte +41 -0
- package/src/showcase/demos/effects/integrations-hub.svelte +82 -0
- package/src/showcase/demos/effects/magnetic.svelte +31 -0
- package/src/showcase/demos/effects/marquee.svelte +33 -0
- package/src/showcase/demos/effects/progressive-blur.svelte +47 -0
- package/src/showcase/demos/effects/spotlight.svelte +40 -0
- package/src/showcase/demos/effects/text-effect.svelte +55 -0
- package/src/showcase/demos/shadcn/accordion.svelte +45 -0
- package/src/showcase/demos/shadcn/alert-dialog.svelte +23 -0
- package/src/showcase/demos/shadcn/alert.svelte +30 -0
- package/src/showcase/demos/shadcn/attachment.svelte +71 -0
- package/src/showcase/demos/shadcn/avatar.svelte +30 -0
- package/src/showcase/demos/shadcn/badge.svelte +26 -0
- package/src/showcase/demos/shadcn/breadcrumb.svelte +34 -0
- package/src/showcase/demos/shadcn/bubble.svelte +36 -0
- package/src/showcase/demos/shadcn/button.svelte +11 -0
- package/src/showcase/demos/shadcn/calendar.svelte +8 -0
- package/src/showcase/demos/shadcn/card.svelte +39 -0
- package/src/showcase/demos/shadcn/checkbox.svelte +39 -0
- package/src/showcase/demos/shadcn/collapsible.svelte +20 -0
- package/src/showcase/demos/shadcn/command.svelte +48 -0
- package/src/showcase/demos/shadcn/context-menu.svelte +54 -0
- package/src/showcase/demos/shadcn/demo-harness.svelte +12 -0
- package/src/showcase/demos/shadcn/demos.test.ts +20 -0
- package/src/showcase/demos/shadcn/dialog.svelte +38 -0
- package/src/showcase/demos/shadcn/dropdown-menu.svelte +59 -0
- package/src/showcase/demos/shadcn/empty.svelte +29 -0
- package/src/showcase/demos/shadcn/field.svelte +115 -0
- package/src/showcase/demos/shadcn/hover-card.svelte +32 -0
- package/src/showcase/demos/shadcn/index.ts +358 -0
- package/src/showcase/demos/shadcn/input-otp.svelte +19 -0
- package/src/showcase/demos/shadcn/input.svelte +5 -0
- package/src/showcase/demos/shadcn/label.svelte +11 -0
- package/src/showcase/demos/shadcn/marker.svelte +30 -0
- package/src/showcase/demos/shadcn/message.svelte +75 -0
- package/src/showcase/demos/shadcn/popover.svelte +36 -0
- package/src/showcase/demos/shadcn/progress.svelte +13 -0
- package/src/showcase/demos/shadcn/radio-group.svelte +19 -0
- package/src/showcase/demos/shadcn/scroll-area.svelte +18 -0
- package/src/showcase/demos/shadcn/select.svelte +29 -0
- package/src/showcase/demos/shadcn/separator.svelte +12 -0
- package/src/showcase/demos/shadcn/sheet.svelte +48 -0
- package/src/showcase/demos/shadcn/skeleton.svelte +11 -0
- package/src/showcase/demos/shadcn/slider.svelte +7 -0
- package/src/showcase/demos/shadcn/sonner.svelte +18 -0
- package/src/showcase/demos/shadcn/spinner.svelte +11 -0
- package/src/showcase/demos/shadcn/switch.svelte +9 -0
- package/src/showcase/demos/shadcn/table.svelte +76 -0
- package/src/showcase/demos/shadcn/tabs.svelte +62 -0
- package/src/showcase/demos/shadcn/textarea.svelte +5 -0
- package/src/showcase/demos/shadcn/toggle-group.svelte +18 -0
- package/src/showcase/demos/shadcn/toggle.svelte +14 -0
- package/src/showcase/demos/shadcn/tooltip.svelte +13 -0
- package/src/showcase/heart.svg +1 -0
- package/src/showcase/index.ts +38 -0
- package/src/showcase/kit.test.ts +72 -0
- package/src/showcase/kit.ts +17 -0
- package/src/showcase/plus.svg +1 -0
- package/src/showcase/showcase-shell.css +91 -0
- package/src/showcase/stacked-section.css +15 -0
- package/src/showcase/success-check.svg +1 -0
- package/src/showcase/types.ts +29 -0
- package/src/svg-raw.d.ts +7 -0
- package/src/test-setup.ts +34 -0
- package/src/tokens.css +993 -0
package/src/tokens.css
ADDED
|
@@ -0,0 +1,993 @@
|
|
|
1
|
+
/* tokens.css
|
|
2
|
+
*
|
|
3
|
+
* The shared style layer for @heyramzi/ui, imported once after Tailwind:
|
|
4
|
+
*
|
|
5
|
+
* @import "tailwindcss";
|
|
6
|
+
* @import "@heyramzi/ui/tokens.css";
|
|
7
|
+
* @import "@heyramzi/ui/animations";
|
|
8
|
+
* @import "@heyramzi/ui/shadcn/utilities.css"; // only if you use Attachment or Message
|
|
9
|
+
*
|
|
10
|
+
* It carries three things: the color palette and semantic tokens, the craft
|
|
11
|
+
* layer (radius, elevation, focus and motion), and the small set of motion
|
|
12
|
+
* primitives the components share. Override any variable on :root to retheme.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
16
|
+
|
|
17
|
+
/* Font families */
|
|
18
|
+
@theme {
|
|
19
|
+
--font-sans: var(--font-satoshi), system-ui, sans-serif;
|
|
20
|
+
--font-heading: var(--font-manrope), system-ui, sans-serif;
|
|
21
|
+
--font-mono: var(--font-space-grotesk), ui-monospace, monospace;
|
|
22
|
+
--font-quote: var(--font-space-grotesk), ui-monospace, monospace;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* OKLCH Color Variables - Single source of truth for all colors */
|
|
26
|
+
/* Palette: indigo, sand and terra, with a neutral gray scale. */
|
|
27
|
+
:root {
|
|
28
|
+
color-scheme: light;
|
|
29
|
+
/* === Font Variables === */
|
|
30
|
+
/* Each consuming app defines @font-face and sets these to the actual font family names */
|
|
31
|
+
--font-satoshi: "Satoshi", system-ui, sans-serif;
|
|
32
|
+
--font-manrope: "Manrope", system-ui, sans-serif;
|
|
33
|
+
--font-space-grotesk: "Space Grotesk", ui-monospace, monospace;
|
|
34
|
+
|
|
35
|
+
/* === Core Gray Scale (7 shades, zero-chroma neutral) === */
|
|
36
|
+
--gray-50: oklch(0.98 0 0); /* Almost white — backgrounds */
|
|
37
|
+
--gray-100: oklch(0.94 0 0); /* Very light gray — subtle backgrounds */
|
|
38
|
+
--gray-200: oklch(0.92 0 0); /* Light gray — borders */
|
|
39
|
+
--gray-300: oklch(0.84 0 0); /* Muted — disabled, placeholder text */
|
|
40
|
+
--gray-500: oklch(0.65 0 0); /* Medium gray — secondary text */
|
|
41
|
+
--gray-700: oklch(0.45 0 0); /* Dark gray — body text */
|
|
42
|
+
--gray-900: oklch(0.15 0 0); /* Near-black — headings, primary text */
|
|
43
|
+
|
|
44
|
+
/* === Accent Colors (3 chromatic) — 60/30/10 split === */
|
|
45
|
+
--brand-indigo: oklch(0.5 0.2 272); /* Primary 60% — CTAs, links, active states, brand mark */
|
|
46
|
+
--brand-indigo-light: oklch(0.68 0.16 272); /* Dark mode variant */
|
|
47
|
+
--brand-sand: oklch(0.78 0.08 40); /* Warmth 30% — highlights, badges, soft accents */
|
|
48
|
+
--brand-terra: oklch(0.65 0.2 30); /* Signal 10% — warnings, attention, energy */
|
|
49
|
+
|
|
50
|
+
/* === Surface System (6 named colors) === */
|
|
51
|
+
/* Dark surfaces (indigo-tinted, h258-264) Light pendants (warm-tinted, h55) */
|
|
52
|
+
--brand-ink: oklch(0.12 0.04 258); /* Base — page background */
|
|
53
|
+
--brand-night: oklch(0.18 0.05 262); /* Surface — cards, panels ↔ Linen */
|
|
54
|
+
--brand-veil: oklch(0.28 0.06 264); /* Borders, dividers ↔ Mist */
|
|
55
|
+
--brand-dusk: oklch(0.22 0.05 262); /* Between night/veil — hover surfaces, inputs */
|
|
56
|
+
--brand-cream: oklch(0.97 0.01 55); /* On-dark text, light backgrounds */
|
|
57
|
+
--brand-linen: oklch(0.985 0.003 55); /* Light surface — cards ↔ Night */
|
|
58
|
+
--brand-mist: oklch(0.9 0.006 55); /* Light borders, dividers ↔ Veil */
|
|
59
|
+
|
|
60
|
+
/* === Indigo Tint Scale (5-step, core = 600) === */
|
|
61
|
+
--indigo-100: oklch(0.92 0.04 272);
|
|
62
|
+
--indigo-200: oklch(0.82 0.08 272);
|
|
63
|
+
--indigo-400: oklch(0.68 0.16 272);
|
|
64
|
+
--indigo-600: oklch(0.5 0.2 272); /* = --brand-indigo */
|
|
65
|
+
--indigo-800: oklch(0.34 0.18 272);
|
|
66
|
+
|
|
67
|
+
/* === Sand Tint Scale (5-step, core = 400) === */
|
|
68
|
+
--sand-100: oklch(0.94 0.02 40);
|
|
69
|
+
--sand-200: oklch(0.88 0.04 40);
|
|
70
|
+
--sand-400: oklch(0.78 0.08 40); /* = --brand-sand */
|
|
71
|
+
--sand-600: oklch(0.64 0.1 40);
|
|
72
|
+
--sand-800: oklch(0.5 0.08 40);
|
|
73
|
+
|
|
74
|
+
/* === Terra Tint Scale (5-step, core = 400) === */
|
|
75
|
+
--terra-100: oklch(0.92 0.05 30);
|
|
76
|
+
--terra-200: oklch(0.82 0.1 30);
|
|
77
|
+
--terra-400: oklch(0.65 0.2 30); /* = --brand-terra */
|
|
78
|
+
--terra-600: oklch(0.52 0.2 30);
|
|
79
|
+
--terra-800: oklch(0.38 0.15 30);
|
|
80
|
+
|
|
81
|
+
/* === Status Tint Scales (5-step, mirror indigo/sand/terra) === */
|
|
82
|
+
/* WHY: status badges use bg-X-100 text-X-600 dark:bg-X-800/30 dark:text-X-400 */
|
|
83
|
+
/* Success (green) — positive states */
|
|
84
|
+
--success-100: oklch(0.94 0.05 150);
|
|
85
|
+
--success-200: oklch(0.88 0.09 148);
|
|
86
|
+
--success-400: oklch(0.75 0.15 146);
|
|
87
|
+
--success-600: oklch(0.62 0.17 145); /* = --success */
|
|
88
|
+
--success-800: oklch(0.45 0.13 148);
|
|
89
|
+
/* Warning (amber) — attention, caution */
|
|
90
|
+
--warning-100: oklch(0.95 0.05 85);
|
|
91
|
+
--warning-200: oklch(0.9 0.09 82);
|
|
92
|
+
--warning-400: oklch(0.82 0.13 78);
|
|
93
|
+
--warning-600: oklch(0.68 0.14 70);
|
|
94
|
+
--warning-800: oklch(0.5 0.11 65);
|
|
95
|
+
/* Info (blue) — informational */
|
|
96
|
+
--info-100: oklch(0.93 0.04 250);
|
|
97
|
+
--info-200: oklch(0.85 0.08 250);
|
|
98
|
+
--info-400: oklch(0.72 0.14 250);
|
|
99
|
+
--info-600: oklch(0.6 0.16 252);
|
|
100
|
+
--info-800: oklch(0.45 0.15 255);
|
|
101
|
+
|
|
102
|
+
/* === Categorical Palette (diagram groups, tags, chart series) === */
|
|
103
|
+
/* WHY: identity colors for grouping/visual distinction, not semantic state. */
|
|
104
|
+
--cat-blue: oklch(0.62 0.18 250);
|
|
105
|
+
--cat-green: oklch(0.65 0.17 150);
|
|
106
|
+
--cat-amber: oklch(0.75 0.14 75);
|
|
107
|
+
--cat-pink: oklch(0.65 0.21 350);
|
|
108
|
+
--cat-teal: oklch(0.68 0.12 195);
|
|
109
|
+
--cat-orange: oklch(0.7 0.19 45);
|
|
110
|
+
--cat-rose: oklch(0.64 0.22 15);
|
|
111
|
+
--cat-cyan: oklch(0.7 0.12 220);
|
|
112
|
+
--cat-yellow: oklch(0.85 0.16 95);
|
|
113
|
+
--cat-indigo: oklch(0.58 0.2 272);
|
|
114
|
+
--cat-purple: oklch(0.58 0.22 305);
|
|
115
|
+
|
|
116
|
+
/* === Semantic Colors === */
|
|
117
|
+
--success: oklch(0.62 0.17 145); /* Green — positive states */
|
|
118
|
+
--error: oklch(0.6 0.2 25); /* Terra-dark — destructive actions */
|
|
119
|
+
--warning: oklch(0.78 0.14 75); /* Amber — warnings, attention */
|
|
120
|
+
--info: oklch(0.68 0.16 250); /* Blue — informational */
|
|
121
|
+
|
|
122
|
+
/* === Pure Colors === */
|
|
123
|
+
--white: oklch(1 0 0);
|
|
124
|
+
--black: oklch(0 0 0);
|
|
125
|
+
|
|
126
|
+
/* === Sidebar Colors === */
|
|
127
|
+
/* Sidebar is one shade darker than content — Linear-style depth */
|
|
128
|
+
--sidebar: oklch(0.96 0 0);
|
|
129
|
+
--sidebar-foreground: oklch(0.45 0 0);
|
|
130
|
+
--sidebar-primary: oklch(0.15 0 0);
|
|
131
|
+
--sidebar-primary-foreground: oklch(0.98 0 0);
|
|
132
|
+
--sidebar-accent: oklch(0.92 0 0);
|
|
133
|
+
--sidebar-accent-foreground: oklch(0.15 0 0);
|
|
134
|
+
--sidebar-border: oklch(0.91 0 0);
|
|
135
|
+
--sidebar-ring: var(--brand-indigo);
|
|
136
|
+
|
|
137
|
+
/* === Shadow tint ===
|
|
138
|
+
The one knob the design layer exposes. Pure black greys out warm surfaces,
|
|
139
|
+
so the shadow takes the darkest surface's hue. Radius, focus and motion live there. */
|
|
140
|
+
--elev-tint: oklch(0.12 0.04 258); /* = --brand-ink */
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@theme {
|
|
144
|
+
/* Gray scale utilities (bg-gray-100, border-gray-200, text-gray-300, etc.) */
|
|
145
|
+
--color-gray-50: var(--gray-50);
|
|
146
|
+
--color-gray-100: var(--gray-100);
|
|
147
|
+
--color-gray-200: var(--gray-200);
|
|
148
|
+
--color-gray-300: var(--gray-300);
|
|
149
|
+
--color-gray-500: var(--gray-500);
|
|
150
|
+
--color-gray-700: var(--gray-700);
|
|
151
|
+
--color-gray-900: var(--gray-900);
|
|
152
|
+
|
|
153
|
+
/* Brand colors (V6 names) */
|
|
154
|
+
--color-brand-indigo: var(--brand-indigo);
|
|
155
|
+
--color-brand-indigo-light: var(--brand-indigo-light);
|
|
156
|
+
--color-brand-sand: var(--brand-sand);
|
|
157
|
+
--color-brand-terra: var(--brand-terra);
|
|
158
|
+
/* Surface system */
|
|
159
|
+
--color-brand-ink: var(--brand-ink);
|
|
160
|
+
--color-brand-night: var(--brand-night);
|
|
161
|
+
--color-brand-veil: var(--brand-veil);
|
|
162
|
+
--color-brand-dusk: var(--brand-dusk);
|
|
163
|
+
--color-brand-cream: var(--brand-cream);
|
|
164
|
+
--color-brand-linen: var(--brand-linen);
|
|
165
|
+
--color-brand-mist: var(--brand-mist);
|
|
166
|
+
|
|
167
|
+
/* Tint scales */
|
|
168
|
+
--color-indigo-100: var(--indigo-100);
|
|
169
|
+
--color-indigo-200: var(--indigo-200);
|
|
170
|
+
--color-indigo-400: var(--indigo-400);
|
|
171
|
+
--color-indigo-600: var(--indigo-600);
|
|
172
|
+
--color-indigo-800: var(--indigo-800);
|
|
173
|
+
--color-sand-100: var(--sand-100);
|
|
174
|
+
--color-sand-200: var(--sand-200);
|
|
175
|
+
--color-sand-400: var(--sand-400);
|
|
176
|
+
--color-sand-600: var(--sand-600);
|
|
177
|
+
--color-sand-800: var(--sand-800);
|
|
178
|
+
--color-terra-100: var(--terra-100);
|
|
179
|
+
--color-terra-200: var(--terra-200);
|
|
180
|
+
--color-terra-400: var(--terra-400);
|
|
181
|
+
--color-terra-600: var(--terra-600);
|
|
182
|
+
--color-terra-800: var(--terra-800);
|
|
183
|
+
|
|
184
|
+
/* Semantic colors */
|
|
185
|
+
--color-success: var(--success);
|
|
186
|
+
--color-error: var(--error);
|
|
187
|
+
--color-warning: var(--warning);
|
|
188
|
+
--color-info: var(--info);
|
|
189
|
+
|
|
190
|
+
/* Status tint scales (bg-success-100, text-warning-600, etc.) */
|
|
191
|
+
--color-success-100: var(--success-100);
|
|
192
|
+
--color-success-200: var(--success-200);
|
|
193
|
+
--color-success-400: var(--success-400);
|
|
194
|
+
--color-success-600: var(--success-600);
|
|
195
|
+
--color-success-800: var(--success-800);
|
|
196
|
+
--color-warning-100: var(--warning-100);
|
|
197
|
+
--color-warning-200: var(--warning-200);
|
|
198
|
+
--color-warning-400: var(--warning-400);
|
|
199
|
+
--color-warning-600: var(--warning-600);
|
|
200
|
+
--color-warning-800: var(--warning-800);
|
|
201
|
+
--color-info-100: var(--info-100);
|
|
202
|
+
--color-info-200: var(--info-200);
|
|
203
|
+
--color-info-400: var(--info-400);
|
|
204
|
+
--color-info-600: var(--info-600);
|
|
205
|
+
--color-info-800: var(--info-800);
|
|
206
|
+
|
|
207
|
+
/* Categorical palette (diagram groups, tags, chart series) */
|
|
208
|
+
--color-cat-blue: var(--cat-blue);
|
|
209
|
+
--color-cat-green: var(--cat-green);
|
|
210
|
+
--color-cat-amber: var(--cat-amber);
|
|
211
|
+
--color-cat-pink: var(--cat-pink);
|
|
212
|
+
--color-cat-teal: var(--cat-teal);
|
|
213
|
+
--color-cat-orange: var(--cat-orange);
|
|
214
|
+
--color-cat-rose: var(--cat-rose);
|
|
215
|
+
--color-cat-cyan: var(--cat-cyan);
|
|
216
|
+
--color-cat-yellow: var(--cat-yellow);
|
|
217
|
+
--color-cat-indigo: var(--cat-indigo);
|
|
218
|
+
--color-cat-purple: var(--cat-purple);
|
|
219
|
+
|
|
220
|
+
/* Light theme color system — uses named surface colors (linen/mist pendants of night/veil) */
|
|
221
|
+
--color-background: var(--gray-50);
|
|
222
|
+
--color-foreground: var(--gray-900);
|
|
223
|
+
--color-foreground-muted: var(--gray-700);
|
|
224
|
+
|
|
225
|
+
--color-card: var(--brand-linen); /* Surface — pendant of night */
|
|
226
|
+
--color-card-foreground: var(--gray-900);
|
|
227
|
+
|
|
228
|
+
--color-popover: var(--brand-linen);
|
|
229
|
+
--color-popover-foreground: var(--gray-900);
|
|
230
|
+
|
|
231
|
+
--color-primary: var(--gray-900);
|
|
232
|
+
--color-primary-foreground: var(--gray-50);
|
|
233
|
+
|
|
234
|
+
--color-secondary: var(--gray-100);
|
|
235
|
+
--color-secondary-foreground: var(--gray-900);
|
|
236
|
+
|
|
237
|
+
--color-muted: var(--gray-100);
|
|
238
|
+
--color-muted-foreground: var(--gray-700);
|
|
239
|
+
|
|
240
|
+
--color-accent: var(--gray-100);
|
|
241
|
+
--color-accent-foreground: var(--gray-900);
|
|
242
|
+
|
|
243
|
+
--color-destructive: var(--error);
|
|
244
|
+
--color-destructive-foreground: var(--gray-50);
|
|
245
|
+
|
|
246
|
+
--color-border: var(--brand-mist); /* Borders — pendant of veil */
|
|
247
|
+
--color-input: var(--brand-mist);
|
|
248
|
+
/* WHY the accent, not gray-900: a near-black halo reads as an error first.
|
|
249
|
+
Focus is the one moment the brand speaks in chrome. */
|
|
250
|
+
--color-ring: var(--brand-indigo);
|
|
251
|
+
|
|
252
|
+
/* Sidebar colors */
|
|
253
|
+
--color-sidebar: var(--sidebar);
|
|
254
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
255
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
256
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
257
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
258
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
259
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
260
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
261
|
+
|
|
262
|
+
/* A spinner reads as a speed. Tailwind's 1s looks like thinking, not working,
|
|
263
|
+
and `animate-spin` is on every loading glyph, so this is a cheap win. */
|
|
264
|
+
--animate-spin: spin 700ms linear infinite;
|
|
265
|
+
|
|
266
|
+
/* Every bare `transition-colors` / `transition-all` reads these two. Tailwind's
|
|
267
|
+
150ms is the right beat on the wrong ease, and ~200 call sites used it. */
|
|
268
|
+
--default-transition-duration: var(--duration-quick);
|
|
269
|
+
--default-transition-timing-function: var(--ease-smooth-out);
|
|
270
|
+
|
|
271
|
+
/* Collapsible animations, on the craft layer's scale and asymmetric: an open
|
|
272
|
+
invites, a close gets out of the way. The old `0.2s ease-out` was off-scale. */
|
|
273
|
+
--animate-collapsible-down: collapsible-down var(--duration-fast) var(--ease-smooth-out);
|
|
274
|
+
--animate-collapsible-up: collapsible-up var(--duration-quick) var(--ease-smooth-out);
|
|
275
|
+
|
|
276
|
+
@keyframes collapsible-down {
|
|
277
|
+
from {
|
|
278
|
+
height: 0;
|
|
279
|
+
}
|
|
280
|
+
to {
|
|
281
|
+
height: var(--bits-collapsible-content-height);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@keyframes collapsible-up {
|
|
286
|
+
from {
|
|
287
|
+
height: var(--bits-collapsible-content-height);
|
|
288
|
+
}
|
|
289
|
+
to {
|
|
290
|
+
height: 0;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Accordion animations, on the same scale and the same asymmetry. */
|
|
295
|
+
--animate-accordion-down: accordion-down var(--duration-fast) var(--ease-smooth-out);
|
|
296
|
+
--animate-accordion-up: accordion-up var(--duration-quick) var(--ease-smooth-out);
|
|
297
|
+
|
|
298
|
+
@keyframes accordion-down {
|
|
299
|
+
from {
|
|
300
|
+
height: 0;
|
|
301
|
+
}
|
|
302
|
+
to {
|
|
303
|
+
height: var(--bits-accordion-content-height);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@keyframes accordion-up {
|
|
308
|
+
from {
|
|
309
|
+
height: var(--bits-accordion-content-height);
|
|
310
|
+
}
|
|
311
|
+
to {
|
|
312
|
+
height: 0;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.dark {
|
|
318
|
+
/* WHY: LayerChart halos axis labels with light-dark(), which reads color-scheme, not the .dark class. */
|
|
319
|
+
color-scheme: dark;
|
|
320
|
+
/* Dark theme — named surface system (ink/night/veil) */
|
|
321
|
+
--color-background: var(--brand-ink); /* Base — page background */
|
|
322
|
+
--color-foreground: var(--brand-cream);
|
|
323
|
+
--color-foreground-muted: var(--gray-300);
|
|
324
|
+
|
|
325
|
+
--color-card: var(--brand-night); /* Surface — cards, panels */
|
|
326
|
+
--color-card-foreground: var(--brand-cream);
|
|
327
|
+
|
|
328
|
+
--color-popover: var(--brand-night);
|
|
329
|
+
--color-popover-foreground: var(--brand-cream);
|
|
330
|
+
|
|
331
|
+
--color-primary: var(--brand-cream);
|
|
332
|
+
--color-primary-foreground: var(--gray-900);
|
|
333
|
+
|
|
334
|
+
--color-secondary: var(--brand-dusk); /* Between night (0.18) and veil (0.28) */
|
|
335
|
+
--color-secondary-foreground: var(--brand-cream);
|
|
336
|
+
|
|
337
|
+
--color-muted: var(--brand-dusk); /* Between night and veil — hover surfaces */
|
|
338
|
+
--color-muted-foreground: var(--gray-300);
|
|
339
|
+
|
|
340
|
+
--color-accent: var(--brand-dusk); /* Between night and veil — accent surfaces */
|
|
341
|
+
--color-accent-foreground: var(--brand-cream);
|
|
342
|
+
|
|
343
|
+
--color-destructive: var(--terra-400); /* Lighter terra for dark bg */
|
|
344
|
+
--color-destructive-foreground: var(--brand-cream);
|
|
345
|
+
|
|
346
|
+
--color-border: var(--brand-veil); /* Named border color */
|
|
347
|
+
--color-input: var(--brand-dusk); /* Between night and veil — input surfaces */
|
|
348
|
+
--color-ring: var(--brand-indigo-light);
|
|
349
|
+
|
|
350
|
+
/* Brand colors for dark theme — lighter variants for contrast on ink bg */
|
|
351
|
+
--color-brand-indigo: var(--brand-indigo-light); /* L=0.68 on ink L=0.12 = ΔL 0.56 ✓ */
|
|
352
|
+
|
|
353
|
+
/* Dark sidebar — uses named surface system */
|
|
354
|
+
--sidebar: var(--brand-night);
|
|
355
|
+
--sidebar-foreground: var(--brand-cream);
|
|
356
|
+
--sidebar-primary: var(--brand-indigo-light);
|
|
357
|
+
--sidebar-primary-foreground: oklch(1 0 0);
|
|
358
|
+
--sidebar-accent: oklch(0.24 0.05 262); /* Between night and veil */
|
|
359
|
+
--sidebar-accent-foreground: var(--brand-cream);
|
|
360
|
+
--sidebar-border: var(--brand-veil);
|
|
361
|
+
--sidebar-ring: var(--brand-indigo-light);
|
|
362
|
+
|
|
363
|
+
--color-sidebar: var(--sidebar);
|
|
364
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
365
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
366
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
367
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
368
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
369
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
370
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* === shadcn bare-name bridge ===
|
|
374
|
+
WHY: shared packages with raw CSS read `var(--card)` and friends with a light
|
|
375
|
+
fallback. We name them `--color-*`, so they painted white cards on ink. */
|
|
376
|
+
|
|
377
|
+
/* One `:root` block covers both themes, since `.dark` sits on html too. Set a
|
|
378
|
+
`--color-*` on a subtree and you must override the bare name there as well. */
|
|
379
|
+
:root {
|
|
380
|
+
--background: var(--color-background);
|
|
381
|
+
--foreground: var(--color-foreground);
|
|
382
|
+
|
|
383
|
+
--card: var(--color-card);
|
|
384
|
+
--card-foreground: var(--color-card-foreground);
|
|
385
|
+
|
|
386
|
+
--popover: var(--color-popover);
|
|
387
|
+
--popover-foreground: var(--color-popover-foreground);
|
|
388
|
+
|
|
389
|
+
--primary: var(--color-primary);
|
|
390
|
+
--primary-foreground: var(--color-primary-foreground);
|
|
391
|
+
|
|
392
|
+
--secondary: var(--color-secondary);
|
|
393
|
+
--secondary-foreground: var(--color-secondary-foreground);
|
|
394
|
+
|
|
395
|
+
--muted: var(--color-muted);
|
|
396
|
+
--muted-foreground: var(--color-muted-foreground);
|
|
397
|
+
|
|
398
|
+
--accent: var(--color-accent);
|
|
399
|
+
--accent-foreground: var(--color-accent-foreground);
|
|
400
|
+
|
|
401
|
+
--destructive: var(--color-destructive);
|
|
402
|
+
--destructive-foreground: var(--color-destructive-foreground);
|
|
403
|
+
|
|
404
|
+
--border: var(--color-border);
|
|
405
|
+
--input: var(--color-input);
|
|
406
|
+
--ring: var(--color-ring);
|
|
407
|
+
|
|
408
|
+
/* Chart series. Indigo leads, green second. Terra sits at 4 since a rate gauge
|
|
409
|
+
reads as caution, not identity. Every value has a dark variant. */
|
|
410
|
+
--chart-1: var(--color-brand-indigo);
|
|
411
|
+
--chart-2: var(--cat-green);
|
|
412
|
+
--chart-3: var(--brand-sand);
|
|
413
|
+
--chart-4: var(--brand-terra);
|
|
414
|
+
--chart-5: var(--cat-cyan);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* The shadow family, now valued by @heyramzi/ui/design. Names stay because
|
|
418
|
+
170-odd call sites use them. Shadow only, since these elements draw their own border. */
|
|
419
|
+
|
|
420
|
+
/* New work: use `shadow-btn`, `shadow-card`, `shadow-raised` and `shadow-overlay`. */
|
|
421
|
+
@layer utilities {
|
|
422
|
+
.shadow-soft-sm {
|
|
423
|
+
box-shadow: var(--elev-btn);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.shadow-soft {
|
|
427
|
+
box-shadow: var(--elev-card);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.shadow-soft-md {
|
|
431
|
+
box-shadow: var(--elev-raised);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* The one step that answers a pointer rather than describing a resting
|
|
435
|
+
height, so it borrows the step above whatever it was at rest. */
|
|
436
|
+
.shadow-soft-hover {
|
|
437
|
+
box-shadow: var(--elev-raised);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* The nine bits-ui state variants moved into `@heyramzi/ui/design` on 14 Sep
|
|
442
|
+
2026. app.css imports that before this file. */
|
|
443
|
+
|
|
444
|
+
@utility no-scrollbar {
|
|
445
|
+
-ms-overflow-style: none;
|
|
446
|
+
scrollbar-width: none;
|
|
447
|
+
&::-webkit-scrollbar {
|
|
448
|
+
display: none;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
@utility thin-scrollbar {
|
|
453
|
+
scrollbar-width: thin;
|
|
454
|
+
scrollbar-color: oklch(0.84 0 0) transparent;
|
|
455
|
+
&::-webkit-scrollbar {
|
|
456
|
+
width: 4px;
|
|
457
|
+
}
|
|
458
|
+
&::-webkit-scrollbar-track {
|
|
459
|
+
background: transparent;
|
|
460
|
+
}
|
|
461
|
+
&::-webkit-scrollbar-thumb {
|
|
462
|
+
background: oklch(0.84 0 0);
|
|
463
|
+
border-radius: 9999px;
|
|
464
|
+
}
|
|
465
|
+
.dark & {
|
|
466
|
+
scrollbar-color: oklch(0.45 0 0) transparent;
|
|
467
|
+
&::-webkit-scrollbar-thumb {
|
|
468
|
+
background: oklch(0.45 0 0);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/* WHY: below sm the dialog docks as a bottom sheet. The .t-modal scale would lift
|
|
474
|
+
it off the edge. A sheet enters from the edge it rests on. */
|
|
475
|
+
@media (max-width: 639px) {
|
|
476
|
+
[data-slot="dialog-content"]:not([data-command-dialog]).t-modal {
|
|
477
|
+
transform: translateY(100%);
|
|
478
|
+
transition:
|
|
479
|
+
transform var(--modal-open-dur) var(--modal-ease),
|
|
480
|
+
opacity var(--modal-open-dur) var(--modal-ease);
|
|
481
|
+
}
|
|
482
|
+
[data-slot="dialog-content"]:not([data-command-dialog]).t-modal[data-state="open"] {
|
|
483
|
+
transform: translateY(0);
|
|
484
|
+
}
|
|
485
|
+
[data-slot="dialog-content"]:not([data-command-dialog]).t-modal[data-state="closed"] {
|
|
486
|
+
transform: translateY(100%);
|
|
487
|
+
transition:
|
|
488
|
+
transform var(--modal-close-dur) var(--modal-ease),
|
|
489
|
+
opacity var(--modal-close-dur) var(--modal-ease);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/* ── The palette does not animate ──────────────────────
|
|
494
|
+
WHY: it's opened by shortcut dozens of times a day, so an entrance feels like
|
|
495
|
+
lag. Raycast and Spotlight don't animate either. */
|
|
496
|
+
|
|
497
|
+
/* The backdrop is a sibling in the portal, so it's named via `overlayClass`.
|
|
498
|
+
Reaching across the portal would also hit a dialog open underneath. */
|
|
499
|
+
[data-slot="dialog-content"][data-command-dialog].t-modal,
|
|
500
|
+
[data-slot="dialog-overlay"].t-modal-backdrop.t-instant {
|
|
501
|
+
transition: none;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
@layer base {
|
|
505
|
+
* {
|
|
506
|
+
@apply border-border outline-ring/50;
|
|
507
|
+
}
|
|
508
|
+
body {
|
|
509
|
+
@apply bg-background text-foreground;
|
|
510
|
+
}
|
|
511
|
+
html {
|
|
512
|
+
@apply font-sans;
|
|
513
|
+
scrollbar-color: var(--gray-300) transparent;
|
|
514
|
+
/* WHY: iOS Safari inflates text in landscape unless this is pinned. */
|
|
515
|
+
-webkit-text-size-adjust: 100%;
|
|
516
|
+
text-size-adjust: 100%;
|
|
517
|
+
}
|
|
518
|
+
.dark html,
|
|
519
|
+
html.dark {
|
|
520
|
+
scrollbar-color: var(--brand-veil) transparent;
|
|
521
|
+
}
|
|
522
|
+
h1,
|
|
523
|
+
h2,
|
|
524
|
+
h3,
|
|
525
|
+
h4,
|
|
526
|
+
h5,
|
|
527
|
+
h6 {
|
|
528
|
+
font-family: var(--font-heading);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/* WHY: the browser's default highlight is a system blue from no theme. Indigo
|
|
532
|
+
at 18% keeps text at its own contrast in both modes. */
|
|
533
|
+
::selection {
|
|
534
|
+
background-color: color-mix(in oklab, var(--brand-indigo) 18%, transparent);
|
|
535
|
+
}
|
|
536
|
+
.dark ::selection,
|
|
537
|
+
html.dark ::selection {
|
|
538
|
+
background-color: color-mix(in oklab, var(--brand-indigo-light) 26%, transparent);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* ── Touch input ───────────────────────────────────────
|
|
542
|
+
WHY any-pointer: an iPad with a Magic Keyboard reports a fine pointer, and
|
|
543
|
+
`pointer: coarse` would drop touch sizing while the screen's still tapped. */
|
|
544
|
+
|
|
545
|
+
/* iOS paints a gray flash on every tap, which clashes with our own :active
|
|
546
|
+
feedback, so it's turned off. */
|
|
547
|
+
@media (any-pointer: coarse) {
|
|
548
|
+
a,
|
|
549
|
+
button,
|
|
550
|
+
label,
|
|
551
|
+
summary,
|
|
552
|
+
select,
|
|
553
|
+
[role="button"],
|
|
554
|
+
[role="link"],
|
|
555
|
+
[role="menuitem"],
|
|
556
|
+
[role="option"],
|
|
557
|
+
[role="tab"] {
|
|
558
|
+
-webkit-tap-highlight-color: transparent;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* WHY: rows are built at desk density (28-32px). A thumb needs 44px, and rows
|
|
562
|
+
stack, so growing them costs only scroll. */
|
|
563
|
+
[data-slot="dropdown-menu-item"],
|
|
564
|
+
[data-slot="dropdown-menu-checkbox-item"],
|
|
565
|
+
[data-slot="dropdown-menu-radio-item"],
|
|
566
|
+
[data-slot="select-item"],
|
|
567
|
+
[data-slot="command-item"],
|
|
568
|
+
[data-slot="context-menu-item"],
|
|
569
|
+
[data-slot="context-menu-checkbox-item"],
|
|
570
|
+
[data-slot="context-menu-radio-item"] {
|
|
571
|
+
min-height: 44px;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/* ── Reduced motion, once ──────────────────────────────
|
|
577
|
+
WHY here: 22 files had no guard and 32 wrote their own. Both app.css files
|
|
578
|
+
import this, so it's stated once. */
|
|
579
|
+
|
|
580
|
+
/* A floor, not a kill switch: transitions still run at the micro step, so hover
|
|
581
|
+
and focus still answer. Entrance delays, loops and long travel go. */
|
|
582
|
+
|
|
583
|
+
/* Unlayered so it beats utilities and scoped rules. A component that wants
|
|
584
|
+
different behaviour writes its own reduced-motion block with `!important`. */
|
|
585
|
+
@media (prefers-reduced-motion: reduce) {
|
|
586
|
+
*,
|
|
587
|
+
*::before,
|
|
588
|
+
*::after {
|
|
589
|
+
animation-delay: 0ms !important;
|
|
590
|
+
animation-duration: 1ms !important;
|
|
591
|
+
animation-iteration-count: 1 !important;
|
|
592
|
+
transition-delay: 0ms !important;
|
|
593
|
+
transition-duration: var(--duration-micro) !important;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
html {
|
|
597
|
+
scroll-behavior: auto !important;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/* ── Radius, by role not by size ─────────────────────────────
|
|
602
|
+
A chip inside a control inside a card has to read as nested, which needs
|
|
603
|
+
three radii that step, not one radius reused. The Tailwind names are the
|
|
604
|
+
home so `rounded-lg` on a button already resolves to the control radius and
|
|
605
|
+
no component has to learn a new class. */
|
|
606
|
+
@theme {
|
|
607
|
+
--radius-xs: 4px; /* tag, dot, inline code */
|
|
608
|
+
--radius-sm: 6px; /* chip, badge, small pill */
|
|
609
|
+
--radius-md: 7px; /* between a chip and a control */
|
|
610
|
+
--radius-lg: 8px; /* control: button, input, select, menu item */
|
|
611
|
+
--radius-xl: 10px; /* card, panel, stage */
|
|
612
|
+
--radius-2xl: 14px; /* overlay: dialog, sheet, command palette */
|
|
613
|
+
--radius-3xl: 20px; /* hero surface, full-bleed panel */
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/* ── Elevation ───────────────────────────────────────────────
|
|
617
|
+
Four steps of lift, plus the two edges that are not lift.
|
|
618
|
+
|
|
619
|
+
WHY the steps are shadow-only and the hairline is its own token: most boxes
|
|
620
|
+
in a kit already draw a border, and an elevation that bakes a `0 0 0 1px`
|
|
621
|
+
ring into every step gives those boxes two edges a pixel apart. Compose them
|
|
622
|
+
where a component drops its border:
|
|
623
|
+
|
|
624
|
+
box-shadow: var(--elev-hairline), var(--elev-card);
|
|
625
|
+
|
|
626
|
+
WHY each step is stacked rather than one blurred drop: a single shadow reads
|
|
627
|
+
as a sticker. Depth is several offsets falling off together, which is what
|
|
628
|
+
the eye reads as distance. They cost nothing extra because every stop is the
|
|
629
|
+
same colour at a different alpha.
|
|
630
|
+
|
|
631
|
+
WHY the blur radii are large and the alphas small: a 4px blur at 20% draws a
|
|
632
|
+
visible grey edge, which the eye reads as a second border. A 28px blur at 7%
|
|
633
|
+
is barely a colour anywhere and reads as height. Reach for more blur before
|
|
634
|
+
more alpha, every time.
|
|
635
|
+
|
|
636
|
+
`--elev-tint` is the one knob an app turns. Pure black greys a warm palette
|
|
637
|
+
out; the hue of the app's own darkest surface keeps the shadow in the
|
|
638
|
+
family. */
|
|
639
|
+
:root {
|
|
640
|
+
|
|
641
|
+
/* Resting on the page. A button, a chip, a row. */
|
|
642
|
+
--elev-btn:
|
|
643
|
+
0 1px 1px -0.5px color-mix(in oklab, var(--elev-tint) 7%, transparent),
|
|
644
|
+
0 2px 5px -2px color-mix(in oklab, var(--elev-tint) 6%, transparent);
|
|
645
|
+
|
|
646
|
+
/* Sitting on the page. A card, a stage, a panel. */
|
|
647
|
+
--elev-card:
|
|
648
|
+
0 1px 2px -1px color-mix(in oklab, var(--elev-tint) 7%, transparent),
|
|
649
|
+
0 4px 9px -3px color-mix(in oklab, var(--elev-tint) 6%, transparent),
|
|
650
|
+
0 14px 28px -10px color-mix(in oklab, var(--elev-tint) 7%, transparent);
|
|
651
|
+
|
|
652
|
+
/* Lifted off the page. A hovered card, a popover, a menu. */
|
|
653
|
+
--elev-raised:
|
|
654
|
+
0 1px 2px -1px color-mix(in oklab, var(--elev-tint) 8%, transparent),
|
|
655
|
+
0 6px 13px -4px color-mix(in oklab, var(--elev-tint) 9%, transparent),
|
|
656
|
+
0 20px 40px -12px color-mix(in oklab, var(--elev-tint) 12%, transparent);
|
|
657
|
+
|
|
658
|
+
/* Floating over a dimmed page. A dialog, a sheet, a command palette. */
|
|
659
|
+
--elev-overlay:
|
|
660
|
+
0 2px 4px -1px color-mix(in oklab, var(--elev-tint) 8%, transparent),
|
|
661
|
+
0 12px 26px -8px color-mix(in oklab, var(--elev-tint) 12%, transparent),
|
|
662
|
+
0 40px 72px -20px color-mix(in oklab, var(--elev-tint) 20%, transparent);
|
|
663
|
+
|
|
664
|
+
/* The two edges. A hairline separates a surface from what is behind it; a rim
|
|
665
|
+
is the light catching its top edge, which is what makes a filled control
|
|
666
|
+
read as a physical key rather than a coloured rectangle. */
|
|
667
|
+
--elev-hairline: 0 0 0 1px var(--color-border, var(--border));
|
|
668
|
+
--elev-rim: inset 0 1px 0 color-mix(in oklab, white 16%, transparent);
|
|
669
|
+
|
|
670
|
+
/* A field is the one box that goes in rather than up. */
|
|
671
|
+
--elev-field: inset 0 1px 2px color-mix(in oklab, var(--elev-tint) 7%, transparent);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/* A dark surface cannot cast a darker shadow than the page it sits on, so the
|
|
675
|
+
hairline does the separating and the shadow only sinks what is behind it. On
|
|
676
|
+
dark the hairline is white at a low alpha, which is what reads as a lit edge
|
|
677
|
+
rather than as a drawn border. */
|
|
678
|
+
.dark {
|
|
679
|
+
--elev-btn: 0 1px 2px color-mix(in oklab, black 30%, transparent);
|
|
680
|
+
--elev-card:
|
|
681
|
+
0 1px 2px color-mix(in oklab, black 24%, transparent),
|
|
682
|
+
0 4px 12px -4px color-mix(in oklab, black 30%, transparent);
|
|
683
|
+
--elev-raised:
|
|
684
|
+
0 2px 6px color-mix(in oklab, black 30%, transparent),
|
|
685
|
+
0 10px 24px -6px color-mix(in oklab, black 38%, transparent);
|
|
686
|
+
--elev-overlay:
|
|
687
|
+
0 4px 10px color-mix(in oklab, black 34%, transparent),
|
|
688
|
+
0 24px 56px -12px color-mix(in oklab, black 50%, transparent);
|
|
689
|
+
|
|
690
|
+
--elev-hairline: 0 0 0 1px color-mix(in oklab, white 10%, transparent);
|
|
691
|
+
--elev-rim: inset 0 1px 0 color-mix(in oklab, white 10%, transparent);
|
|
692
|
+
--elev-field: inset 0 1px 2px color-mix(in oklab, black 40%, transparent);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/* ── Focus ───────────────────────────────────────────────────
|
|
696
|
+
One ring, two parts: a solid edge that redraws the control's own outline in
|
|
697
|
+
the accent, and a soft halo that carries it off the surface. Written as a
|
|
698
|
+
variable so a component spends one line on it and every control focuses the
|
|
699
|
+
same way. */
|
|
700
|
+
:root {
|
|
701
|
+
--ring-color: var(--color-ring, var(--ring));
|
|
702
|
+
--ring-halo: color-mix(in oklab, var(--ring-color) 16%, transparent);
|
|
703
|
+
/* A solid pixel redrawing the control's own edge, then a wide soft band. At a
|
|
704
|
+
higher alpha the band reads as a second border rather than as a glow, which
|
|
705
|
+
is why it is 16% over 4px and not 30% over 2px. */
|
|
706
|
+
--ring-focus: 0 0 0 1px var(--ring-color), 0 0 0 5px var(--ring-halo);
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/* ── Motion ──────────────────────────────────────────────────
|
|
710
|
+
The transitions-dev scale, verbatim, so a snippet pasted from that skill and
|
|
711
|
+
a component written here read from the same names.
|
|
712
|
+
|
|
713
|
+
The doctrine in one line: an open is an invitation and a close should get out
|
|
714
|
+
of the way, so every close is shorter than its open and no close bounces. */
|
|
715
|
+
:root {
|
|
716
|
+
--duration-stagger: 40ms;
|
|
717
|
+
--duration-micro: 80ms;
|
|
718
|
+
--duration-quick: 150ms; /* every close, text swap, tooltip in */
|
|
719
|
+
--duration-fast: 250ms; /* every open, tabs, icon swap, page slide */
|
|
720
|
+
--duration-medium: 350ms; /* panel close, toast close */
|
|
721
|
+
--duration-slow: 400ms; /* panel open, skeleton reveal */
|
|
722
|
+
--duration-very-slow: 500ms; /* emphasis: badge, text reveal, success check */
|
|
723
|
+
|
|
724
|
+
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1); /* all surface motion */
|
|
725
|
+
--ease-in-out: ease-in-out; /* swaps and cross-fades */
|
|
726
|
+
--ease-out: ease-out; /* tooltips */
|
|
727
|
+
--ease-linear: linear; /* shimmer, pulse, spinner */
|
|
728
|
+
|
|
729
|
+
--distance-micro: 4px;
|
|
730
|
+
--distance-small: 6px;
|
|
731
|
+
--distance-base: 8px;
|
|
732
|
+
--distance-medium: 12px;
|
|
733
|
+
--distance-large: 30px;
|
|
734
|
+
|
|
735
|
+
--scale-large: 0.96; /* modal */
|
|
736
|
+
--scale-medium: 0.97; /* dropdown, popover open */
|
|
737
|
+
--scale-small: 0.98; /* tooltip */
|
|
738
|
+
--scale-tiny: 0.99; /* dropdown close */
|
|
739
|
+
|
|
740
|
+
--blur-small: 2px;
|
|
741
|
+
--blur-medium: 3px;
|
|
742
|
+
--blur-large: 8px;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/* Tailwind utility aliases, so `shadow-card`, `duration-fast` and
|
|
746
|
+
`ease-smooth-out` exist as classes and a component can stay in utilities
|
|
747
|
+
instead of dropping into a style block for one shadow. */
|
|
748
|
+
@theme inline {
|
|
749
|
+
--shadow-hairline: var(--elev-hairline);
|
|
750
|
+
--shadow-btn: var(--elev-btn);
|
|
751
|
+
--shadow-card: var(--elev-card);
|
|
752
|
+
--shadow-raised: var(--elev-raised);
|
|
753
|
+
--shadow-overlay: var(--elev-overlay);
|
|
754
|
+
--shadow-field: var(--elev-field);
|
|
755
|
+
--shadow-rim: var(--elev-rim);
|
|
756
|
+
/* A filled control: the lit top edge and the resting lift, in one class,
|
|
757
|
+
because the two never appear apart and utilities cannot be stacked. */
|
|
758
|
+
--shadow-key: var(--elev-rim), var(--elev-btn);
|
|
759
|
+
/* The composed pair, for a surface that draws no border of its own. */
|
|
760
|
+
--shadow-edge-card: var(--elev-hairline), var(--elev-card);
|
|
761
|
+
--shadow-edge-raised: var(--elev-hairline), var(--elev-raised);
|
|
762
|
+
--shadow-edge-overlay: var(--elev-hairline), var(--elev-overlay);
|
|
763
|
+
|
|
764
|
+
--ease-smooth-out: var(--ease-smooth-out);
|
|
765
|
+
|
|
766
|
+
/* WHY the durations are re-declared under a second name: Tailwind's
|
|
767
|
+
`duration-*` utility reads `--transition-duration-*`, not `--duration-*`, so
|
|
768
|
+
the six names above generated no class at all. `duration-fast` therefore
|
|
769
|
+
compiled to nothing and the element ended up at `transition-duration: 0s`:
|
|
770
|
+
no error, no warning, and a component that simply does not animate. The
|
|
771
|
+
comment at the top of this block had claimed `duration-fast` was a class
|
|
772
|
+
since the block was written. Found 31 Aug 2026 by probing a live page. */
|
|
773
|
+
--transition-duration-micro: var(--duration-micro);
|
|
774
|
+
--transition-duration-quick: var(--duration-quick);
|
|
775
|
+
--transition-duration-fast: var(--duration-fast);
|
|
776
|
+
--transition-duration-medium: var(--duration-medium);
|
|
777
|
+
--transition-duration-slow: var(--duration-slow);
|
|
778
|
+
--transition-duration-very-slow: var(--duration-very-slow);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/* The bits-ui state variants every primitive in `./shadcn` is written against.
|
|
782
|
+
*
|
|
783
|
+
* bits-ui v2 writes `data-checked` / `data-open` and v1 wrote
|
|
784
|
+
* `data-state="checked"`, so each variant matches both and a component does not
|
|
785
|
+
* have to know which it is talking to. They live here rather than in a
|
|
786
|
+
* consumer's stylesheet because the classes that need them ship in this
|
|
787
|
+
* package: an app that defines only the palette would render a switch that
|
|
788
|
+
* never moves. */
|
|
789
|
+
@custom-variant data-open {
|
|
790
|
+
&:where([data-state="open"]),
|
|
791
|
+
&:where([data-open]:not([data-open="false"])) {
|
|
792
|
+
@slot;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
@custom-variant data-closed {
|
|
797
|
+
&:where([data-state="closed"]),
|
|
798
|
+
&:where([data-closed]:not([data-closed="false"])) {
|
|
799
|
+
@slot;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
@custom-variant data-checked {
|
|
804
|
+
&:where([data-state="checked"]),
|
|
805
|
+
&:where([data-checked]:not([data-checked="false"])) {
|
|
806
|
+
@slot;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
@custom-variant data-unchecked {
|
|
811
|
+
&:where([data-state="unchecked"]),
|
|
812
|
+
&:where([data-unchecked]:not([data-unchecked="false"])) {
|
|
813
|
+
@slot;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
@custom-variant data-selected {
|
|
818
|
+
&:where([data-selected]) {
|
|
819
|
+
@slot;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
@custom-variant data-disabled {
|
|
824
|
+
&:where([data-disabled="true"]),
|
|
825
|
+
&:where([data-disabled]:not([data-disabled="false"])) {
|
|
826
|
+
@slot;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
@custom-variant data-active {
|
|
831
|
+
&:where([data-state="active"]),
|
|
832
|
+
&:where([data-active]:not([data-active="false"])) {
|
|
833
|
+
@slot;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
@custom-variant data-horizontal {
|
|
838
|
+
&:where([data-orientation="horizontal"]) {
|
|
839
|
+
@slot;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
@custom-variant data-vertical {
|
|
844
|
+
&:where([data-orientation="vertical"]) {
|
|
845
|
+
@slot;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
@layer base {
|
|
850
|
+
/* One ring for the whole kit. `:where` keeps it at specificity zero on top of
|
|
851
|
+
the layer, so a control that needs a different ring writes one and wins. */
|
|
852
|
+
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
|
|
853
|
+
outline: none;
|
|
854
|
+
box-shadow: var(--ring-focus);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/* The accent at a low alpha, not the browser blue, because a selected word is
|
|
858
|
+
the one moment the palette shows up inside running text. */
|
|
859
|
+
::selection {
|
|
860
|
+
background: color-mix(in oklab, var(--ring-color) 24%, transparent);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/* A default macOS overlay scrollbar paints a black bar on a dark panel. Track
|
|
864
|
+
transparent, thumb on the line token, so it belongs to whatever surface it
|
|
865
|
+
is over. The border is what insets the thumb without a second element. */
|
|
866
|
+
:where(html) {
|
|
867
|
+
scrollbar-color: var(--color-border, var(--border)) transparent;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
::-webkit-scrollbar {
|
|
871
|
+
width: 10px;
|
|
872
|
+
height: 10px;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
::-webkit-scrollbar-track {
|
|
876
|
+
background: transparent;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
::-webkit-scrollbar-thumb {
|
|
880
|
+
border: 3px solid transparent;
|
|
881
|
+
background-clip: padding-box;
|
|
882
|
+
border-radius: 999px;
|
|
883
|
+
background-color: var(--color-border, var(--border));
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
::-webkit-scrollbar-thumb:hover {
|
|
887
|
+
background-color: var(--color-muted-foreground, var(--muted-foreground));
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
@layer components {
|
|
892
|
+
/* Three moves the kit repeats. They are classes rather than tokens because a
|
|
893
|
+
component wants one name, not four declarations, and because the reduced
|
|
894
|
+
motion guard then lives in one place instead of in every component.
|
|
895
|
+
|
|
896
|
+
Namespaced `t-` to match the transitions-dev snippets, which these sit
|
|
897
|
+
beside rather than duplicate. */
|
|
898
|
+
|
|
899
|
+
/* A control that reads as a key: it travels down a pixel under the finger.
|
|
900
|
+
The travel is what sells it, because a colour change alone reads as a hover
|
|
901
|
+
state, not as a press. */
|
|
902
|
+
.t-press {
|
|
903
|
+
transition:
|
|
904
|
+
background-color var(--duration-quick) var(--ease-smooth-out),
|
|
905
|
+
border-color var(--duration-quick) var(--ease-smooth-out),
|
|
906
|
+
color var(--duration-quick) var(--ease-smooth-out),
|
|
907
|
+
box-shadow var(--duration-quick) var(--ease-smooth-out),
|
|
908
|
+
transform var(--duration-micro) var(--ease-smooth-out);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.t-press:active:not(:disabled, [aria-disabled="true"]) {
|
|
912
|
+
transform: translateY(1px);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/* A card that answers the pointer. It rises by a pixel and gains the next
|
|
916
|
+
step of elevation, so the hover reads as the card coming forward rather
|
|
917
|
+
than as its border changing colour. */
|
|
918
|
+
.t-lift {
|
|
919
|
+
transition:
|
|
920
|
+
box-shadow var(--duration-fast) var(--ease-smooth-out),
|
|
921
|
+
transform var(--duration-fast) var(--ease-smooth-out);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.t-lift:hover {
|
|
925
|
+
transform: translateY(-1px);
|
|
926
|
+
box-shadow: var(--elev-raised);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/* A surface arriving. The open carries the distance, the scale and the blur;
|
|
930
|
+
the close drops all three and takes less time, per the open/close
|
|
931
|
+
asymmetry rule in transitions-dev. */
|
|
932
|
+
.t-enter {
|
|
933
|
+
animation: t-enter var(--duration-fast) var(--ease-smooth-out) both;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.t-exit {
|
|
937
|
+
animation: t-exit var(--duration-quick) var(--ease-smooth-out) both;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
@media (prefers-reduced-motion: reduce) {
|
|
941
|
+
.t-press,
|
|
942
|
+
.t-lift {
|
|
943
|
+
transition: none;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.t-press:active,
|
|
947
|
+
.t-lift:hover {
|
|
948
|
+
transform: none;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
.t-enter,
|
|
952
|
+
.t-exit {
|
|
953
|
+
animation-duration: 1ms;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
@keyframes t-enter {
|
|
959
|
+
from {
|
|
960
|
+
opacity: 0;
|
|
961
|
+
transform: translateY(var(--distance-micro)) scale(var(--scale-medium));
|
|
962
|
+
filter: blur(var(--blur-small));
|
|
963
|
+
}
|
|
964
|
+
to {
|
|
965
|
+
opacity: 1;
|
|
966
|
+
transform: none;
|
|
967
|
+
filter: none;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/* A mark confirming a state that has already changed: it arrives after the box
|
|
972
|
+
it sits in, so it grows into place instead of fading. */
|
|
973
|
+
@keyframes t-check {
|
|
974
|
+
from {
|
|
975
|
+
opacity: 0;
|
|
976
|
+
transform: scale(0.4);
|
|
977
|
+
}
|
|
978
|
+
to {
|
|
979
|
+
opacity: 1;
|
|
980
|
+
transform: scale(1);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
@keyframes t-exit {
|
|
985
|
+
from {
|
|
986
|
+
opacity: 1;
|
|
987
|
+
transform: none;
|
|
988
|
+
}
|
|
989
|
+
to {
|
|
990
|
+
opacity: 0;
|
|
991
|
+
transform: scale(var(--scale-tiny));
|
|
992
|
+
}
|
|
993
|
+
}
|