@fragments-sdk/ui 0.18.0 → 0.19.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/dist/assets/ui.css +2700 -3256
- package/dist/chart.cjs +0 -1
- package/dist/chart.js +0 -1
- package/dist/codeblock.cjs +0 -1
- package/dist/codeblock.js +0 -1
- package/dist/colorpicker.cjs +0 -1
- package/dist/colorpicker.js +0 -1
- package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
- package/dist/components/Accordion/Accordion.module.scss.js +8 -8
- package/dist/components/Alert/Alert.module.scss.cjs +12 -12
- package/dist/components/Alert/Alert.module.scss.js +12 -12
- package/dist/components/AppShell/AppShell.module.scss.cjs +12 -12
- package/dist/components/AppShell/AppShell.module.scss.js +12 -12
- package/dist/components/Avatar/Avatar.module.scss.cjs +13 -13
- package/dist/components/Avatar/Avatar.module.scss.js +13 -13
- package/dist/components/Badge/Badge.module.scss.cjs +13 -13
- package/dist/components/Badge/Badge.module.scss.js +13 -13
- package/dist/components/BentoGrid/BentoGrid.module.scss.cjs +14 -14
- package/dist/components/BentoGrid/BentoGrid.module.scss.js +14 -14
- package/dist/components/Box/Box.module.scss.cjs +152 -152
- package/dist/components/Box/Box.module.scss.js +152 -152
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.cjs +8 -8
- package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.js +8 -8
- package/dist/components/Button/Button.module.scss.cjs +12 -12
- package/dist/components/Button/Button.module.scss.js +12 -12
- package/dist/components/Card/Card.module.scss.cjs +14 -14
- package/dist/components/Card/Card.module.scss.js +14 -14
- package/dist/components/Chart/Chart.module.scss.cjs +15 -15
- package/dist/components/Chart/Chart.module.scss.js +15 -15
- package/dist/components/Chart/index.d.ts +0 -1
- package/dist/components/Chart/index.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.scss.cjs +10 -10
- package/dist/components/Checkbox/Checkbox.module.scss.js +10 -10
- package/dist/components/Chip/Chip.module.scss.cjs +15 -15
- package/dist/components/Chip/Chip.module.scss.js +15 -15
- package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +21 -21
- package/dist/components/CodeBlock/CodeBlock.module.scss.js +21 -21
- package/dist/components/CodeBlock/index.d.ts +0 -1
- package/dist/components/CodeBlock/index.d.ts.map +1 -1
- package/dist/components/Collapsible/Collapsible.module.scss.cjs +10 -10
- package/dist/components/Collapsible/Collapsible.module.scss.js +10 -10
- package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
- package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
- package/dist/components/ColorPicker/index.d.ts +0 -1
- package/dist/components/ColorPicker/index.d.ts.map +1 -1
- package/dist/components/Combobox/Combobox.module.scss.cjs +23 -23
- package/dist/components/Combobox/Combobox.module.scss.js +23 -23
- package/dist/components/Combobox/index.cjs +13 -10
- package/dist/components/Combobox/index.d.ts.map +1 -1
- package/dist/components/Combobox/index.js +13 -10
- package/dist/components/Command/Command.module.scss.cjs +11 -11
- package/dist/components/Command/Command.module.scss.js +11 -11
- package/dist/components/ConversationList/ConversationList.module.scss.cjs +10 -10
- package/dist/components/ConversationList/ConversationList.module.scss.js +10 -10
- package/dist/components/DataTable/DataTable.module.scss.cjs +26 -26
- package/dist/components/DataTable/DataTable.module.scss.js +26 -26
- package/dist/components/DataTable/index.cjs +0 -1
- package/dist/components/DataTable/index.d.ts +0 -1
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/index.js +0 -1
- package/dist/components/DatePicker/DatePicker.module.scss.cjs +31 -31
- package/dist/components/DatePicker/DatePicker.module.scss.js +31 -31
- package/dist/components/DatePicker/index.d.ts +0 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
- package/dist/components/Dialog/Dialog.module.scss.js +14 -14
- package/dist/components/Drawer/Drawer.module.scss.cjs +33 -27
- package/dist/components/Drawer/Drawer.module.scss.js +34 -28
- package/dist/components/Drawer/index.cjs +36 -14
- package/dist/components/Drawer/index.d.ts +21 -3
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Drawer/index.js +36 -14
- package/dist/components/Editor/Editor.module.scss.cjs +17 -17
- package/dist/components/Editor/Editor.module.scss.js +17 -17
- package/dist/components/EmptyState/EmptyState.module.scss.cjs +8 -8
- package/dist/components/EmptyState/EmptyState.module.scss.js +8 -8
- package/dist/components/Field/Field.module.scss.cjs +4 -4
- package/dist/components/Field/Field.module.scss.js +4 -4
- package/dist/components/Fieldset/Fieldset.module.scss.cjs +3 -3
- package/dist/components/Fieldset/Fieldset.module.scss.js +3 -3
- package/dist/components/Header/Header.module.scss.cjs +28 -28
- package/dist/components/Header/Header.module.scss.js +28 -28
- package/dist/components/Icon/Icon.module.scss.cjs +8 -8
- package/dist/components/Icon/Icon.module.scss.js +8 -8
- package/dist/components/Image/Image.module.scss.cjs +27 -27
- package/dist/components/Image/Image.module.scss.js +27 -27
- package/dist/components/Input/Input.module.scss.cjs +19 -19
- package/dist/components/Input/Input.module.scss.js +19 -19
- package/dist/components/Link/Link.module.scss.cjs +10 -10
- package/dist/components/Link/Link.module.scss.js +10 -10
- package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
- package/dist/components/Listbox/Listbox.module.scss.js +8 -8
- package/dist/components/Loading/Loading.module.scss.cjs +30 -30
- package/dist/components/Loading/Loading.module.scss.js +30 -30
- package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
- package/dist/components/Markdown/Markdown.module.scss.js +1 -1
- package/dist/components/Markdown/index.d.ts +0 -1
- package/dist/components/Markdown/index.d.ts.map +1 -1
- package/dist/components/Menu/Menu.module.scss.cjs +16 -13
- package/dist/components/Menu/Menu.module.scss.js +17 -14
- package/dist/components/Menu/index.cjs +1 -1
- package/dist/components/Menu/index.d.ts.map +1 -1
- package/dist/components/Menu/index.js +1 -1
- package/dist/components/Message/Message.module.scss.cjs +18 -18
- package/dist/components/Message/Message.module.scss.js +18 -18
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +28 -28
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +28 -28
- package/dist/components/Pagination/Pagination.module.scss.cjs +7 -7
- package/dist/components/Pagination/Pagination.module.scss.js +7 -7
- package/dist/components/Popover/Popover.module.scss.cjs +10 -10
- package/dist/components/Popover/Popover.module.scss.js +10 -10
- package/dist/components/Progress/Progress.module.scss.cjs +25 -25
- package/dist/components/Progress/Progress.module.scss.js +25 -25
- package/dist/components/Prompt/Prompt.module.scss.cjs +26 -14
- package/dist/components/Prompt/Prompt.module.scss.js +26 -14
- package/dist/components/Prompt/index.cjs +16 -0
- package/dist/components/Prompt/index.d.ts +17 -1
- package/dist/components/Prompt/index.d.ts.map +1 -1
- package/dist/components/Prompt/index.js +16 -0
- package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +16 -16
- package/dist/components/RadioGroup/RadioGroup.module.scss.js +16 -16
- package/dist/components/ScrollArea/ScrollArea.module.scss.cjs +10 -10
- package/dist/components/ScrollArea/ScrollArea.module.scss.js +10 -10
- package/dist/components/Select/Select.module.scss.cjs +17 -17
- package/dist/components/Select/Select.module.scss.js +17 -17
- package/dist/components/Select/index.cjs +20 -20
- package/dist/components/Select/index.d.ts.map +1 -1
- package/dist/components/Select/index.js +20 -20
- package/dist/components/Separator/Separator.module.scss.cjs +10 -10
- package/dist/components/Separator/Separator.module.scss.js +10 -10
- package/dist/components/Sidebar/Sidebar.module.scss.cjs +42 -42
- package/dist/components/Sidebar/Sidebar.module.scss.js +42 -42
- package/dist/components/Slider/Slider.module.scss.cjs +12 -12
- package/dist/components/Slider/Slider.module.scss.js +12 -12
- package/dist/components/Slider/index.cjs +23 -21
- package/dist/components/Slider/index.js +23 -21
- package/dist/components/Stack/Stack.module.scss.cjs +35 -35
- package/dist/components/Stack/Stack.module.scss.js +35 -35
- package/dist/components/Table/Table.module.scss.cjs +16 -16
- package/dist/components/Table/Table.module.scss.js +16 -16
- package/dist/components/Table/index.d.ts +0 -1
- package/dist/components/Table/index.d.ts.map +1 -1
- package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +7 -7
- package/dist/components/TableOfContents/TableOfContents.module.scss.js +7 -7
- package/dist/components/Tabs/Tabs.module.scss.cjs +9 -9
- package/dist/components/Tabs/Tabs.module.scss.js +9 -9
- package/dist/components/Text/Text.module.scss.cjs +38 -38
- package/dist/components/Text/Text.module.scss.js +38 -38
- package/dist/components/Textarea/Textarea.module.scss.cjs +23 -23
- package/dist/components/Textarea/Textarea.module.scss.js +23 -23
- package/dist/components/Theme/ThemeToggle.module.scss.cjs +6 -6
- package/dist/components/Theme/ThemeToggle.module.scss.js +6 -6
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.cjs +22 -22
- package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.js +22 -22
- package/dist/components/Toast/Toast.module.scss.cjs +20 -20
- package/dist/components/Toast/Toast.module.scss.js +20 -20
- package/dist/components/Toggle/Toggle.module.scss.cjs +13 -13
- package/dist/components/Toggle/Toggle.module.scss.js +13 -13
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +17 -17
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +17 -17
- package/dist/components/Tooltip/Tooltip.module.scss.cjs +3 -3
- package/dist/components/Tooltip/Tooltip.module.scss.js +3 -3
- package/dist/components/Tooltip/index.cjs +4 -3
- package/dist/components/Tooltip/index.d.ts +4 -1
- package/dist/components/Tooltip/index.d.ts.map +1 -1
- package/dist/components/Tooltip/index.js +4 -3
- package/dist/datepicker.cjs +0 -1
- package/dist/datepicker.js +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/markdown.cjs +0 -1
- package/dist/markdown.js +0 -1
- package/dist/table.cjs +0 -1
- package/dist/table.js +0 -1
- package/dist/utils/seed-derivation.cjs +29 -0
- package/dist/utils/seed-derivation.d.ts +1 -1
- package/dist/utils/seed-derivation.d.ts.map +1 -1
- package/dist/utils/seed-derivation.js +29 -0
- package/fragments.json +1 -1
- package/package.json +18 -14
- package/src/components/Button/Button.module.scss +24 -1
- package/src/components/Card/Card.module.scss +5 -1
- package/src/components/Chart/index.tsx +0 -1
- package/src/components/Chip/Chip.module.scss +4 -4
- package/src/components/CodeBlock/index.tsx +0 -1
- package/src/components/ColorPicker/index.tsx +0 -1
- package/src/components/Combobox/index.tsx +7 -8
- package/src/components/Command/Command.module.scss +22 -9
- package/src/components/DataTable/index.tsx +0 -2
- package/src/components/DatePicker/index.tsx +0 -2
- package/src/components/Drawer/Drawer.contract.json +1 -0
- package/src/components/Drawer/Drawer.module.scss +45 -5
- package/src/components/Drawer/index.tsx +66 -23
- package/src/components/Header/Header.contract.json +2 -0
- package/src/components/Input/Input.module.scss +16 -6
- package/src/components/Markdown/Markdown.module.scss +0 -3
- package/src/components/Markdown/index.tsx +0 -1
- package/src/components/Menu/Menu.module.scss +6 -0
- package/src/components/Menu/index.tsx +3 -1
- package/src/components/Message/Message.module.scss +2 -2
- package/src/components/NavigationMenu/NavigationMenu.module.scss +18 -23
- package/src/components/Pagination/Pagination.module.scss +1 -1
- package/src/components/Prompt/Prompt.module.scss +117 -3
- package/src/components/Prompt/index.tsx +40 -0
- package/src/components/Select/index.tsx +20 -25
- package/src/components/Sidebar/Sidebar.module.scss +1 -1
- package/src/components/Slider/index.tsx +10 -10
- package/src/components/Table/index.tsx +0 -2
- package/src/components/TableOfContents/TableOfContents.module.scss +19 -15
- package/src/components/Toggle/Toggle.module.scss +3 -3
- package/src/components/Tooltip/index.tsx +7 -3
- package/src/index.ts +8 -3
- package/src/styles/globals.scss +6 -1
- package/src/tokens/_computed.scss +3 -1
- package/src/tokens/_density.scss +4 -4
- package/src/tokens/_derive.scss +48 -55
- package/src/tokens/_palettes.scss +20 -1
- package/src/tokens/_seeds.scss +2 -2
- package/src/tokens/_variables.scss +45 -29
- package/src/utils/seed-derivation.ts +23 -1
|
@@ -36,6 +36,9 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
|
|
|
36
36
|
defaultOpen?: boolean;
|
|
37
37
|
/** Callback when open state changes */
|
|
38
38
|
onOpenChange?: (open: boolean) => void;
|
|
39
|
+
/** Whether clicking the trigger closes the tooltip.
|
|
40
|
+
* @default false */
|
|
41
|
+
closeOnClick?: boolean;
|
|
39
42
|
/** Explicit props for the tooltip popup element (preferred over top-level HTMLAttributes for clarity) */
|
|
40
43
|
contentProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
41
44
|
}
|
|
@@ -83,6 +86,7 @@ function TooltipRoot({
|
|
|
83
86
|
open,
|
|
84
87
|
defaultOpen,
|
|
85
88
|
onOpenChange,
|
|
89
|
+
closeOnClick = false,
|
|
86
90
|
contentProps,
|
|
87
91
|
className,
|
|
88
92
|
style,
|
|
@@ -113,8 +117,8 @@ function TooltipRoot({
|
|
|
113
117
|
[children],
|
|
114
118
|
);
|
|
115
119
|
|
|
116
|
-
if (disabled) {
|
|
117
|
-
return children;
|
|
120
|
+
if (disabled || !children) {
|
|
121
|
+
return children ?? null;
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
const {
|
|
@@ -129,7 +133,7 @@ function TooltipRoot({
|
|
|
129
133
|
defaultOpen={defaultOpen}
|
|
130
134
|
onOpenChange={onOpenChange}
|
|
131
135
|
>
|
|
132
|
-
<BaseTooltip.Trigger render={renderTrigger} />
|
|
136
|
+
<BaseTooltip.Trigger closeOnClick={closeOnClick} render={renderTrigger} />
|
|
133
137
|
<BaseTooltip.Portal>
|
|
134
138
|
<BaseTooltip.Positioner
|
|
135
139
|
side={side}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
1
|
+
// CSS variables and base styles are NOT auto-imported here.
|
|
2
|
+
// Consumers must import styles separately with seed configuration:
|
|
3
|
+
// @use '@fragments-sdk/ui/styles' with ($fui-brand: ..., $fui-neutral: ...);
|
|
4
|
+
// Bundling globals.scss here would compile with default seeds and
|
|
5
|
+
// override any consumer-configured palette.
|
|
4
6
|
|
|
5
7
|
// Runtime CSS detection — warns if component styles aren't loaded
|
|
6
8
|
import { checkCssLoaded } from './utils/css-warning';
|
|
@@ -404,6 +406,8 @@ export {
|
|
|
404
406
|
type PromptVariant,
|
|
405
407
|
type PromptTextareaProps,
|
|
406
408
|
type PromptToolbarProps,
|
|
409
|
+
type PromptTabsProps,
|
|
410
|
+
type PromptTabProps,
|
|
407
411
|
type PromptActionsProps,
|
|
408
412
|
type PromptInfoProps,
|
|
409
413
|
type PromptActionButtonProps,
|
|
@@ -591,6 +595,7 @@ export {
|
|
|
591
595
|
type DrawerBodyProps,
|
|
592
596
|
type DrawerFooterProps,
|
|
593
597
|
type DrawerCloseProps,
|
|
598
|
+
type DrawerSwipeAreaProps,
|
|
594
599
|
} from './components/Drawer';
|
|
595
600
|
|
|
596
601
|
// Pagination
|
package/src/styles/globals.scss
CHANGED
|
@@ -83,13 +83,18 @@ $fui-info: #3b82f6 !default;
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// Base Element Resets
|
|
86
|
-
:where(
|
|
86
|
+
// Use real specificity (not :where()) for font-size so it overrides
|
|
87
|
+
// the browser default 16px. This makes 1rem = 14px throughout.
|
|
88
|
+
html {
|
|
89
|
+
font-size: #{$fui-base-font-size};
|
|
87
90
|
scroll-behavior: smooth;
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
:where(body) {
|
|
91
94
|
margin: 0;
|
|
95
|
+
font-size: inherit;
|
|
92
96
|
font-family: var(--fui-font-sans, Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
|
|
97
|
+
line-height: var(--fui-line-height-normal, $fui-line-height-normal);
|
|
93
98
|
background-color: var(--fui-bg-primary, #ffffff);
|
|
94
99
|
color: var(--fui-text-primary, #171717);
|
|
95
100
|
-webkit-font-smoothing: antialiased;
|
|
@@ -86,6 +86,7 @@ $computed-sidebar-item-height: density.px-to-rem($_density, map.get($_density, s
|
|
|
86
86
|
|
|
87
87
|
// Accent colors (from brand seed)
|
|
88
88
|
$computed-color-accent: seeds.$fui-brand;
|
|
89
|
+
$computed-color-on-accent: derive.contrast-color(seeds.$fui-brand);
|
|
89
90
|
$computed-color-accent-hover: derive.derive-accent-hover(seeds.$fui-brand, false);
|
|
90
91
|
$computed-color-accent-active: derive.derive-accent-active(seeds.$fui-brand, false);
|
|
91
92
|
|
|
@@ -153,8 +154,9 @@ $computed-backdrop: derive.derive-backdrop(false);
|
|
|
153
154
|
// Computed: Colors - Dark Mode
|
|
154
155
|
// --------------------------------------------
|
|
155
156
|
|
|
156
|
-
// Accent colors
|
|
157
|
+
// Accent colors — dark brands lightened for visibility; on-accent handles text contrast
|
|
157
158
|
$computed-dark-color-accent: derive.derive-dark-accent(seeds.$fui-brand);
|
|
159
|
+
$computed-dark-color-on-accent: derive.contrast-color($computed-dark-color-accent);
|
|
158
160
|
$computed-dark-color-accent-hover: derive.derive-accent-hover($computed-dark-color-accent, true);
|
|
159
161
|
$computed-dark-color-accent-active: derive.derive-accent-active($computed-dark-color-accent, true);
|
|
160
162
|
|
package/src/tokens/_density.scss
CHANGED
|
@@ -59,8 +59,8 @@ $density-default: (
|
|
|
59
59
|
// Input height
|
|
60
60
|
input-height: 40px,
|
|
61
61
|
// ~6 units
|
|
62
|
-
input-height-sm:
|
|
63
|
-
// 4 units
|
|
62
|
+
input-height-sm: 32px,
|
|
63
|
+
// ~4.5 units
|
|
64
64
|
input-height-lg: 44px,
|
|
65
65
|
// ~6 units
|
|
66
66
|
// Touch targets (baseline)
|
|
@@ -70,8 +70,8 @@ $density-default: (
|
|
|
70
70
|
touch-lg: 44px,
|
|
71
71
|
// WCAG AAA recommended
|
|
72
72
|
// Sidebar navigation
|
|
73
|
-
sidebar-item-height:
|
|
74
|
-
// 5 units
|
|
73
|
+
sidebar-item-height: 36px,
|
|
74
|
+
// ~5 units
|
|
75
75
|
);
|
|
76
76
|
|
|
77
77
|
$density-relaxed: (
|
package/src/tokens/_derive.scss
CHANGED
|
@@ -20,14 +20,8 @@
|
|
|
20
20
|
/// @param {Color} $color - Color to check
|
|
21
21
|
/// @return {Boolean} True if dark
|
|
22
22
|
@function is-dark-color($color) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
$b: math.div(color.channel($color, 'blue', $space: rgb), 255);
|
|
26
|
-
|
|
27
|
-
// Relative luminance formula (simplified)
|
|
28
|
-
$luminance: 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
|
|
29
|
-
|
|
30
|
-
@return $luminance < 0.5;
|
|
23
|
+
// oklch lightness is perceptually uniform (0-1 range)
|
|
24
|
+
@return color.channel($color, 'lightness', $space: oklch) < 0.5;
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
/// Get appropriate contrast color (black or white)
|
|
@@ -52,22 +46,22 @@
|
|
|
52
46
|
/// @param {Boolean} $is-dark - Whether in dark mode
|
|
53
47
|
/// @return {Color} Hover state color
|
|
54
48
|
@function derive-accent-hover($base, $is-dark: false) {
|
|
55
|
-
$l: color.channel($base, 'lightness', $space:
|
|
49
|
+
$l: color.channel($base, 'lightness', $space: oklch);
|
|
56
50
|
|
|
57
51
|
@if $is-dark {
|
|
58
|
-
@if $l > 85
|
|
52
|
+
@if $l > 0.85 {
|
|
59
53
|
// Very light accent on dark bg: darken for visible hover
|
|
60
|
-
@return color.
|
|
54
|
+
@return color.adjust($base, $lightness: -0.05, $space: oklch);
|
|
61
55
|
}
|
|
62
56
|
// Standard dark mode: lighten for hover
|
|
63
|
-
@return color.
|
|
57
|
+
@return color.adjust($base, $lightness: 0.04, $space: oklch);
|
|
64
58
|
} @else {
|
|
65
|
-
@if $l < 15
|
|
59
|
+
@if $l < 0.15 {
|
|
66
60
|
// Very dark accent on light bg: lighten for visible hover
|
|
67
|
-
@return color.
|
|
61
|
+
@return color.adjust($base, $lightness: 0.09, $space: oklch);
|
|
68
62
|
}
|
|
69
63
|
// Standard light mode: darken for hover
|
|
70
|
-
@return color.
|
|
64
|
+
@return color.adjust($base, $lightness: -0.05, $space: oklch);
|
|
71
65
|
}
|
|
72
66
|
}
|
|
73
67
|
|
|
@@ -78,38 +72,36 @@
|
|
|
78
72
|
/// @param {Boolean} $is-dark - Whether in dark mode
|
|
79
73
|
/// @return {Color} Active state color
|
|
80
74
|
@function derive-accent-active($base, $is-dark: false) {
|
|
81
|
-
$l: color.channel($base, 'lightness', $space:
|
|
75
|
+
$l: color.channel($base, 'lightness', $space: oklch);
|
|
82
76
|
|
|
83
77
|
@if $is-dark {
|
|
84
|
-
@if $l > 85
|
|
78
|
+
@if $l > 0.85 {
|
|
85
79
|
// Very light accent on dark bg: darken more for active
|
|
86
|
-
@return color.
|
|
80
|
+
@return color.adjust($base, $lightness: -0.08, $space: oklch);
|
|
87
81
|
}
|
|
88
82
|
// Standard dark mode: lighten more for active
|
|
89
|
-
@return color.
|
|
83
|
+
@return color.adjust($base, $lightness: 0.07, $space: oklch);
|
|
90
84
|
} @else {
|
|
91
|
-
@if $l < 15
|
|
85
|
+
@if $l < 0.15 {
|
|
92
86
|
// Very dark accent on light bg: lighten more for active
|
|
93
|
-
@return color.
|
|
87
|
+
@return color.adjust($base, $lightness: 0.14, $space: oklch);
|
|
94
88
|
}
|
|
95
89
|
// Standard light mode: darken more for active
|
|
96
|
-
@return color.
|
|
90
|
+
@return color.adjust($base, $lightness: -0.09, $space: oklch);
|
|
97
91
|
}
|
|
98
92
|
}
|
|
99
93
|
|
|
100
94
|
/// Derive a light variant of accent for dark mode
|
|
101
|
-
///
|
|
95
|
+
/// Lightens dark brand colors so the accent stands out on dark backgrounds.
|
|
96
|
+
/// Clamps lightness to 0.45–0.85 and chroma to 0.12 to keep it muted.
|
|
102
97
|
/// @param {Color} $brand - Brand color
|
|
103
98
|
/// @return {Color} Lightened accent for dark mode
|
|
104
99
|
@function derive-dark-accent($brand) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// If brand is already light, use it as-is or slightly adjust
|
|
111
|
-
@return color.scale($brand, $lightness: 10%);
|
|
112
|
-
}
|
|
100
|
+
$l: color.channel($brand, 'lightness', $space: oklch);
|
|
101
|
+
$c: color.channel($brand, 'chroma', $space: oklch);
|
|
102
|
+
$clamped-l: math.max(0.45, math.min($l, 0.85));
|
|
103
|
+
$clamped-c: math.min($c, 0.12);
|
|
104
|
+
@return oklch($clamped-l $clamped-c color.channel($brand, 'hue', $space: oklch));
|
|
113
105
|
}
|
|
114
106
|
|
|
115
107
|
// --------------------------------------------
|
|
@@ -129,9 +121,9 @@
|
|
|
129
121
|
@for $i from 1 through 40 {
|
|
130
122
|
@if wcag-contrast($adjusted, $bg) < $target {
|
|
131
123
|
@if $is-dark {
|
|
132
|
-
$adjusted: color.adjust($adjusted, $lightness: 2
|
|
124
|
+
$adjusted: color.adjust($adjusted, $lightness: 2%, $space: oklch);
|
|
133
125
|
} @else {
|
|
134
|
-
$adjusted: color.adjust($adjusted, $lightness: -2
|
|
126
|
+
$adjusted: color.adjust($adjusted, $lightness: -2%, $space: oklch);
|
|
135
127
|
}
|
|
136
128
|
}
|
|
137
129
|
}
|
|
@@ -202,13 +194,14 @@
|
|
|
202
194
|
/// @return {Map} Text token values
|
|
203
195
|
@function derive-text($palette, $is-dark: false, $palette-name: 'stone') {
|
|
204
196
|
@if $is-dark {
|
|
205
|
-
// Dark mode:
|
|
197
|
+
// Dark mode: neutral white text on all palettes.
|
|
198
|
+
// Palette-tinted text (e.g. green-on-green-dark) looks muddy and reduces
|
|
199
|
+
// readability. Every major dark theme (Linear, Vercel, Stripe, GitHub)
|
|
200
|
+
// uses neutral white text regardless of background tint.
|
|
206
201
|
@return (
|
|
207
|
-
primary:
|
|
208
|
-
secondary:
|
|
209
|
-
|
|
210
|
-
// against palette[950] backgrounds (pure palette[500] gives ~4.1:1)
|
|
211
|
-
tertiary: color.mix(get-shade($palette, 500), get-shade($palette, 400), 10%),
|
|
202
|
+
primary: #ffffff,
|
|
203
|
+
secondary: rgba(255, 255, 255, 0.6),
|
|
204
|
+
tertiary: rgba(255, 255, 255, 0.4),
|
|
212
205
|
inverse: get-shade($palette, 900) // Text on light accents
|
|
213
206
|
);
|
|
214
207
|
}
|
|
@@ -239,16 +232,16 @@
|
|
|
239
232
|
/// @return {Map} Border token values
|
|
240
233
|
@function derive-borders($palette, $is-dark: false) {
|
|
241
234
|
@if $is-dark {
|
|
242
|
-
// Dark mode:
|
|
235
|
+
// Dark mode: subtle white-alpha borders
|
|
243
236
|
@return (
|
|
244
237
|
default: rgba(255, 255, 255, 0.08),
|
|
245
|
-
strong: rgba(255, 255, 255, 0.
|
|
238
|
+
strong: rgba(255, 255, 255, 0.15)
|
|
246
239
|
);
|
|
247
240
|
} @else {
|
|
248
|
-
// Light mode:
|
|
241
|
+
// Light mode: reduced opacity (ChatGPT --border-light ~5%)
|
|
249
242
|
@return (
|
|
250
|
-
default: rgba(0, 0, 0, 0.
|
|
251
|
-
strong: rgba(0, 0, 0, 0.
|
|
243
|
+
default: rgba(0, 0, 0, 0.05),
|
|
244
|
+
strong: rgba(0, 0, 0, 0.10)
|
|
252
245
|
);
|
|
253
246
|
}
|
|
254
247
|
}
|
|
@@ -262,18 +255,18 @@
|
|
|
262
255
|
/// @return {Map} Shadow token values
|
|
263
256
|
@function derive-shadows($is-dark: false) {
|
|
264
257
|
@if $is-dark {
|
|
265
|
-
// Dark mode:
|
|
258
|
+
// Dark mode: near-zero shadows (Linear uses borders, not shadows)
|
|
266
259
|
@return (
|
|
267
|
-
sm: (0 1px 2px 0 rgba(0, 0, 0, 0.
|
|
268
|
-
md: (0 2px 4px -1px rgba(0, 0, 0, 0.
|
|
269
|
-
lg: (0 8px 12px -3px rgba(0, 0, 0, 0.
|
|
260
|
+
sm: (0 1px 2px 0 rgba(0, 0, 0, 0.15)),
|
|
261
|
+
md: (0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 1px 3px -2px rgba(0, 0, 0, 0.15)),
|
|
262
|
+
lg: (0 8px 12px -3px rgba(0, 0, 0, 0.25), 0 3px 5px -4px rgba(0, 0, 0, 0.18))
|
|
270
263
|
);
|
|
271
264
|
} @else {
|
|
272
|
-
// Light mode:
|
|
265
|
+
// Light mode: flatter aesthetic (Linear/ChatGPT near-zero shadows)
|
|
273
266
|
@return (
|
|
274
|
-
sm: (0 1px 2px 0 rgba(0, 0, 0, 0.
|
|
275
|
-
md: (0 2px 4px -1px rgba(0, 0, 0, 0.
|
|
276
|
-
lg: (0 8px 12px -3px rgba(0, 0, 0, 0.
|
|
267
|
+
sm: (0 1px 2px 0 rgba(0, 0, 0, 0.02)),
|
|
268
|
+
md: (0 2px 4px -1px rgba(0, 0, 0, 0.04), 0 1px 3px -2px rgba(0, 0, 0, 0.03)),
|
|
269
|
+
lg: (0 8px 12px -3px rgba(0, 0, 0, 0.06), 0 3px 5px -4px rgba(0, 0, 0, 0.04))
|
|
277
270
|
);
|
|
278
271
|
}
|
|
279
272
|
}
|
|
@@ -324,7 +317,7 @@
|
|
|
324
317
|
/// @param {Color} $color - The semantic color
|
|
325
318
|
/// @return {Color} Hover state color
|
|
326
319
|
@function derive-semantic-hover($color) {
|
|
327
|
-
@return color.
|
|
320
|
+
@return color.adjust($color, $lightness: -0.05, $space: oklch);
|
|
328
321
|
}
|
|
329
322
|
|
|
330
323
|
// --------------------------------------------
|
|
@@ -424,9 +417,9 @@
|
|
|
424
417
|
@for $i from 1 through 40 {
|
|
425
418
|
@if wcag-contrast($adjusted, $bg) < $target {
|
|
426
419
|
@if $is-dark {
|
|
427
|
-
$adjusted: color.adjust($adjusted, $lightness: 2
|
|
420
|
+
$adjusted: color.adjust($adjusted, $lightness: 2%, $space: oklch);
|
|
428
421
|
} @else {
|
|
429
|
-
$adjusted: color.adjust($adjusted, $lightness: -2
|
|
422
|
+
$adjusted: color.adjust($adjusted, $lightness: -2%, $space: oklch);
|
|
430
423
|
}
|
|
431
424
|
}
|
|
432
425
|
}
|
|
@@ -83,6 +83,24 @@ $palette-earth: (
|
|
|
83
83
|
950: #0a0f08 // Very dark green-gray for dark mode bg
|
|
84
84
|
);
|
|
85
85
|
|
|
86
|
+
// --------------------------------------------
|
|
87
|
+
// Fragments - Rich saturated green tones
|
|
88
|
+
// The Fragments brand palette — deep forest greens
|
|
89
|
+
// --------------------------------------------
|
|
90
|
+
$palette-fragments: (
|
|
91
|
+
50: #f0f7f3,
|
|
92
|
+
100: #dceee3,
|
|
93
|
+
200: #b8ddc6,
|
|
94
|
+
300: #88c5a0,
|
|
95
|
+
400: #5aaa7a,
|
|
96
|
+
500: #3d8f60,
|
|
97
|
+
600: #2d7049,
|
|
98
|
+
700: #235536,
|
|
99
|
+
800: #1a3025, // Dark card surface
|
|
100
|
+
900: #142318, // Dark surface
|
|
101
|
+
950: #0d1f17 // Darkest bg
|
|
102
|
+
);
|
|
103
|
+
|
|
86
104
|
// --------------------------------------------
|
|
87
105
|
// Fire - Warm red/orange tones
|
|
88
106
|
// Energy, passion feel
|
|
@@ -110,6 +128,7 @@ $palettes: (
|
|
|
110
128
|
"sand": $palette-sand,
|
|
111
129
|
"earth": $palette-earth,
|
|
112
130
|
"fire": $palette-fire,
|
|
131
|
+
"fragments": $palette-fragments,
|
|
113
132
|
"wind": $palette-stone // Legacy alias — "wind" was renamed to "stone"
|
|
114
133
|
);
|
|
115
134
|
|
|
@@ -118,7 +137,7 @@ $palettes: (
|
|
|
118
137
|
// --------------------------------------------
|
|
119
138
|
|
|
120
139
|
/// Get a palette map by name
|
|
121
|
-
/// @param {String} $name - Palette name (stone, ice, sand, earth, fire)
|
|
140
|
+
/// @param {String} $name - Palette name (stone, ice, sand, earth, fire, fragments)
|
|
122
141
|
/// @return {Map} The palette map with shades 50-950
|
|
123
142
|
@function get-palette($name) {
|
|
124
143
|
@if not map.has-key($palettes, $name) {
|
package/src/tokens/_seeds.scss
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
$fui-brand: #18181b !default;
|
|
27
27
|
|
|
28
28
|
/// Neutral palette name for surfaces, text, and borders
|
|
29
|
-
/// Options: "stone" | "ice" | "earth" | "sand" | "fire"
|
|
29
|
+
/// Options: "stone" | "ice" | "earth" | "sand" | "fire" | "fragments"
|
|
30
30
|
/// @type String
|
|
31
31
|
$fui-neutral: "stone" !default;
|
|
32
32
|
|
|
@@ -45,7 +45,7 @@ $fui-radius-style: "default" !default;
|
|
|
45
45
|
// --------------------------------------------
|
|
46
46
|
// Fail fast at compile time if invalid seed values are provided.
|
|
47
47
|
|
|
48
|
-
$_valid-neutrals: "stone", "ice", "earth", "sand", "fire";
|
|
48
|
+
$_valid-neutrals: "stone", "ice", "earth", "sand", "fire", "fragments";
|
|
49
49
|
@if not list.index($_valid-neutrals, $fui-neutral) {
|
|
50
50
|
@error "Invalid $fui-neutral: '#{$fui-neutral}'. Must be one of: #{$_valid-neutrals}";
|
|
51
51
|
}
|
|
@@ -57,13 +57,15 @@ $fui-font-mono:
|
|
|
57
57
|
"Geist Mono", "SF Mono", SFMono-Regular, ui-monospace, "Cascadia Code", Menlo, monospace !default;
|
|
58
58
|
|
|
59
59
|
// Font sizes (rem based on 14px root)
|
|
60
|
+
// Compressed scale: base/md = 14px (1rem). No 16px step.
|
|
61
|
+
// Hierarchy driven by weight, not size jumps.
|
|
60
62
|
$fui-font-size-2xs: 0.714rem !default; // 10px
|
|
61
63
|
$fui-font-size-xs: 0.857rem !default; // 12px
|
|
62
64
|
$fui-font-size-sm: 1rem !default; // 14px (base)
|
|
63
|
-
$fui-font-size-base:
|
|
65
|
+
$fui-font-size-base: 1rem !default; // 14px (= sm, body base)
|
|
64
66
|
$fui-font-size-lg: 1.286rem !default; // 18px
|
|
65
|
-
$fui-font-size-xl: 1.
|
|
66
|
-
$fui-font-size-2xl:
|
|
67
|
+
$fui-font-size-xl: 1.429rem !default; // 20px
|
|
68
|
+
$fui-font-size-2xl: 1.714rem !default; // 24px
|
|
67
69
|
|
|
68
70
|
$fui-font-weight-normal: 400 !default;
|
|
69
71
|
$fui-font-weight-medium: 500 !default;
|
|
@@ -74,6 +76,10 @@ $fui-line-height-tight: 1.25 !default;
|
|
|
74
76
|
$fui-line-height-normal: 1.5 !default;
|
|
75
77
|
$fui-line-height-relaxed: 1.625 !default;
|
|
76
78
|
|
|
79
|
+
// Letter spacing (Linear-inspired tight tracking for headings)
|
|
80
|
+
$fui-letter-spacing-tight: -0.02em !default; // for xl+ headings
|
|
81
|
+
$fui-letter-spacing-normal: normal !default;
|
|
82
|
+
|
|
77
83
|
// --------------------------------------------
|
|
78
84
|
// Spacing (derived from density seed)
|
|
79
85
|
// --------------------------------------------
|
|
@@ -105,14 +111,15 @@ $fui-radius-full: computed.$computed-radius-full !default;
|
|
|
105
111
|
// --------------------------------------------
|
|
106
112
|
// Transitions
|
|
107
113
|
// --------------------------------------------
|
|
108
|
-
$fui-transition-fast:
|
|
109
|
-
$fui-transition-normal: 200ms
|
|
114
|
+
$fui-transition-fast: 160ms cubic-bezier(0.25, 0.46, 0.45, 0.94) !default; // Linear's easing
|
|
115
|
+
$fui-transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1) !default; // ChatGPT's easing
|
|
110
116
|
|
|
111
117
|
// --------------------------------------------
|
|
112
118
|
// Colors - Light Mode (derived from brand/neutral seeds)
|
|
113
119
|
// --------------------------------------------
|
|
114
120
|
// Accent colors (derived from $fui-brand seed)
|
|
115
121
|
$fui-color-accent: computed.$computed-color-accent !default;
|
|
122
|
+
$fui-color-on-accent: computed.$computed-color-on-accent !default;
|
|
116
123
|
$fui-color-accent-hover: computed.$computed-color-accent-hover !default;
|
|
117
124
|
$fui-color-accent-active: computed.$computed-color-accent-active !default;
|
|
118
125
|
|
|
@@ -174,8 +181,9 @@ $fui-scrollbar-thumb-hover: computed.$computed-scrollbar-thumb-hover !default;
|
|
|
174
181
|
// --------------------------------------------
|
|
175
182
|
// Colors - Dark Mode (derived from seeds)
|
|
176
183
|
// --------------------------------------------
|
|
177
|
-
// Accent colors (
|
|
184
|
+
// Accent colors (brand used directly in dark mode; on-accent handles text contrast)
|
|
178
185
|
$fui-dark-color-accent: computed.$computed-dark-color-accent !default;
|
|
186
|
+
$fui-dark-color-on-accent: computed.$computed-dark-color-on-accent !default;
|
|
179
187
|
$fui-dark-color-accent-hover: computed.$computed-dark-color-accent-hover !default;
|
|
180
188
|
$fui-dark-color-accent-active: computed.$computed-dark-color-accent-active !default;
|
|
181
189
|
|
|
@@ -265,15 +273,15 @@ $fui-touch-lg: computed.$computed-touch-lg !default;
|
|
|
265
273
|
$fui-target-size-min: 1.714rem !default; // 24px
|
|
266
274
|
$fui-target-size-comfortable: $fui-touch-md !default;
|
|
267
275
|
|
|
268
|
-
// Toggle/Switch (
|
|
269
|
-
$fui-toggle-width-sm:
|
|
270
|
-
$fui-toggle-width-md:
|
|
271
|
-
$fui-toggle-width-lg:
|
|
272
|
-
$fui-toggle-height-sm:
|
|
273
|
-
$fui-toggle-height-md:
|
|
274
|
-
$fui-toggle-height-lg:
|
|
275
|
-
$fui-toggle-thumb-sm:
|
|
276
|
-
$fui-toggle-thumb-md: 1.
|
|
276
|
+
// Toggle/Switch (web-proportioned: ~1.8:1 width:height ratio)
|
|
277
|
+
$fui-toggle-width-sm: 1.857rem !default; // 26px
|
|
278
|
+
$fui-toggle-width-md: 2.571rem !default; // 36px
|
|
279
|
+
$fui-toggle-width-lg: 3.286rem !default; // 46px
|
|
280
|
+
$fui-toggle-height-sm: 1.143rem !default; // 16px
|
|
281
|
+
$fui-toggle-height-md: 1.429rem !default; // 20px
|
|
282
|
+
$fui-toggle-height-lg: 1.857rem !default; // 26px
|
|
283
|
+
$fui-toggle-thumb-sm: 0.857rem !default; // 12px
|
|
284
|
+
$fui-toggle-thumb-md: 1.143rem !default; // 16px
|
|
277
285
|
$fui-toggle-thumb-offset: 2px !default; // Thumb inset from track edge
|
|
278
286
|
|
|
279
287
|
// Badge
|
|
@@ -430,6 +438,8 @@ $fui-dark-tooltip-shadow:
|
|
|
430
438
|
--fui-line-height-tight: #{$fui-line-height-tight};
|
|
431
439
|
--fui-line-height-normal: #{$fui-line-height-normal};
|
|
432
440
|
--fui-line-height-relaxed: #{$fui-line-height-relaxed};
|
|
441
|
+
--fui-letter-spacing-tight: #{$fui-letter-spacing-tight};
|
|
442
|
+
--fui-letter-spacing-normal: #{$fui-letter-spacing-normal};
|
|
433
443
|
|
|
434
444
|
// Spacing (micro)
|
|
435
445
|
--fui-space-px: #{$fui-space-px};
|
|
@@ -460,6 +470,7 @@ $fui-dark-tooltip-shadow:
|
|
|
460
470
|
|
|
461
471
|
// Colors — Accent (light-dark for automatic dark mode)
|
|
462
472
|
--fui-color-accent: light-dark(#{$fui-color-accent}, #{$fui-dark-color-accent});
|
|
473
|
+
--fui-color-on-accent: light-dark(#{$fui-color-on-accent}, #{$fui-dark-color-on-accent});
|
|
463
474
|
--fui-color-accent-hover: light-dark(#{$fui-color-accent-hover}, #{$fui-dark-color-accent-hover});
|
|
464
475
|
--fui-color-accent-active: light-dark(#{$fui-color-accent-active}, #{$fui-dark-color-accent-active});
|
|
465
476
|
|
|
@@ -506,7 +517,7 @@ $fui-dark-tooltip-shadow:
|
|
|
506
517
|
--fui-border-strong: light-dark(#{$fui-border-strong}, #{$fui-dark-border-strong});
|
|
507
518
|
|
|
508
519
|
// Form chrome (derived from theme surfaces + seed-driven accent)
|
|
509
|
-
--fui-field-bg:
|
|
520
|
+
--fui-field-bg: var(--fui-bg-tertiary);
|
|
510
521
|
--fui-field-bg-disabled: color-mix(in srgb, var(--fui-bg-tertiary) 88%, var(--fui-bg-primary));
|
|
511
522
|
--fui-field-border: color-mix(in srgb, var(--fui-border-strong) 78%, var(--fui-bg-primary));
|
|
512
523
|
--fui-field-border-hover: color-mix(in srgb, var(--fui-text-tertiary) 58%, var(--fui-border-strong));
|
|
@@ -590,18 +601,22 @@ $fui-dark-tooltip-shadow:
|
|
|
590
601
|
@supports (color: oklch(from red l c h)) {
|
|
591
602
|
:root {
|
|
592
603
|
// Accent derived from seed-brand
|
|
593
|
-
// Light mode: brand as-is
|
|
604
|
+
// Light mode: brand as-is. Dark mode: lightened for visibility on dark surfaces.
|
|
594
605
|
--fui-color-accent: light-dark(
|
|
595
606
|
var(--fui-seed-brand),
|
|
596
|
-
oklch(from var(--fui-seed-brand) clamp(0.
|
|
607
|
+
oklch(from var(--fui-seed-brand) clamp(0.45, l, 0.85) min(c, 0.12) h)
|
|
597
608
|
);
|
|
609
|
+
|
|
610
|
+
// Auto-contrast text for elements on accent backgrounds (buttons, chips, etc.)
|
|
611
|
+
// Lightness > 0.6 → dark text; otherwise → white. Users can override this token.
|
|
612
|
+
--fui-color-on-accent: oklch(from var(--fui-color-accent) calc(0 + (1 - clamp(0, calc((l - 0.6) * 999), 1))) 0 0);
|
|
598
613
|
--fui-color-accent-hover: light-dark(
|
|
599
614
|
oklch(from var(--fui-seed-brand) max(0.05, calc(l - 0.06)) c h),
|
|
600
|
-
oklch(from var(--fui-seed-brand) clamp(0.
|
|
615
|
+
oklch(from var(--fui-seed-brand) clamp(0.52, calc(l + 0.07), 0.90) min(c, 0.12) h)
|
|
601
616
|
);
|
|
602
617
|
--fui-color-accent-active: light-dark(
|
|
603
618
|
oklch(from var(--fui-seed-brand) max(0.05, calc(l - 0.12)) c h),
|
|
604
|
-
oklch(from var(--fui-seed-brand) clamp(0.
|
|
619
|
+
oklch(from var(--fui-seed-brand) clamp(0.40, calc(l - 0.05), 0.80) min(c, 0.12) h)
|
|
605
620
|
);
|
|
606
621
|
|
|
607
622
|
// Semantic hover derived from seed
|
|
@@ -626,23 +641,23 @@ $fui-dark-tooltip-shadow:
|
|
|
626
641
|
);
|
|
627
642
|
|
|
628
643
|
// Focus ring derived from seed-brand
|
|
629
|
-
--fui-focus-ring-color:
|
|
630
|
-
var(--fui-seed-brand),
|
|
631
|
-
oklch(from var(--fui-seed-brand) clamp(0.88, calc(1 - l + 0.1), 0.96) min(c, 0.05) h)
|
|
632
|
-
);
|
|
644
|
+
--fui-focus-ring-color: var(--fui-seed-brand);
|
|
633
645
|
}
|
|
634
646
|
|
|
635
647
|
// Runtime-derived dark mode overrides (replaces SCSS-computed when supported)
|
|
648
|
+
// Dark brands are lightened so the button stands out against dark backgrounds.
|
|
649
|
+
// Hover goes slightly lighter, active slightly darker. on-accent handles text.
|
|
636
650
|
:root[data-theme="dark"],
|
|
637
651
|
:root.dark {
|
|
638
|
-
--fui-color-accent: oklch(from var(--fui-seed-brand) clamp(0.
|
|
639
|
-
--fui-color-accent
|
|
640
|
-
--fui-color-accent-
|
|
652
|
+
--fui-color-accent: oklch(from var(--fui-seed-brand) clamp(0.45, l, 0.85) min(c, 0.12) h);
|
|
653
|
+
--fui-color-on-accent: oklch(from var(--fui-color-accent) calc(0 + (1 - clamp(0, calc((l - 0.6) * 999), 1))) 0 0);
|
|
654
|
+
--fui-color-accent-hover: oklch(from var(--fui-seed-brand) clamp(0.52, calc(l + 0.07), 0.90) min(c, 0.12) h);
|
|
655
|
+
--fui-color-accent-active: oklch(from var(--fui-seed-brand) clamp(0.40, calc(l - 0.05), 0.80) min(c, 0.12) h);
|
|
641
656
|
--fui-color-danger-bg: color-mix(in oklch, var(--fui-seed-danger) 15%, transparent);
|
|
642
657
|
--fui-color-success-bg: color-mix(in oklch, var(--fui-seed-success) 15%, transparent);
|
|
643
658
|
--fui-color-warning-bg: color-mix(in oklch, var(--fui-seed-warning) 15%, transparent);
|
|
644
659
|
--fui-color-info-bg: color-mix(in oklch, var(--fui-seed-info) 15%, transparent);
|
|
645
|
-
--fui-focus-ring-color:
|
|
660
|
+
--fui-focus-ring-color: var(--fui-seed-brand);
|
|
646
661
|
}
|
|
647
662
|
}
|
|
648
663
|
|
|
@@ -717,8 +732,9 @@ $fui-dark-tooltip-shadow:
|
|
|
717
732
|
|
|
718
733
|
// Private mixin for dark mode token values
|
|
719
734
|
@mixin _fui-dark-tokens {
|
|
720
|
-
// Accent colors
|
|
735
|
+
// Accent colors — brand used directly; on-accent handles text contrast
|
|
721
736
|
--fui-color-accent: #{$fui-dark-color-accent};
|
|
737
|
+
--fui-color-on-accent: #{$fui-dark-color-on-accent};
|
|
722
738
|
--fui-color-accent-hover: #{$fui-dark-color-accent-hover};
|
|
723
739
|
--fui-color-accent-active: #{$fui-dark-color-accent-active};
|
|
724
740
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// Types
|
|
14
14
|
// ============================================
|
|
15
15
|
|
|
16
|
-
export type NeutralPalette = 'stone' | 'ice' | 'sand' | 'earth' | 'fire';
|
|
16
|
+
export type NeutralPalette = 'stone' | 'ice' | 'sand' | 'earth' | 'fire' | 'fragments';
|
|
17
17
|
export type DensityPreset = 'compact' | 'default' | 'relaxed';
|
|
18
18
|
export type RadiusStyle = 'sharp' | 'subtle' | 'default' | 'rounded' | 'pill';
|
|
19
19
|
|
|
@@ -128,6 +128,21 @@ export const PALETTES: Record<NeutralPalette, PaletteShades> = {
|
|
|
128
128
|
900: '#1c100a', // Darkened and desaturated for dark mode
|
|
129
129
|
950: '#120a06', // Very dark warm gray for dark mode bg
|
|
130
130
|
},
|
|
131
|
+
// Fragments - Rich saturated green tones (the Fragments brand palette)
|
|
132
|
+
// Dark shades anchor to the Fragments marketing aesthetic
|
|
133
|
+
fragments: {
|
|
134
|
+
50: '#f0f7f3',
|
|
135
|
+
100: '#dceee3',
|
|
136
|
+
200: '#b8ddc6',
|
|
137
|
+
300: '#88c5a0',
|
|
138
|
+
400: '#5aaa7a',
|
|
139
|
+
500: '#3d8f60',
|
|
140
|
+
600: '#2d7049',
|
|
141
|
+
700: '#235536',
|
|
142
|
+
800: '#1a3025', // Dark card surface
|
|
143
|
+
900: '#142318', // Dark surface
|
|
144
|
+
950: '#0d1f17', // Darkest bg
|
|
145
|
+
},
|
|
131
146
|
};
|
|
132
147
|
|
|
133
148
|
// ============================================
|
|
@@ -181,6 +196,13 @@ export const PALETTE_SEMANTIC_COLORS: Record<NeutralPalette, SemanticColors> = {
|
|
|
181
196
|
danger: '#dc2626', // Red 600 (complements orange)
|
|
182
197
|
info: '#2563eb', // Blue 600
|
|
183
198
|
},
|
|
199
|
+
// Fragments - Brand-complementary semantic colors
|
|
200
|
+
fragments: {
|
|
201
|
+
success: '#39d98a', // Vibrant green (brand signature)
|
|
202
|
+
warning: '#f59e0b', // Amber 500
|
|
203
|
+
danger: '#ef4444', // Red 500
|
|
204
|
+
info: '#3b82f6', // Blue 500
|
|
205
|
+
},
|
|
184
206
|
};
|
|
185
207
|
|
|
186
208
|
/**
|