@wallarm-org/design-system 1.25.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,8 @@ export const App = () => {
37
37
  };
38
38
  ```
39
39
 
40
+ `ThemeProvider` also controls the Frame style (`useTheme().setFrameStyle`, `'neutral' | 'branded'`) - see [Installation Guide](docs/installation.md) for details.
41
+
40
42
  ```css
41
43
  /* App.css */
42
44
  @import 'tailwindcss';
@@ -1,5 +1,5 @@
1
1
  import { type NavRailMode } from '../../NavRail';
2
- import type { Theme } from '../../ThemeProvider';
2
+ import { type Theme } from '../../ThemeProvider';
3
3
  export type SidebarMode = 'adaptive' | 'expanded' | 'collapsed' | 'compact';
4
4
  /** Adaptive collapses the rail inside a product and expands it on Home; the other modes pin it. */
5
5
  export declare const railModeFor: (mode: SidebarMode, onHome: boolean) => NavRailMode;
@@ -1,10 +1,12 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Fragment } from "react";
3
3
  import { LogOut, PanelLeftDashed, PencilRuler, Settings, User, UserRound } from "../../../icons/index.js";
4
+ import { cn } from "../../../utils/cn.js";
4
5
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemContent, DropdownMenuItemIcon, DropdownMenuItemText, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuTriggerItem } from "../../DropdownMenu/index.js";
5
6
  import { NavRailItem } from "../../NavRail/index.js";
6
7
  import { HStack, VStack } from "../../Stack/index.js";
7
8
  import { Text } from "../../Text/index.js";
9
+ import { useTheme } from "../../ThemeProvider/index.js";
8
10
  const railModeFor = (mode, onHome)=>{
9
11
  if ('adaptive' === mode) return onHome ? 'expanded' : 'collapsed';
10
12
  return mode;
@@ -32,13 +34,27 @@ const THEME_LABELS = {
32
34
  light: 'Light',
33
35
  dark: 'Dark'
34
36
  };
37
+ const FRAME_STYLES = [
38
+ 'neutral',
39
+ 'branded'
40
+ ];
41
+ const FRAME_STYLE_LABELS = {
42
+ neutral: 'Neutral',
43
+ branded: 'Branded'
44
+ };
45
+ const FRAME_STYLE_SWATCH = {
46
+ neutral: 'bg-icon-secondary',
47
+ branded: 'bg-icon-brand'
48
+ };
35
49
  const SIDEBAR_MODE_LABELS = {
36
50
  adaptive: 'Adaptive',
37
51
  expanded: 'Always expanded',
38
52
  collapsed: 'Always collapsed',
39
53
  compact: 'Compact'
40
54
  };
41
- const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChange })=>/*#__PURE__*/ jsxs(DropdownMenu, {
55
+ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChange })=>{
56
+ const { frameStyle, setFrameStyle } = useTheme();
57
+ return /*#__PURE__*/ jsxs(DropdownMenu, {
42
58
  positioning: {
43
59
  placement: 'right-end',
44
60
  gutter: 6,
@@ -106,30 +122,60 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
106
122
  /*#__PURE__*/ jsx(DropdownMenuItemText, {
107
123
  children: "Appearance"
108
124
  }),
109
- /*#__PURE__*/ jsx(Text, {
125
+ /*#__PURE__*/ jsxs(Text, {
110
126
  size: "xs",
111
127
  color: "secondary",
112
- children: THEME_LABELS[theme]
128
+ children: [
129
+ THEME_LABELS[theme],
130
+ " and ",
131
+ FRAME_STYLE_LABELS[frameStyle].toLowerCase()
132
+ ]
113
133
  })
114
134
  ]
115
135
  })
116
136
  ]
117
137
  }),
