gbs-add-block 1.2.15 → 1.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +2 -2
  2. package/index.cjs +219 -21
  3. package/package.json +1 -1
  4. package/source/beta-components/breadcrumb/react/props.ts +2 -2
  5. package/source/beta-components/breadcrumb/styles.css +8 -8
  6. package/source/beta-components/button/react/props.ts +2 -2
  7. package/source/beta-components/button/styles.css +15 -15
  8. package/source/beta-components/card/README.md +60 -0
  9. package/source/beta-components/card/__tests__/core.test.ts +57 -0
  10. package/source/beta-components/card/core/index.ts +4 -0
  11. package/source/beta-components/card/core/trend.ts +32 -0
  12. package/source/beta-components/card/core/types.ts +5 -0
  13. package/source/beta-components/card/index.ts +5 -0
  14. package/source/beta-components/card/react/Card.tsx +133 -0
  15. package/source/beta-components/card/react/Stat.tsx +127 -0
  16. package/source/beta-components/card/react/props.ts +4 -0
  17. package/source/beta-components/card/styles.css +231 -0
  18. package/source/beta-components/checkbox/react/Checkbox.tsx +147 -146
  19. package/source/beta-components/checkbox/react/CheckboxGroup.tsx +8 -8
  20. package/source/beta-components/checkbox/react/props.ts +2 -2
  21. package/source/beta-components/checkbox/styles.css +11 -11
  22. package/source/beta-components/combobox/README.md +3 -3
  23. package/source/beta-components/combobox/react/MultiSelect.tsx +265 -263
  24. package/source/beta-components/combobox/react/Popover.tsx +38 -70
  25. package/source/beta-components/combobox/react/Select.tsx +200 -198
  26. package/source/beta-components/combobox/react/icons.tsx +6 -29
  27. package/source/beta-components/combobox/react/props.ts +4 -2
  28. package/source/beta-components/combobox/styles.css +18 -18
  29. package/source/beta-components/data-grid/react/Popover.tsx +35 -0
  30. package/source/beta-components/{datagrid → data-grid}/react/context.ts +2 -2
  31. package/source/beta-components/{datagrid → data-grid}/react/icons.tsx +8 -35
  32. package/source/beta-components/{datagrid → data-grid}/styles.css +24 -24
  33. package/source/beta-components/{datepicker → date-picker}/README.md +3 -3
  34. package/source/beta-components/{datepicker → date-picker}/react/DatePicker.tsx +249 -249
  35. package/source/beta-components/{datepicker → date-picker}/react/DateRangePicker.tsx +291 -291
  36. package/source/beta-components/date-picker/react/Popover.tsx +45 -0
  37. package/source/beta-components/date-picker/react/icons.tsx +15 -0
  38. package/source/beta-components/{datepicker → date-picker}/react/props.ts +2 -2
  39. package/source/beta-components/{datepicker → date-picker}/styles.css +18 -18
  40. package/source/beta-components/dialog/react/icons.tsx +16 -47
  41. package/source/beta-components/dialog/react/props.ts +2 -2
  42. package/source/beta-components/dialog/styles.css +21 -21
  43. package/source/beta-components/{fileuploader → file-uploader}/react/FileUploader.tsx +511 -515
  44. package/source/beta-components/{fileuploader → file-uploader}/react/icons.tsx +7 -27
  45. package/source/beta-components/{fileuploader → file-uploader}/react/props.ts +2 -2
  46. package/source/beta-components/{fileuploader → file-uploader}/styles.css +17 -17
  47. package/source/beta-components/input/core/count.ts +3 -12
  48. package/source/beta-components/input/react/Input.tsx +219 -219
  49. package/source/beta-components/input/react/OtpInput.tsx +256 -256
  50. package/source/beta-components/input/react/icons.tsx +3 -21
  51. package/source/beta-components/input/react/props.ts +2 -2
  52. package/source/beta-components/input/styles.css +15 -15
  53. package/source/beta-components/menu/README.md +68 -0
  54. package/source/beta-components/menu/__tests__/core.test.ts +120 -0
  55. package/source/beta-components/menu/core/index.ts +11 -0
  56. package/source/beta-components/menu/core/navigation.ts +84 -0
  57. package/source/beta-components/menu/core/types.ts +32 -0
  58. package/source/beta-components/menu/index.ts +19 -0
  59. package/source/beta-components/menu/react/Menu.tsx +371 -0
  60. package/source/beta-components/menu/react/context.ts +31 -0
  61. package/source/beta-components/menu/react/items.tsx +268 -0
  62. package/source/beta-components/menu/react/locale.ts +6 -0
  63. package/source/beta-components/menu/react/props.ts +4 -0
  64. package/source/beta-components/menu/react/useMenuKeys.ts +124 -0
  65. package/source/beta-components/menu/styles.css +222 -0
  66. package/source/beta-components/modal/react/Modal.tsx +242 -238
  67. package/source/beta-components/modal/react/icons.tsx +1 -19
  68. package/source/beta-components/modal/react/props.ts +2 -2
  69. package/source/beta-components/modal/styles.css +17 -13
  70. package/source/beta-components/popover/README.md +44 -0
  71. package/source/beta-components/popover/core/index.ts +2 -0
  72. package/source/beta-components/popover/core/types.ts +12 -0
  73. package/source/beta-components/popover/index.ts +4 -0
  74. package/source/beta-components/popover/react/Popover.tsx +202 -0
  75. package/source/beta-components/popover/react/locale.ts +5 -0
  76. package/source/beta-components/popover/react/props.ts +4 -0
  77. package/source/beta-components/popover/styles.css +146 -0
  78. package/source/beta-components/shared/README.md +54 -0
  79. package/source/beta-components/shared/__tests__/boundaries.test.ts +95 -0
  80. package/source/beta-components/shared/__tests__/core.test.ts +55 -0
  81. package/source/beta-components/shared/__tests__/position.test.ts +143 -0
  82. package/source/beta-components/shared/core/cx.ts +9 -0
  83. package/source/beta-components/shared/core/field.ts +35 -0
  84. package/source/beta-components/shared/core/position.ts +124 -0
  85. package/source/beta-components/shared/core/text.ts +14 -0
  86. package/source/beta-components/shared/index.ts +8 -0
  87. package/source/beta-components/shared/react/Popover.tsx +189 -0
  88. package/source/beta-components/shared/react/icons.tsx +74 -0
  89. package/source/beta-components/shared/react/useControllableState.ts +42 -0
  90. package/source/beta-components/shared/version.json +4 -0
  91. package/source/beta-components/shared/version.ts +6 -0
  92. package/source/beta-components/skeleton/README.md +58 -0
  93. package/source/beta-components/skeleton/__tests__/core.test.ts +41 -0
  94. package/source/beta-components/skeleton/core/index.ts +3 -0
  95. package/source/beta-components/skeleton/core/lines.ts +25 -0
  96. package/source/beta-components/skeleton/core/types.ts +5 -0
  97. package/source/beta-components/skeleton/index.ts +5 -0
  98. package/source/beta-components/skeleton/react/Empty.tsx +51 -0
  99. package/source/beta-components/skeleton/react/Skeleton.tsx +92 -0
  100. package/source/beta-components/skeleton/react/props.ts +4 -0
  101. package/source/beta-components/skeleton/styles.css +186 -0
  102. package/source/beta-components/spinner/react/props.ts +2 -2
  103. package/source/beta-components/spinner/styles.css +174 -167
  104. package/source/beta-components/tabs/react/Tabs.tsx +306 -260
  105. package/source/beta-components/tabs/styles.css +264 -257
  106. package/source/beta-components/textarea/core/count.ts +3 -12
  107. package/source/beta-components/textarea/react/Textarea.tsx +208 -209
  108. package/source/beta-components/textarea/react/props.ts +2 -2
  109. package/source/beta-components/textarea/styles.css +12 -12
  110. package/source/beta-components/toaster/react/icons.tsx +19 -52
  111. package/source/beta-components/toaster/react/props.ts +2 -2
  112. package/source/beta-components/toaster/styles.css +18 -18
  113. package/source/beta-components/tooltip/README.md +43 -0
  114. package/source/beta-components/tooltip/__tests__/core.test.ts +42 -0
  115. package/source/beta-components/tooltip/core/index.ts +4 -0
  116. package/source/beta-components/tooltip/core/types.ts +4 -0
  117. package/source/beta-components/tooltip/core/visibility.ts +34 -0
  118. package/source/beta-components/tooltip/index.ts +3 -0
  119. package/source/beta-components/tooltip/react/Tooltip.tsx +196 -0
  120. package/source/beta-components/tooltip/react/props.ts +4 -0
  121. package/source/beta-components/tooltip/styles.css +72 -0
  122. package/source/beta-components/datagrid/react/Popover.tsx +0 -79
  123. package/source/beta-components/datepicker/react/Popover.tsx +0 -87
  124. package/source/beta-components/datepicker/react/icons.tsx +0 -32
  125. /package/source/beta-components/{datagrid → data-grid}/README.md +0 -0
  126. /package/source/beta-components/{datagrid → data-grid}/__tests__/core.test.ts +0 -0
  127. /package/source/beta-components/{datagrid → data-grid}/__tests__/export.test.ts +0 -0
  128. /package/source/beta-components/{datagrid → data-grid}/core/columnHelper.ts +0 -0
  129. /package/source/beta-components/{datagrid → data-grid}/core/columns.ts +0 -0
  130. /package/source/beta-components/{datagrid → data-grid}/core/filtering.ts +0 -0
  131. /package/source/beta-components/{datagrid → data-grid}/core/grid.ts +0 -0
  132. /package/source/beta-components/{datagrid → data-grid}/core/index.ts +0 -0
  133. /package/source/beta-components/{datagrid → data-grid}/core/rows.ts +0 -0
  134. /package/source/beta-components/{datagrid → data-grid}/core/sorting.ts +0 -0
  135. /package/source/beta-components/{datagrid → data-grid}/core/state.ts +0 -0
  136. /package/source/beta-components/{datagrid → data-grid}/core/store.ts +0 -0
  137. /package/source/beta-components/{datagrid → data-grid}/core/types.ts +0 -0
  138. /package/source/beta-components/{datagrid → data-grid}/core/values.ts +0 -0
  139. /package/source/beta-components/{datagrid → data-grid}/core/virtual.ts +0 -0
  140. /package/source/beta-components/{datagrid → data-grid}/export/csv.ts +0 -0
  141. /package/source/beta-components/{datagrid → data-grid}/export/download.ts +0 -0
  142. /package/source/beta-components/{datagrid → data-grid}/export/pdf.ts +0 -0
  143. /package/source/beta-components/{datagrid → data-grid}/export/table.ts +0 -0
  144. /package/source/beta-components/{datagrid → data-grid}/export/xlsx.ts +0 -0
  145. /package/source/beta-components/{datagrid → data-grid}/export/zip.ts +0 -0
  146. /package/source/beta-components/{datagrid → data-grid}/index.ts +0 -0
  147. /package/source/beta-components/{datagrid → data-grid}/react/Cell.tsx +0 -0
  148. /package/source/beta-components/{datagrid → data-grid}/react/ColumnMenu.tsx +0 -0
  149. /package/source/beta-components/{datagrid → data-grid}/react/DataGrid.tsx +0 -0
  150. /package/source/beta-components/{datagrid → data-grid}/react/FilterForm.tsx +0 -0
  151. /package/source/beta-components/{datagrid → data-grid}/react/HeaderRow.tsx +0 -0
  152. /package/source/beta-components/{datagrid → data-grid}/react/Pagination.tsx +0 -0
  153. /package/source/beta-components/{datagrid → data-grid}/react/Row.tsx +0 -0
  154. /package/source/beta-components/{datagrid → data-grid}/react/Toolbar.tsx +0 -0
  155. /package/source/beta-components/{datagrid → data-grid}/react/Viewport.tsx +0 -0
  156. /package/source/beta-components/{datagrid → data-grid}/react/hooks.ts +0 -0
  157. /package/source/beta-components/{datagrid → data-grid}/react/keyboard.ts +0 -0
  158. /package/source/beta-components/{datagrid → data-grid}/react/locale.ts +0 -0
  159. /package/source/beta-components/{datepicker → date-picker}/__tests__/core.test.ts +0 -0
  160. /package/source/beta-components/{datepicker → date-picker}/core/calendar.ts +0 -0
  161. /package/source/beta-components/{datepicker → date-picker}/core/format.ts +0 -0
  162. /package/source/beta-components/{datepicker → date-picker}/core/index.ts +0 -0
  163. /package/source/beta-components/{datepicker → date-picker}/core/types.ts +0 -0
  164. /package/source/beta-components/{datepicker → date-picker}/index.ts +0 -0
  165. /package/source/beta-components/{datepicker → date-picker}/react/Calendar.tsx +0 -0
  166. /package/source/beta-components/{datepicker → date-picker}/react/CalendarPanel.tsx +0 -0
  167. /package/source/beta-components/{datepicker → date-picker}/react/MonthYearPanels.tsx +0 -0
  168. /package/source/beta-components/{datepicker → date-picker}/react/locale.ts +0 -0
  169. /package/source/beta-components/{datepicker → date-picker}/react/useDatePicker.ts +0 -0
  170. /package/source/beta-components/{fileuploader → file-uploader}/README.md +0 -0
  171. /package/source/beta-components/{fileuploader → file-uploader}/__tests__/core.test.ts +0 -0
  172. /package/source/beta-components/{fileuploader → file-uploader}/core/format.ts +0 -0
  173. /package/source/beta-components/{fileuploader → file-uploader}/core/index.ts +0 -0
  174. /package/source/beta-components/{fileuploader → file-uploader}/core/store.ts +0 -0
  175. /package/source/beta-components/{fileuploader → file-uploader}/core/transport.ts +0 -0
  176. /package/source/beta-components/{fileuploader → file-uploader}/core/types.ts +0 -0
  177. /package/source/beta-components/{fileuploader → file-uploader}/core/validate.ts +0 -0
  178. /package/source/beta-components/{fileuploader → file-uploader}/index.ts +0 -0
  179. /package/source/beta-components/{fileuploader → file-uploader}/react/FileRow.tsx +0 -0
  180. /package/source/beta-components/{fileuploader → file-uploader}/react/locale.ts +0 -0
  181. /package/source/beta-components/{fileuploader → file-uploader}/react/useFileUploader.ts +0 -0