118
- /*#__PURE__*/ jsx(DropdownMenuContent, {
138
+ /*#__PURE__*/ jsxs(DropdownMenuContent, {
119
139
  className: "w-132",
120
- children: /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
121
- value: theme,
122
- onValueChange: ({ value })=>{
123
- const next = THEMES.find((t)=>t === value);
124
- if (next) onThemeChange(next);
125
- },
126
- children: THEMES.map((t)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
127
- value: t,
128
- children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
129
- children: THEME_LABELS[t]
130
- })
131
- }, t))
132
- })
140
+ children: [
141
+ /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
142
+ value: theme,
143
+ onValueChange: ({ value })=>{
144
+ const next = THEMES.find((t)=>t === value);
145
+ if (next) onThemeChange(next);
146
+ },
147
+ children: THEMES.map((t)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
148
+ value: t,
149
+ children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
150
+ children: THEME_LABELS[t]
151
+ })
152
+ }, t))
153
+ }),
154
+ /*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
155
+ /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
156
+ value: frameStyle,
157
+ onValueChange: ({ value })=>{
158
+ const next = FRAME_STYLES.find((s)=>s === value);
159
+ if (next) setFrameStyle(next);
160
+ },
161
+ children: FRAME_STYLES.map((s)=>/*#__PURE__*/ jsxs(DropdownMenuRadioItem, {
162
+ value: s,
163
+ children: [
164
+ /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
165
+ children: /*#__PURE__*/ jsx("span", {
166
+ className: "flex size-16 items-center justify-center",
167
+ children: /*#__PURE__*/ jsx("span", {
168
+ className: cn('size-8 rounded-full', FRAME_STYLE_SWATCH[s])
169
+ })
170
+ })
171
+ }),
172
+ /*#__PURE__*/ jsx(DropdownMenuItemText, {
173
+ children: FRAME_STYLE_LABELS[s]
174
+ })
175
+ ]
176
+ }, s))
177
+ })
178
+ ]
133
179
  })
134
180
  ]
135
181
  }),
@@ -192,4 +238,5 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
192
238
  })
193
239
  ]
194
240
  });
241
+ };
195
242
  export { AccountDropdown, railModeFor };
@@ -4,7 +4,7 @@ import { cn } from "../../utils/cn.js";
4
4
  import { useTestId } from "../../utils/testId.js";
5
5
  import { Text } from "../Text/index.js";
6
6
  import { navPanelGroupItemVariants } from "./classes.js";
7
- import { useNavPanelDepth, useNavPanelIndent } from "./NavPanelContext.js";
7
+ import { NAV_PANEL_BASE_PADDING, useNavPanelDepth, useNavPanelIndent } from "./NavPanelContext.js";
8
8
  const NavPanelGroupItem = ({ ref, asChild = false, icon: Icon, active = false, className, children, ...props })=>{
9
9
  const testId = useTestId('group-item');
10
10
  const depth = useNavPanelDepth();
@@ -33,6 +33,13 @@ const NavPanelGroupItem = ({ ref, asChild = false, icon: Icon, active = false, c
33
33
  size: "sm",
34
34
  truncate: true,
35
35
  children: children
36
+ }),
37
+ active && depth > 0 && /*#__PURE__*/ jsx("span", {
38
+ "aria-hidden": true,
39
+ className: "absolute top-0 bottom-0 hidden w-px bg-border-brand branded:block",
40
+ style: {
41
+ left: depth * indent - NAV_PANEL_BASE_PADDING
42
+ }
36
43
  })
37
44
  ]
38
45
  });
@@ -2,7 +2,7 @@ import { cva } from "class-variance-authority";
2
2
  const navPanelItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 p-8 text-sm text-text-primary transition-colors outline-none', {
3
3
  variants: {
4
4
  active: {
5
- true: 'overlay-states-primary-active font-semibold',
5
+ true: 'overlay-states-primary-active font-semibold branded:overlay-states-brand-active branded:text-text-brand',
6
6
  false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
7
7
  }
8
8
  },
@@ -13,7 +13,7 @@ const navPanelItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-point
13
13
  const navPanelGroupItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 py-8 pr-8 text-sm text-text-primary transition-colors outline-none', {
14
14
  variants: {
15
15
  active: {
16
- true: 'overlay-states-primary-active font-semibold',
16
+ true: 'overlay-states-primary-active font-semibold branded:overlay-states-brand-active branded:text-text-brand',
17
17
  false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
18
18
  }
19
19
  },