@@ -0,0 +1,133 @@
1
+ "use client";
2
+
3
+ import type { AnchorHTMLAttributes, CSSProperties, HTMLAttributes, ReactNode, Ref } from "react";
4
+ import type { CardPadding, CardSlot, CardVariant } from "../core/types";
5
+ import { cx } from "./props";
6
+
7
+ export interface CardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
8
+ children?: ReactNode;
9
+ /** Default `outlined`. */
10
+ variant?: CardVariant;
11
+ /** Padding applied to the header, body and footer. Default `md`. */
12
+ padding?: CardPadding;
13
+ /**
14
+ * Makes the whole card a link. The card becomes an `<a>`, so keep any other
15
+ * interactive content out of it — nested links and buttons are not valid.
16
+ */
17
+ href?: string;
18
+ /** Passed through when `href` is set. */
19
+ target?: AnchorHTMLAttributes<HTMLAnchorElement>["target"];
20
+ rel?: string;
21
+ /** Lifts the card on hover, for a card that is clickable by other means. */
22
+ interactive?: boolean;
23
+ className?: string;
24
+ classNames?: Partial<Record<CardSlot, string>>;
25
+ style?: CSSProperties;
26
+ ref?: Ref<HTMLElement>;
27
+ }
28
+
29
+ /**
30
+ * A surface that groups related content, with optional header, body and footer.
31
+ *
32
+ * Give it a heading through `CardHeader` rather than a bare `title` prop, so the
33
+ * page decides the heading level: a card is not always at the same depth.
34
+ */
35
+ export function Card(props: CardProps) {
36
+ const {
37
+ ref,
38
+ children,
39
+ variant = "outlined",
40
+ padding = "md",
41
+ href,
42
+ target,
43
+ rel,
44
+ interactive = false,
45
+ className,
46
+ classNames,
47
+ style,
48
+ ...rest
49
+ } = props;
50
+
51
+ const shared = {
52
+ className: cx("cd-root", classNames?.root, className),
53
+ style,
54
+ "data-variant": variant,
55
+ "data-padding": padding,
56
+ "data-interactive": (interactive || href !== undefined) || undefined,
57
+ ...rest,
58
+ };
59
+
60
+ if (href !== undefined) {
61
+ return (
62
+ <a
63
+ {...shared}
64
+ ref={ref as Ref<HTMLAnchorElement>}
65
+ href={href}
66
+ target={target}
67
+ // Anything opening a new tab gets the safe default unless told otherwise.
68
+ rel={rel ?? (target === "_blank" ? "noreferrer" : undefined)}
69
+ >
70
+ {children}
71
+ </a>
72
+ );
73
+ }
74
+
75
+ return (
76
+ <div {...shared} ref={ref as Ref<HTMLDivElement>}>
77
+ {children}
78
+ </div>
79
+ );
80
+ }
81
+
82
+ export interface CardHeaderProps {
83
+ /** The heading. Wrap it in your own `h2`/`h3` to set the level. */
84
+ title?: ReactNode;
85
+ description?: ReactNode;
86
+ /** Buttons or a menu, aligned to the end of the header. */
87
+ actions?: ReactNode;
88
+ children?: ReactNode;
89
+ className?: string;
90
+ classNames?: Partial<Record<CardSlot, string>>;
91
+ }
92
+
93
+ export function CardHeader({
94
+ title,
95
+ description,
96
+ actions,
97
+ children,
98
+ className,
99
+ classNames,
100
+ }: CardHeaderProps) {
101
+ return (
102
+ <div className={cx("cd-header", classNames?.header, className)}>
103
+ <div className="cd-heading">
104
+ {title && <div className={cx("cd-title", classNames?.title)}>{title}</div>}
105
+ {description && (
106
+ <div className={cx("cd-description", classNames?.description)}>{description}</div>
107
+ )}
108
+ {children}
109
+ </div>
110
+ {actions && <div className={cx("cd-actions", classNames?.actions)}>{actions}</div>}
111
+ </div>
112
+ );
113
+ }
114
+
115
+ export function CardBody({
116
+ children,
117
+ className,
118
+ }: {
119
+ children?: ReactNode;
120
+ className?: string;
121
+ }) {
122
+ return <div className={cx("cd-body", className)}>{children}</div>;
123
+ }
124
+
125
+ export function CardFooter({
126
+ children,
127
+ className,
128
+ }: {
129
+ children?: ReactNode;
130
+ className?: string;
131
+ }) {
132
+ return <div className={cx("cd-footer", className)}>{children}</div>;
133
+ }
@@ -0,0 +1,127 @@
1
+ "use client";
2
+
3
+ import { useId, type CSSProperties, type ReactNode } from "react";
4
+ import { isPositive, type TrendDirection } from "../core/trend";
5
+ import type { StatSlot } from "../core/types";
6
+ import { cx } from "./props";
7
+
8
+ export interface StatTrend {
9
+ /** `up`, `down` or `flat`. `trendDirection(change)` works this out for you. */
10
+ direction: TrendDirection;
11
+ /** What is shown beside the arrow, already formatted, e.g. "12.4%". */
12
+ label: ReactNode;
13
+ /**
14
+ * Down is the good outcome for this figure, as with churn or error rates.
15
+ * Only changes the colour; the arrow still points the way the number moved.
16
+ */
17
+ invert?: boolean;
18
+ /** Read out after the change, e.g. "since last month". */
19
+ description?: ReactNode;
20
+ }
21
+
22
+ export interface StatProps {
23
+ /** What the figure is. Always visible — a number alone means nothing. */
24
+ label: ReactNode;
25
+ value: ReactNode;
26
+ trend?: StatTrend;
27
+ /** A note under the figure. */
28
+ help?: ReactNode;
29
+ icon?: ReactNode;
30
+ /** Shows placeholder bars instead of the figure. */
31
+ loading?: boolean;
32
+ className?: string;
33
+ classNames?: Partial<Record<StatSlot, string>>;
34
+ style?: CSSProperties;
35
+ }
36
+
37
+ const ARROWS: Record<TrendDirection, string> = {
38
+ up: "M12 19V5M5 12l7-7 7 7",
39
+ down: "M12 5v14M19 12l-7 7-7-7",
40
+ flat: "M5 12h14",
41
+ };
42
+
43
+ /** The word behind the arrow, so the direction is not carried by colour alone. */
44
+ const DIRECTION_TEXT: Record<TrendDirection, string> = {
45
+ up: "Up",
46
+ down: "Down",
47
+ flat: "No change",
48
+ };
49
+
50
+ /**
51
+ * A single figure with its label and, optionally, how it has changed.
52
+ *
53
+ * Put it inside a `Card` for a dashboard tile, or use it on its own in a row of
54
+ * summary numbers.
55
+ */
56
+ export function Stat(props: StatProps) {
57
+ const { label, value, trend, help, icon, loading = false, className, classNames, style } = props;
58
+ const id = useId();
59
+ const positive = trend ? isPositive(trend.direction, trend.invert) : null;
60
+
61
+ return (
62
+ <div
63
+ className={cx("st-root", classNames?.root, className)}
64
+ style={style}
65
+ data-loading={loading || undefined}
66
+ >
67
+ <div className="st-head">
68
+ <span id={`${id}-label`} className={cx("st-label", classNames?.label)}>
69
+ {label}
70
+ </span>
71
+ {icon && (
72
+ <span className={cx("st-icon", classNames?.icon)} aria-hidden="true">
73
+ {icon}
74
+ </span>
75
+ )}
76
+ </div>
77
+
78
+ {loading ? (
79
+ <>
80
+ <div className="st-placeholder st-placeholder-value" />
81
+ <div className="st-placeholder st-placeholder-help" />
82
+ <span className="st-sr-only">Loading</span>
83
+ </>
84
+ ) : (
85
+ <>
86
+ <div
87
+ className={cx("st-value", classNames?.value)}
88
+ aria-labelledby={`${id}-label`}
89
+ role="figure"
90
+ >
91
+ {value}
92
+ </div>
93
+
94
+ {trend && (
95
+ <div
96
+ className={cx("st-trend", classNames?.trend)}
97
+ data-direction={trend.direction}
98
+ data-positive={positive === null ? undefined : positive}
99
+ >
100
+ <svg
101
+ width="14"
102
+ height="14"
103
+ viewBox="0 0 24 24"
104
+ fill="none"
105
+ stroke="currentColor"
106
+ strokeWidth="2.5"
107
+ strokeLinecap="round"
108
+ strokeLinejoin="round"
109
+ aria-hidden="true"
110
+ focusable="false"
111
+ >
112
+ <path d={ARROWS[trend.direction]} />
113
+ </svg>
114
+ <span className="st-sr-only">{DIRECTION_TEXT[trend.direction]}</span>
115
+ <span className="st-trend-label">{trend.label}</span>
116
+ {trend.description && (
117
+ <span className="st-trend-description">{trend.description}</span>
118
+ )}
119
+ </div>
120
+ )}
121
+
122
+ {help && <div className={cx("st-help", classNames?.help)}>{help}</div>}
123
+ </>
124
+ )}
125
+ </div>
126
+ );
127
+ }
@@ -0,0 +1,4 @@
1
+ export type { CardSlot, StatSlot } from "../core/types";
2
+
3
+ // Shared with every other component, so class handling cannot drift.
4
+ export { cx } from "../../shared/core/cx";
@@ -0,0 +1,231 @@
1
+ /*
2
+ * Card and Stat styles.
3
+ *
4
+ * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
+ * (set them on :root to theme every component at once) and fall back to the
6
+ * same default palette otherwise. Rules live in the `components` layer, so utility classes passed
7
+ * through `className` / `classNames` override them.
8
+ */
9
+ @layer theme, base, components, utilities;
10
+
11
+ @layer components {
12
+ .cd-root,
13
+ .st-root {
14
+ --cd-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
15
+ --cd-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
16
+ --cd-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
17
+ --cd-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
18
+ --cd-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
19
+ --cd-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
20
+ --cd-success: var(--gbs-success, light-dark(#15803d, #4ade80));
21
+ --cd-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
22
+ --cd-shadow: var(--gbs-shadow, var(--dg-shadow, 0 10px 30px -8px light-dark(rgb(0 0 0 / 0.18), rgb(0 0 0 / 0.6))));
23
+ --cd-radius: var(--gbs-radius, var(--dg-radius, 8px));
24
+ --cd-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
25
+ --cd-px: 16px;
26
+
27
+ color-scheme: inherit;
28
+ font-size: var(--cd-font-size);
29
+ line-height: 1.5;
30
+ color: var(--cd-fg);
31
+ }
32
+
33
+ :where(.dark, [data-theme="dark"]) :is(.cd-root, .st-root) {
34
+ color-scheme: dark;
35
+ }
36
+ :where(.light, [data-theme="light"]) :is(.cd-root, .st-root) {
37
+ color-scheme: light;
38
+ }
39
+
40
+ :where(.cd-root, .st-root) *,
41
+ :where(.cd-root, .st-root) *::before,
42
+ :where(.cd-root, .st-root) *::after {
43
+ box-sizing: border-box;
44
+ }
45
+
46
+ /* ---------------------------------------------------------------- card */
47
+
48
+ .cd-root {
49
+ display: flex;
50
+ flex-direction: column;
51
+ min-width: 0;
52
+ border-radius: var(--cd-radius);
53
+ background: var(--cd-bg);
54
+ text-decoration: none;
55
+ }
56
+ .cd-root[data-variant="outlined"] {
57
+ border: 1px solid var(--cd-border);
58
+ }
59
+ .cd-root[data-variant="elevated"] {
60
+ border: 1px solid transparent;
61
+ box-shadow: var(--cd-shadow);
62
+ }
63
+ .cd-root[data-variant="plain"] {
64
+ background: transparent;
65
+ }
66
+
67
+ .cd-root[data-padding="none"] {
68
+ --cd-px: 0px;
69
+ }
70
+ .cd-root[data-padding="sm"] {
71
+ --cd-px: 12px;
72
+ }
73
+ .cd-root[data-padding="lg"] {
74
+ --cd-px: 24px;
75
+ }
76
+
77
+ .cd-root[data-interactive] {
78
+ cursor: pointer;
79
+ transition:
80
+ background-color 120ms ease,
81
+ box-shadow 120ms ease,
82
+ translate 120ms ease;
83
+ }
84
+ .cd-root[data-interactive]:hover {
85
+ background: var(--cd-hover);
86
+ }
87
+ .cd-root[data-variant="elevated"][data-interactive]:hover {
88
+ translate: 0 -1px;
89
+ }
90
+ .cd-root[data-interactive]:focus-visible {
91
+ outline: 2px solid var(--cd-focus);
92
+ outline-offset: 2px;
93
+ }
94
+
95
+ .cd-header {
96
+ display: flex;
97
+ align-items: flex-start;
98
+ gap: 12px;
99
+ padding: var(--cd-px) var(--cd-px) 0;
100
+ }
101
+ .cd-heading {
102
+ flex: 1 1 auto;
103
+ min-width: 0;
104
+ }
105
+ .cd-title {
106
+ font-size: 1.05em;
107
+ font-weight: 600;
108
+ line-height: 1.35;
109
+ }
110
+ .cd-description {
111
+ margin-top: 2px;
112
+ color: var(--cd-muted);
113
+ }
114
+ .cd-actions {
115
+ display: flex;
116
+ flex: none;
117
+ align-items: center;
118
+ gap: 4px;
119
+ }
120
+
121
+ .cd-body {
122
+ flex: 1 1 auto;
123
+ min-width: 0;
124
+ padding: var(--cd-px);
125
+ }
126
+ /* The header already spaces the top, so the body should not double it. */
127
+ .cd-header + .cd-body {
128
+ padding-top: 12px;
129
+ }
130
+
131
+ .cd-footer {
132
+ display: flex;
133
+ flex-wrap: wrap;
134
+ align-items: center;
135
+ gap: 8px;
136
+ padding: 12px var(--cd-px);
137
+ border-top: 1px solid var(--cd-border);
138
+ }
139
+
140
+ /* ---------------------------------------------------------------- stat */
141
+
142
+ .st-root {
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 4px;
146
+ min-width: 0;
147
+ }
148
+ .st-head {
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 8px;
152
+ }
153
+ .st-label {
154
+ flex: 1 1 auto;
155
+ min-width: 0;
156
+ color: var(--cd-muted);
157
+ font-weight: 500;
158
+ overflow: hidden;
159
+ text-overflow: ellipsis;
160
+ white-space: nowrap;
161
+ }
162
+ .st-icon {
163
+ display: inline-flex;
164
+ flex: none;
165
+ color: var(--cd-muted);
166
+ }
167
+ .st-value {
168
+ font-size: 1.9em;
169
+ font-weight: 650;
170
+ font-variant-numeric: tabular-nums;
171
+ line-height: 1.15;
172
+ letter-spacing: -0.01em;
173
+ }
174
+
175
+ .st-trend {
176
+ display: flex;
177
+ align-items: center;
178
+ gap: 4px;
179
+ color: var(--cd-muted);
180
+ }
181
+ /* Colour is a second signal: the arrow and the visually hidden word carry
182
+ the direction on their own. */
183
+ .st-trend[data-positive="true"] {
184
+ color: var(--cd-success);
185
+ }
186
+ .st-trend[data-positive="false"] {
187
+ color: var(--cd-danger);
188
+ }
189
+ .st-trend-label {
190
+ font-variant-numeric: tabular-nums;
191
+ font-weight: 500;
192
+ }
193
+ .st-trend-description {
194
+ color: var(--cd-muted);
195
+ }
196
+
197
+ .st-help {
198
+ color: var(--cd-muted);
199
+ }
200
+
201
+ .st-placeholder {
202
+ border-radius: 4px;
203
+ background: var(--cd-hover);
204
+ }
205
+ .st-placeholder-value {
206
+ width: 5ch;
207
+ height: 1.9em;
208
+ }
209
+ .st-placeholder-help {
210
+ width: 10ch;
211
+ height: 1em;
212
+ }
213
+
214
+ .st-sr-only {
215
+ position: absolute;
216
+ width: 1px;
217
+ height: 1px;
218
+ margin: -1px;
219
+ padding: 0;
220
+ overflow: hidden;
221
+ border: 0;
222
+ clip-path: inset(50%);
223
+ white-space: nowrap;
224
+ }
225
+
226
+ @media (forced-colors: active) {
227
+ .cd-root[data-variant="elevated"] {
228
+ border-color: CanvasText;
229
+ }
230
+ }
231
+ }