@@ -31,14 +31,15 @@ const NavRailItem = ({ ref, asChild = false, icon: Icon, label, shortcut, active
31
31
  "data-testid": testId,
32
32
  className: cn(navRailItemVariants({
33
33
  mode,
34
- active
34
+ active,
35
+ avatar: hasPlate
35
36
  }), className),
36
37
  children: [
37
38
  /*#__PURE__*/ jsx("span", {
38
39
  className: "flex shrink-0 items-center justify-center",
39
40
  children: hasPlate ? /*#__PURE__*/ jsxs("span", {
40
41
  "data-slot": "nav-rail-item-avatar",
41
- className: cn('-m-4 grid size-24 place-items-center overflow-hidden rounded-8 bg-states-primary-hover *:col-start-1 *:row-start-1', !photo && 'border border-border-primary'),
42
+ className: cn('-m-4 grid size-24 place-items-center overflow-hidden rounded-8 bg-states-primary-hover branded:bg-states-brand-hover branded:text-icon-brand *:col-start-1 *:row-start-1', !photo && 'border border-border-primary branded:border-border-brand'),
42
43
  children: [
43
44
  /*#__PURE__*/ jsx(Icon, {
44
45
  size: "md"
@@ -13,5 +13,6 @@ export declare const navRailSkeletonVariants: (props?: ({
13
13
  export declare const navRailItemVariants: (props?: ({
14
14
  mode?: "collapsed" | "compact" | "expanded" | null | undefined;
15
15
  active?: boolean | null | undefined;
16
+ avatar?: boolean | null | undefined;
16
17
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
17
18
  export declare const navRailItemCompactLabelClassName = "line-clamp-2 w-56 shrink-0 text-center text-2xs font-medium text-ellipsis break-normal";
@@ -52,13 +52,18 @@ const navRailItemVariants = cva('overlay flex w-full cursor-pointer items-center
52
52
  compact: 'min-h-42 flex-col justify-center gap-2 px-8 py-6'
53
53
  },
54
54
  active: {
55
- true: 'overlay-states-primary-active',
55
+ true: 'overlay-states-primary-active branded:overlay-states-brand-active branded:data-[state=open]:overlay-states-brand-active branded:text-text-brand',
56
56
  false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
57
+ },
58
+ avatar: {
59
+ true: 'branded:hover:overlay-states-brand-hover branded:focus-visible:overlay-states-brand-hover branded:active:overlay-states-brand-pressed branded:data-[state=open]:overlay-states-brand-active',
60
+ false: ''
57
61
  }
58
62
  },
59
63
  defaultVariants: {
60
64
  mode: 'expanded',
61
- active: false
65
+ active: false,
66
+ avatar: false
62
67
  }
63
68
  });
64
69
  const navRailItemCompactLabelClassName = 'line-clamp-2 w-56 shrink-0 text-center text-2xs font-medium text-ellipsis break-normal';
@@ -1,9 +1,12 @@
1
1
  import { type FC, type ReactNode } from 'react';
2
- import type { Theme } from './types';
2
+ import type { FrameStyle, Theme } from './types';
3
3
  interface ThemeProviderProps {
4
4
  children: ReactNode;
5
5
  defaultTheme?: Theme;
6
6
  storageKey?: string;
7
+ /** Frame style used until the user picks one. */
8
+ defaultFrameStyle?: FrameStyle;
9
+ frameStyleStorageKey?: string;
7
10
  }
8
11
  export declare const ThemeProvider: FC<ThemeProviderProps>;
9
12
  export {};
@@ -1,23 +1,39 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from "react";
3
3
  import { ThemeProviderContext } from "./ThemeProviderContext.js";
4
- const ThemeProvider = ({ children, defaultTheme = 'light', storageKey = 'wasd-theme', ...props })=>{
4
+ const ThemeProvider = ({ children, defaultTheme = 'light', storageKey = 'wasd-theme', defaultFrameStyle = 'neutral', frameStyleStorageKey = 'wasd-frame-style', ...props })=>{
5
5
  const [theme, setTheme] = useState(()=>localStorage.getItem(storageKey) || defaultTheme);
6
+ const [frameStyle, setFrameStyle] = useState(()=>{
7
+ const stored = localStorage.getItem(frameStyleStorageKey);
8
+ return 'neutral' === stored || 'branded' === stored ? stored : defaultFrameStyle;
9
+ });
6
10
  useEffect(()=>{
7
11
  const root = window.document.documentElement;
8
12
  root.setAttribute('data-theme', theme);
9
13
  }, [
10
14
  theme
11
15
  ]);
16
+ useEffect(()=>{
17
+ window.document.documentElement.setAttribute('data-frame-style', frameStyle);
18
+ }, [
19
+ frameStyle
20
+ ]);
12
21
  const value = useMemo(()=>({
13
22
  theme,
14
23
  setTheme: (theme)=>{
15
24
  localStorage.setItem(storageKey, theme);
16
25
  setTheme(theme);
26
+ },
27
+ frameStyle,
28
+ setFrameStyle: (frameStyle)=>{
29
+ localStorage.setItem(frameStyleStorageKey, frameStyle);
30
+ setFrameStyle(frameStyle);
17
31
  }
18
32
  }), [
19
33
  theme,
20
- storageKey
34
+ storageKey,
35
+ frameStyle,
36
+ frameStyleStorageKey
21
37
  ]);
22
38
  return /*#__PURE__*/ jsx(ThemeProviderContext.Provider, {
23
39
  ...props,
@@ -1,6 +1,8 @@
1
- import type { Theme } from './types';
1
+ import type { FrameStyle, Theme } from './types';
2
2
  export interface ThemeProviderState {
3
3
  theme: Theme;
4
4
  setTheme: (theme: Theme) => void;
5
+ frameStyle: FrameStyle;
6
+ setFrameStyle: (frameStyle: FrameStyle) => void;
5
7
  }
6
8
  export declare const ThemeProviderContext: import("react").Context<ThemeProviderState>;
@@ -1,6 +1,8 @@
1
1
  import { createContext } from "react";
2
2
  const ThemeProviderContext = createContext({
3
3
  theme: 'light',
4
- setTheme: ()=>null
4
+ setTheme: ()=>null,
5
+ frameStyle: 'neutral',
6
+ setFrameStyle: ()=>null
5
7
  });
6
8
  export { ThemeProviderContext };
@@ -1,3 +1,3 @@
1
1
  export { ThemeProvider } from './ThemeProvider';
2
- export type { Theme } from './types';
2
+ export type { FrameStyle, Theme } from './types';
3
3
  export { useTheme } from './useTheme';
@@ -1 +1,3 @@
1
1
  export type Theme = 'dark' | 'light';
2
+ /** The Frame's look inside a theme: the neutral gray surround, or the warm branded one. */
3
+ export type FrameStyle = 'neutral' | 'branded';
package/dist/index.d.ts CHANGED
@@ -87,7 +87,7 @@ export { Tabs, TabsButton, TabsContent, TabsLineActions, TabsList, TabsSeparator
87
87
  export { Tag, TagClose, type TagProps } from './components/Tag';
88
88
  export { Text, type TextProps } from './components/Text';
89
89
  export { Textarea, type TextareaProps } from './components/Textarea';
90
- export { type Theme, ThemeProvider, useTheme, } from './components/ThemeProvider';
90
+ export { type FrameStyle, type Theme, ThemeProvider, useTheme, } from './components/ThemeProvider';
91
91
  export { TimeInput, type TimeInputProps } from './components/TimeInput';
92
92
  export { Timeline, TimelineConnector, type TimelineConnectorProps, TimelineContent, type TimelineContentProps, TimelineDescription, type TimelineDescriptionProps, TimelineIndicator, type TimelineIndicatorProps, TimelineItem, type TimelineItemProps, type TimelineProps, TimelineSeparator, type TimelineSeparatorProps, TimelineTitle, type TimelineTitleProps, } from './components/Timeline';
93
93
  export { Toast, ToastActions, Toaster, toaster } from './components/Toast';
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.24.0",
3
- "generatedAt": "2026-09-28T08:13:10.040Z",
2
+ "version": "1.25.0",
3
+ "generatedAt": "2026-09-28T09:09:05.490Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
@@ -45049,6 +45049,14 @@
45049
45049
  "false"
45050
45050
  ],
45051
45051
  "defaultValue": "false"
45052
+ },
45053
+ {
45054
+ "name": "avatar",
45055
+ "options": [
45056
+ "true",
45057
+ "false"
45058
+ ],
45059
+ "defaultValue": "false"
45052
45060
  }
45053
45061
  ],
45054
45062
  "subComponents": [
@@ -102204,6 +102212,10 @@
102204
102212
  "name": "--color-component-app-shell-bg",
102205
102213
  "value": "var(--color-slate-100)"
102206
102214
  },
102215
+ {
102216
+ "name": "--color-component-app-shell-bg-branded",
102217
+ "value": "var(--color-w-orange-50)"
102218
+ },
102207
102219
  {
102208
102220
  "name": "--color-component-app-shell-ambient-dot",
102209
102221
  "value": "--alpha(var(--color-slate-500) / 28%)"
@@ -103282,6 +103294,10 @@
103282
103294
  "name": "--color-component-app-shell-bg",
103283
103295
  "value": "var(--color-slate-975)"
103284
103296
  },
103297
+ {
103298
+ "name": "--color-component-app-shell-bg-branded",
103299
+ "value": "#160e1a"
103300
+ },
103285
103301
  {
103286
103302
  "name": "--color-component-app-shell-ambient-dot",
103287
103303
  "value": "--alpha(var(--color-slate-50) / 15%)"
@@ -40,6 +40,17 @@
40
40
  --app-shell-ambient-grain-blend: screen;
41
41
  }
42
42
 
43
+ /* Branded Frame (WDS-182): multiplying or screening gray noise over the warm base dulls it
44
+ toward gray. Soft-light adds the same texture and keeps the orange. */
45
+ :root[data-frame-style='branded'] {
46
+ --app-shell-ambient-grain-opacity: 0.6;
47
+ --app-shell-ambient-grain-blend: soft-light;
48
+ }
49
+
50
+ :root[data-theme='dark'][data-frame-style='branded'] {
51
+ --app-shell-ambient-grain-opacity: 0.35;
52
+ }
53
+
43
54
  @utility app-shell-ambient {
44
55
  position: absolute;
45
56
  inset: 0;
@@ -31,6 +31,10 @@
31
31
  @import './components/app-shell.css';
32
32
  @import './components/chart.css';
33
33
 
34
+ /* Frame style (WDS-182): styles that apply only while the user has picked the Branded Frame.
35
+ ThemeProvider writes `data-frame-style` on <html>, so this reaches every micro-frontend. */
36
+ @custom-variant branded (&:where([data-frame-style='branded'] *));
37
+
34
38
  [data-scope='scroll-area'][data-part='viewport'] {
35
39
  scrollbar-width: none;
36
40
  &::-webkit-scrollbar {
@@ -215,6 +215,11 @@
215
215
  --color-component-toast-ic-success: var(--color-green-400);
216
216
  --color-component-toast-ic-info: var(--color-blue-400);
217
217
  --color-component-app-shell-bg: var(--color-slate-100);
218
+ /* Branded Frame (WDS-182): the Frame fill when the user picks the Branded Frame style.
219
+ * Swapped in for the token above under `[data-frame-style='branded']` (end of file), so
220
+ * AppShell follows with no component change; the Ambient tones below get their own
221
+ * Branded recipe at the end of the file. */
222
+ --color-component-app-shell-bg-branded: var(--color-w-orange-50);
218
223
 
219
224
  /* AppShell Frame ambient — the soft spots and dot raster painted into the
220
225
  * Frame (header + rail). Every tone derives from the Frame token above, so
@@ -661,6 +666,7 @@
661
666
  --color-component-toast-ic-success: var(--color-green-600);
662
667
  --color-component-toast-ic-info: var(--color-blue-600);
663
668
  --color-component-app-shell-bg: var(--color-slate-975);
669
+ --color-component-app-shell-bg-branded: #160e1a;
664
670
 
665
671
  /* AppShell Frame ambient (dark) — on a near-black base only lifts read, so
666
672
  * every spot mixes toward white. */
@@ -876,3 +882,76 @@
876
882
  --color-data-viz-1: #ffffff;
877
883
  --temp-token: #ffffff;
878
884
  }
885
+
886
+ /* ========================================
887
+ * FRAME STYLE: BRANDED (WDS-182)
888
+ * ThemeProvider writes `data-frame-style` on <html>. Branded is not a value swap like
889
+ * dark: components switch to the existing brand tokens through the `branded:` variant
890
+ * (index.css). Only the Frame base and the Ambient tones change here. These rules are
891
+ * unlayered, so they beat the light theme values in `@layer theme`; the doubled
892
+ * specificity of `:root[...]` beats `[data-theme='dark']`.
893
+ *
894
+ * The neutral Ambient recipe mixes the base toward white/black in oklch. The achromatic
895
+ * end has no hue, so on a pale orange base the tones lose theirs and read gray. Branded
896
+ * tints the spots toward the brand oranges in oklab instead, which keeps the hue, and
897
+ * lifts only part-way to white so they stay warm. The grain's blend lives in app-shell.css.
898
+ * ======================================== */
899
+ :root[data-frame-style='branded'] {
900
+ --color-component-app-shell-bg: var(--color-component-app-shell-bg-branded);
901
+ --color-component-app-shell-ambient-lift: color-mix(
902
+ in oklab,
903
+ var(--color-component-app-shell-bg),
904
+ white 40%
905
+ );
906
+ --color-component-app-shell-ambient-lift-soft: color-mix(
907
+ in srgb,
908
+ color-mix(in oklab, var(--color-component-app-shell-bg), white 25%) 70%,
909
+ transparent
910
+ );
911
+ --color-component-app-shell-ambient-shade: color-mix(
912
+ in srgb,
913
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-300) 30%) 70%,
914
+ transparent
915
+ );
916
+ --color-component-app-shell-ambient-shade-soft: color-mix(
917
+ in srgb,
918
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-200) 30%) 65%,
919
+ transparent
920
+ );
921
+ --color-component-app-shell-ambient-header: color-mix(
922
+ in srgb,
923
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-300) 25%) 22%,
924
+ transparent
925
+ );
926
+ --color-component-app-shell-ambient-dot: --alpha(var(--color-w-orange-500) / 28%);
927
+ }
928
+
929
+ /* Dark: only a faint warm glow toward the deepest brand oranges, as quiet as the neutral lifts. */
930
+ :root[data-theme='dark'][data-frame-style='branded'] {
931
+ --color-component-app-shell-ambient-lift: color-mix(
932
+ in srgb,
933
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-900) 10%) 95%,
934
+ transparent
935
+ );
936
+ --color-component-app-shell-ambient-lift-soft: color-mix(
937
+ in srgb,
938
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-900) 14%) 70%,
939
+ transparent
940
+ );
941
+ --color-component-app-shell-ambient-shade: color-mix(
942
+ in srgb,
943
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-900) 12%) 60%,
944
+ transparent
945
+ );
946
+ --color-component-app-shell-ambient-shade-soft: color-mix(
947
+ in srgb,
948
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-950) 18%) 95%,
949
+ transparent
950
+ );
951
+ --color-component-app-shell-ambient-header: color-mix(
952
+ in srgb,
953
+ color-mix(in oklab, var(--color-component-app-shell-bg), var(--color-w-orange-900) 10%) 30%,
954
+ transparent
955
+ );
956
+ --color-component-app-shell-ambient-dot: --alpha(var(--color-w-orange-300) / 15%);
957
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",