@gtivr4/a1-design-system-react 0.15.0 → 0.18.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.
Files changed (41) hide show
  1. package/package.json +3 -2
  2. package/src/color-scheme.css +2 -0
  3. package/src/components/accordion/accordion.css +6 -0
  4. package/src/components/autocomplete/Autocomplete.d.ts +53 -0
  5. package/src/components/autocomplete/Autocomplete.jsx +380 -0
  6. package/src/components/autocomplete/autocomplete.css +346 -0
  7. package/src/components/banner/Banner.d.ts +9 -2
  8. package/src/components/banner/Banner.jsx +32 -6
  9. package/src/components/banner/banner.css +81 -0
  10. package/src/components/bottom-sheet/BottomSheet.d.ts +22 -0
  11. package/src/components/bottom-sheet/BottomSheet.jsx +154 -0
  12. package/src/components/bottom-sheet/bottom-sheet.css +113 -0
  13. package/src/components/code/Code.jsx +6 -1
  14. package/src/components/data-table/DataTable.jsx +11 -1
  15. package/src/components/data-table/data-table.css +19 -0
  16. package/src/components/figure/Figure.d.ts +7 -0
  17. package/src/components/figure/Figure.jsx +23 -2
  18. package/src/components/figure/figure.css +25 -0
  19. package/src/components/grid/Grid.d.ts +1 -1
  20. package/src/components/grid/Grid.jsx +2 -0
  21. package/src/components/grid/grid.css +5 -0
  22. package/src/components/page-layout/page-layout.css +10 -4
  23. package/src/components/page-nav/PageNav.jsx +29 -8
  24. package/src/components/page-nav/page-nav.css +13 -0
  25. package/src/components/paragraph/Paragraph.d.ts +2 -0
  26. package/src/components/paragraph/Paragraph.jsx +4 -0
  27. package/src/components/paragraph/paragraph.css +6 -6
  28. package/src/components/segmented-control/SegmentedControl.d.ts +8 -0
  29. package/src/components/segmented-control/SegmentedControl.jsx +16 -3
  30. package/src/components/segmented-control/segmented.css +31 -1
  31. package/src/components/slider/slider.css +10 -2
  32. package/src/components/split-button/SplitButton.jsx +3 -1
  33. package/src/components/tabs/tabs.css +3 -0
  34. package/src/components/toolbar/Toolbar.d.ts +7 -0
  35. package/src/components/toolbar/Toolbar.jsx +13 -5
  36. package/src/components/top-header/top-header.css +2 -0
  37. package/src/components/tree-menu/TreeMenu.jsx +11 -7
  38. package/src/index.d.ts +71 -0
  39. package/src/index.js +2 -0
  40. package/src/themes.css +293 -0
  41. package/src/tokens.css +22 -1
@@ -25,8 +25,10 @@
25
25
  /* ── Sizes (match the field family: compact / default / comfortable) ─────────── */
26
26
 
27
27
  .a1-slider--compact {
28
- --a1-slider-track-height: var(--base-spacing-6);
29
- --a1-slider-thumb-size: var(--base-spacing-16);
28
+ /* Track + thumb are one step up from the smallest scale so the compact slider
29
+ stays grabbable; the label/detent text keeps the compact field-family size. */
30
+ --a1-slider-track-height: var(--base-spacing-8);
31
+ --a1-slider-thumb-size: var(--base-spacing-20);
30
32
  --a1-slider-label-size: var(--semantic-font-size-form-label-compact);
31
33
  --a1-slider-label-weight: var(--component-field-compact-label-font-weight);
32
34
  --a1-slider-detent-size: var(--semantic-font-size-body-xs);
@@ -222,6 +224,12 @@
222
224
  .a1-slider--disabled {
223
225
  --a1-slider-fill-color: var(--semantic-color-border-default);
224
226
  --a1-slider-thumb-color: var(--semantic-color-border-default);
227
+ --a1-slider-active-color: var(--semantic-color-text-muted);
228
+ }
229
+
230
+ .a1-slider--disabled .a1-slider__input,
231
+ .a1-slider--disabled .a1-slider__track,
232
+ .a1-slider--disabled .a1-slider__ticks {
225
233
  opacity: 0.6;
226
234
  }
227
235
 
@@ -32,6 +32,7 @@ export function SplitButton({
32
32
  }) {
33
33
  const [open, setOpen] = useState(false);
34
34
  const toggleRef = useRef(null);
35
+ const rootRef = useRef(null);
35
36
 
36
37
  const resolvedVariant = variants.includes(variant) ? variant : "primary";
37
38
  const resolvedSize = sizes.includes(size) ? size : "md";
@@ -48,6 +49,7 @@ export function SplitButton({
48
49
 
49
50
  return (
50
51
  <div
52
+ ref={rootRef}
51
53
  className={["a1-split-button", isInert && "a1-split-button--disabled", className].filter(Boolean).join(" ")}
52
54
  {...rest}
53
55
  >
@@ -75,7 +77,7 @@ export function SplitButton({
75
77
  >
76
78
  <Icon name="arrow_drop_down" className="a1-split-button__caret" aria-hidden="true" />
77
79
  </button>
78
- <Menu open={open} onClose={() => setOpen(false)} anchorRef={toggleRef} aria-label={menuLabel}>
80
+ <Menu open={open} onClose={() => setOpen(false)} anchorRef={rootRef} aria-label={menuLabel}>
79
81
  {actions.map((action) => (
80
82
  <MenuItem
81
83
  key={action.id}
@@ -64,6 +64,9 @@
64
64
  .a1-tab-list--scrollable {
65
65
  flex: 1;
66
66
  overflow-x: auto;
67
+ /* Setting overflow-x alone makes the browser compute overflow-y to `auto`,
68
+ which lets a sub-pixel of height add a stray vertical scroll. Pin it. */
69
+ overflow-y: hidden;
67
70
  scrollbar-width: none;
68
71
  }
69
72
 
@@ -116,6 +116,13 @@ export interface ToolbarGroupProps {
116
116
  columns?: number;
117
117
  /** Show option labels as text; boolean or a responsive breakpoint object. Default: false (icon-only) */
118
118
  showLabels?: ToolbarShowLabel;
119
+ /**
120
+ * `"all"` (default) honours `showLabels` for every option. `"selected"` shows
121
+ * the label only on the currently selected option; the rest render icon/swatch-only
122
+ * and a `"none"`/empty value falls back to the standard none icon. Use it for a
123
+ * swatch picker where only the chosen swatch is named (e.g. Section surface/gradient).
124
+ */
125
+ labelMode?: "all" | "selected";
119
126
  "aria-label"?: string;
120
127
  disabled?: boolean;
121
128
  className?: string;
@@ -108,8 +108,8 @@ export function Toolbar({
108
108
  }
109
109
 
110
110
  /** Visual separator between tools within a Toolbar. */
111
- export function ToolbarDivider() {
112
- return <span className="a1-toolbar__divider" role="separator" aria-orientation="vertical" />;
111
+ export function ToolbarDivider({ className = "", ...rest }) {
112
+ return <span className={cx("a1-toolbar__divider", className)} role="separator" aria-orientation="vertical" {...rest} />;
113
113
  }
114
114
 
115
115
  function ToolButtonContent({ icon, label, showLabel, swatch }) {
@@ -196,6 +196,7 @@ export function ToolbarMenu({
196
196
  disabled = false,
197
197
  "aria-label": ariaLabel,
198
198
  className = "",
199
+ ...rest
199
200
  }) {
200
201
  const [open, setOpen] = useState(false);
201
202
  const btnRef = useRef(null);
@@ -215,6 +216,7 @@ export function ToolbarMenu({
215
216
  title={label}
216
217
  disabled={disabled}
217
218
  onClick={() => setOpen((o) => !o)}
219
+ {...rest}
218
220
  >
219
221
  <ToolButtonContent icon={buttonIcon} label={label} showLabel={showLabel} />
220
222
  <Icon name="arrow_drop_down" size="sm" className="a1-toolbar__caret" />
@@ -248,9 +250,11 @@ export function ToolbarGroup({
248
250
  options = [],
249
251
  columns,
250
252
  showLabels = false,
253
+ labelMode = "all",
251
254
  "aria-label": ariaLabel,
252
255
  disabled = false,
253
256
  className = "",
257
+ ...rest
254
258
  }) {
255
259
  const btnRefs = useRef([]);
256
260
  const grid = typeof columns === "number" && columns > 0;
@@ -295,6 +299,7 @@ export function ToolbarGroup({
295
299
  aria-label={ariaLabel}
296
300
  className={cx("a1-toolbar__group", grid && "a1-toolbar__group--grid", className)}
297
301
  style={style}
302
+ {...rest}
298
303
  >
299
304
  {options.map((opt, i) => {
300
305
  const selected = i === selectedIndex;
@@ -302,7 +307,10 @@ export function ToolbarGroup({
302
307
  // selected) is the single tab stop for the group.
303
308
  const tabIndex = selected || (selectedIndex === -1 && i === 0) ? 0 : -1;
304
309
  const optLabel = opt.label ?? String(opt.value);
305
- const icon = opt.icon ?? (!labelAlwaysShown(showLabels) && isNoneValue(opt.value) ? TOOLBAR_NONE_ICON : undefined);
310
+ // `labelMode="selected"` shows the label only on the selected option;
311
+ // the rest fall back to icon/swatch-only (and "none" to its icon).
312
+ const optShowLabel = labelMode === "selected" ? selected : showLabels;
313
+ const icon = opt.icon ?? (!labelAlwaysShown(optShowLabel) && isNoneValue(opt.value) ? TOOLBAR_NONE_ICON : undefined);
306
314
  return (
307
315
  <button
308
316
  key={String(opt.value)}
@@ -310,7 +318,7 @@ export function ToolbarGroup({
310
318
  type="button"
311
319
  role="radio"
312
320
  aria-checked={selected}
313
- aria-label={toolAriaLabel(showLabels, optLabel)}
321
+ aria-label={toolAriaLabel(optShowLabel, optLabel)}
314
322
  title={optLabel}
315
323
  tabIndex={tabIndex}
316
324
  disabled={disabled || opt.disabled}
@@ -318,7 +326,7 @@ export function ToolbarGroup({
318
326
  onClick={() => onChange?.(opt.value)}
319
327
  onKeyDown={(e) => handleKeyDown(e, i)}
320
328
  >
321
- <ToolButtonContent icon={icon} label={opt.label} showLabel={showLabels} swatch={opt.swatch} />
329
+ <ToolButtonContent icon={icon} label={opt.label} showLabel={optShowLabel} swatch={opt.swatch} />
322
330
  </button>
323
331
  );
324
332
  })}
@@ -144,6 +144,8 @@
144
144
  }
145
145
 
146
146
  .a1-top-header__nav-submenu-trigger {
147
+ min-inline-size: 24px;
148
+ min-block-size: 24px;
147
149
  padding-inline: var(--base-spacing-8);
148
150
  }
149
151
 
@@ -482,16 +482,20 @@ export function TreeMenu({
482
482
 
483
483
  if (!showExpandControls) return tree;
484
484
 
485
+ // One toggle: if anything is expanded, collapse everything; otherwise expand all.
486
+ const anyExpanded = expandedIds.size > 0;
487
+
485
488
  return (
486
489
  <div className="a1-tree-menu-root">
487
490
  <div className="a1-tree-menu__controls">
488
- <button type="button" className="a1-tree-menu__control-btn" onClick={handleExpandAll}>
489
- <Icon name="unfold_more" />
490
- Expand all
491
- </button>
492
- <button type="button" className="a1-tree-menu__control-btn" onClick={handleCollapseAll}>
493
- <Icon name="unfold_less" />
494
- Collapse all
491
+ <button
492
+ type="button"
493
+ className="a1-tree-menu__control-btn"
494
+ aria-expanded={anyExpanded}
495
+ onClick={anyExpanded ? handleCollapseAll : handleExpandAll}
496
+ >
497
+ <Icon name={anyExpanded ? 'unfold_less' : 'unfold_more'} />
498
+ {anyExpanded ? 'Collapse all' : 'Expand all'}
495
499
  </button>
496
500
  </div>
497
501
  {tree}
package/src/index.d.ts ADDED
@@ -0,0 +1,71 @@
1
+ // Aggregated type entry — generated to mirror index.js so TS consumers (and
2
+ // design-sync) see the component exports. Regenerate if index.js changes.
3
+
4
+ export { Accordion } from "./components/accordion/Accordion";
5
+ export { ContextMenu } from "./components/context-menu/ContextMenu";
6
+ export { TreeMenu } from "./components/tree-menu/TreeMenu";
7
+ export { Calendar } from "./components/calendar/Calendar";
8
+ export { PageNav } from "./components/page-nav/PageNav";
9
+ export { Blockquote } from "./components/blockquote/Blockquote";
10
+ export { Breadcrumb } from "./components/breadcrumb/Breadcrumb";
11
+ export { Notification } from "./components/notification/Notification";
12
+ export { Snackbar } from "./components/snackbar/Snackbar";
13
+ export { StatusBar } from "./components/status-bar/StatusBar";
14
+ export { CircularProgress } from "./components/circular-progress/CircularProgress";
15
+ export { StepTracker } from "./components/step-tracker/StepTracker";
16
+ export { Bleed } from "./components/bleed/Bleed";
17
+ export { IconButton } from "./components/icon-button/IconButton";
18
+ export { Button } from "./components/button/Button";
19
+ export { SplitButton } from "./components/split-button/SplitButton";
20
+ export { ButtonContainer } from "./components/button-container/ButtonContainer";
21
+ export { Card } from "./components/card/Card";
22
+ export { Cluster } from "./components/cluster/Cluster";
23
+ export { Code } from "./components/code/Code";
24
+ export { DefinitionList } from "./components/definition-list/DefinitionList";
25
+ export { Dialog } from "./components/dialog/Dialog";
26
+ export { Divider } from "./components/divider/Divider";
27
+ export { InlineEditable } from "./components/inline-editable/InlineEditable";
28
+ export { Heading, HeadingMark } from "./components/heading/Heading";
29
+ export { List, ListItem } from "./components/list/List";
30
+ export { Inset } from "./components/inset/Inset";
31
+ export { Icon } from "./components/icon/Icon";
32
+ export { Link } from "./components/link/Link";
33
+ export { Paragraph } from "./components/paragraph/Paragraph";
34
+ export { Banner } from "./components/banner/Banner";
35
+ export { Fieldset } from "./components/fieldset/Fieldset";
36
+ export { FieldRow } from "./components/field-row/FieldRow";
37
+ export { TextField } from "./components/field/TextField";
38
+ export { SelectField } from "./components/field/SelectField";
39
+ export { Autocomplete } from "./components/autocomplete/Autocomplete";
40
+ export { NumberField } from "./components/field/NumberField";
41
+ export { TextareaField } from "./components/field/TextareaField";
42
+ export { CheckboxGroup } from "./components/checkbox-group/CheckboxGroup";
43
+ export { ChoiceGroup } from "./components/choice-group/ChoiceGroup";
44
+ export { RadioGroup } from "./components/radio-group/RadioGroup";
45
+ export { Switch } from "./components/switch/Switch";
46
+ export { MessageBadge, MessageEmptyState } from "./components/message/Message";
47
+ export { Pagination } from "./components/pagination/Pagination";
48
+ export { SegmentedControl } from "./components/segmented-control/SegmentedControl";
49
+ export { Slider } from "./components/slider/Slider";
50
+ export {
51
+ Toolbar,
52
+ ToolbarToggle,
53
+ ToolbarButton,
54
+ ToolbarGroup,
55
+ ToolbarMenu,
56
+ ToolbarDivider,
57
+ TOOLBAR_NONE_ICON,
58
+ } from "./components/toolbar/Toolbar.jsx";
59
+ export { Tabs, TabList, Tab, TabPanel } from "./components/tabs/Tabs";
60
+ export { Grid, GridItem } from "./components/grid/Grid";
61
+ export { Inverse } from "./components/inverse/Inverse";
62
+ export { Section } from "./components/section/Section";
63
+ export { Stack } from "./components/stack/Stack";
64
+ export { PageLayout } from "./components/page-layout/PageLayout";
65
+ export { Menu, MenuSection, MenuItem } from "./components/menu/Menu";
66
+ export { SideNav, SideNavItem, SideNavGroup } from "./components/side-nav/SideNav";
67
+ export { BottomDrawer } from "./components/bottom-drawer/BottomDrawer";
68
+ export { DataTable } from "./components/data-table/DataTable";
69
+ export { Figure } from "./components/figure/Figure";
70
+ export { Spacer } from "./components/spacer/Spacer";
71
+ export { StickyActions } from "./components/sticky-actions/StickyActions";
package/src/index.js CHANGED
@@ -33,6 +33,7 @@ export { Fieldset } from "./components/fieldset/Fieldset.jsx";
33
33
  export { FieldRow } from "./components/field-row/FieldRow.jsx";
34
34
  export { TextField } from "./components/field/TextField.jsx";
35
35
  export { SelectField } from "./components/field/SelectField.jsx";
36
+ export { Autocomplete } from "./components/autocomplete/Autocomplete.jsx";
36
37
  export { DateField } from "./components/field/DateField.jsx";
37
38
  export { PhoneField } from "./components/field/PhoneField.jsx";
38
39
  export { ZipField, ZIP_MASKS } from "./components/field/ZipField.jsx";
@@ -69,6 +70,7 @@ export { Menu, MenuSection, MenuItem } from "./components/menu/Menu.jsx";
69
70
  export { SideNav, SideNavItem, SideNavGroup } from "./components/side-nav/SideNav.jsx";
70
71
  export { TokenSelect } from "./components/token-select/TokenSelect.jsx";
71
72
  export { BottomDrawer } from "./components/bottom-drawer/BottomDrawer.jsx";
73
+ export { BottomSheet } from "./components/bottom-sheet/BottomSheet.jsx";
72
74
  export { TopHeader } from "./components/top-header/TopHeader.jsx";
73
75
  export { DataTable } from "./components/data-table/DataTable.jsx";
74
76
  export { DataTableFilters } from "./components/data-table/DataTableFilters.jsx";
package/src/themes.css CHANGED
@@ -93,6 +93,152 @@ html.a1-theme-accessible.a1-theme-light, html.a1-theme-light.a1-theme-accessible
93
93
  }
94
94
 
95
95
 
96
+ /* ────────────────────────────────────────────────────────────
97
+ Aperture
98
+ Modern, minimal, gallery-grade theme for a photography portfolio — near-monochrome graphite on clean whites (Apple + Audi inspired) so imagery dominates, with a refined Apple-blue info and Audi-red error. Type: an elegant script display (Pinyon Script), an editorial serif heading (Playfair Display), and a clean, slightly elegant sans body (Manrope). Apply class="a1-theme-aperture" to <html>.
99
+ ──────────────────────────────────────────────────────────── */
100
+
101
+ html.a1-theme-aperture {
102
+ --base-color-accent-0: #FFFFFF;
103
+ --base-color-accent-50: #F5F5F7;
104
+ --base-color-accent-100: #E8E8ED;
105
+ --base-color-accent-200: #D2D2D7;
106
+ --base-color-accent-300: #AEAEB2;
107
+ --base-color-accent-400: #6E6E73;
108
+ --base-color-accent-500: #1D1D1F;
109
+ --base-color-accent-600: #161618;
110
+ --base-color-accent-700: #0F0F10;
111
+ --base-color-accent-800: #08080A;
112
+ --base-color-accent-900: #040405;
113
+ --base-color-accent-1000: #000000;
114
+ --base-color-info-0: #FBFDFF;
115
+ --base-color-info-50: #EAF3FE;
116
+ --base-color-info-100: #D2E6FD;
117
+ --base-color-info-200: #A6CCFB;
118
+ --base-color-info-300: #6FA8F6;
119
+ --base-color-info-400: #3D86EE;
120
+ --base-color-info-500: #0071E3;
121
+ --base-color-info-600: #005BBF;
122
+ --base-color-info-700: #00458F;
123
+ --base-color-info-800: #002E60;
124
+ --base-color-info-900: #001A37;
125
+ --base-color-info-1000: #000D1C;
126
+ --base-color-success-0: #F9FDFB;
127
+ --base-color-success-50: #ECF7F1;
128
+ --base-color-success-100: #D7EEE3;
129
+ --base-color-success-200: #B0DCC8;
130
+ --base-color-success-300: #82C5A8;
131
+ --base-color-success-400: #54A886;
132
+ --base-color-success-500: #2E8765;
133
+ --base-color-success-600: #246B50;
134
+ --base-color-success-700: #1B503C;
135
+ --base-color-success-800: #123528;
136
+ --base-color-success-900: #0A1F17;
137
+ --base-color-success-1000: #05100C;
138
+ --base-color-error-0: #FFFBFB;
139
+ --base-color-error-50: #FCECEE;
140
+ --base-color-error-100: #F8D6DB;
141
+ --base-color-error-200: #F0AEB7;
142
+ --base-color-error-300: #E47E8C;
143
+ --base-color-error-400: #D4536A;
144
+ --base-color-error-500: #BB0A30;
145
+ --base-color-error-600: #960826;
146
+ --base-color-error-700: #71061D;
147
+ --base-color-error-800: #4C0413;
148
+ --base-color-error-900: #2E020B;
149
+ --base-color-error-1000: #170105;
150
+ --base-color-warn-0: #FFFCF6;
151
+ --base-color-warn-50: #FBF2E1;
152
+ --base-color-warn-100: #F6E4C3;
153
+ --base-color-warn-200: #EECB8C;
154
+ --base-color-warn-300: #E0AD55;
155
+ --base-color-warn-400: #C68F35;
156
+ --base-color-warn-500: #9A6D1E;
157
+ --base-color-warn-600: #7B5718;
158
+ --base-color-warn-700: #5C4112;
159
+ --base-color-warn-800: #3D2C0C;
160
+ --base-color-warn-900: #251A07;
161
+ --base-color-warn-1000: #130D03;
162
+ --semantic-color-text-default: #1D1D1F;
163
+ --semantic-color-text-muted: #6E6E73;
164
+ --semantic-color-text-inverse: #FFFFFF;
165
+ --semantic-color-text-accent: var(--base-color-accent-600);
166
+ --semantic-color-surface-page: #FAFAFA;
167
+ --semantic-color-surface-card: #FFFFFF;
168
+ --semantic-color-surface-field: #FFFFFF;
169
+ --semantic-color-surface-panel: #FFFFFF;
170
+ --semantic-color-surface-raised: #F0F0F2;
171
+ --semantic-color-border-subtle: #EBEBED;
172
+ --semantic-color-border-default: #D2D2D7;
173
+ --semantic-color-border-strong: #AEAEB2;
174
+ --semantic-color-action-background: var(--base-color-accent-500);
175
+ --semantic-color-action-background-hover: var(--base-color-accent-600);
176
+ --semantic-color-action-background-pressed: var(--base-color-accent-700);
177
+ --semantic-color-action-foreground: var(--base-color-accent-0);
178
+ --semantic-color-action-foreground-pressed: var(--base-color-accent-100);
179
+ --semantic-color-action-surface: var(--base-color-accent-50);
180
+ --semantic-color-action-border: var(--base-color-accent-300);
181
+ --semantic-color-status-error-background: var(--base-color-error-500);
182
+ --semantic-color-status-error-surface: var(--base-color-error-50);
183
+ --semantic-color-status-error-border: var(--base-color-error-300);
184
+ --semantic-color-status-error-foreground: var(--base-color-error-0);
185
+ --semantic-color-status-warn-background: var(--base-color-warn-500);
186
+ --semantic-color-status-warn-surface: var(--base-color-warn-50);
187
+ --semantic-color-status-warn-border: var(--base-color-warn-300);
188
+ --semantic-color-status-warn-foreground: var(--base-color-warn-0);
189
+ --semantic-color-status-success-background: var(--base-color-success-500);
190
+ --semantic-color-status-success-surface: var(--base-color-success-50);
191
+ --semantic-color-status-success-border: var(--base-color-success-300);
192
+ --semantic-color-status-success-foreground: var(--base-color-success-0);
193
+ --semantic-color-status-info-background: var(--base-color-info-500);
194
+ --semantic-color-status-info-surface: var(--base-color-info-50);
195
+ --semantic-color-status-info-border: var(--base-color-info-300);
196
+ --semantic-color-status-info-foreground: var(--base-color-info-0);
197
+ --component-button-primary-background: var(--semantic-color-action-background);
198
+ --component-button-primary-background-hover: var(--semantic-color-action-background-hover);
199
+ --component-button-primary-background-pressed: var(--semantic-color-action-background-pressed);
200
+ --component-button-primary-foreground: var(--base-color-accent-0);
201
+ --component-button-primary-foreground-hover: var(--base-color-accent-50);
202
+ --component-button-primary-foreground-pressed: var(--base-color-accent-100);
203
+ --component-button-primary-border: var(--semantic-color-action-background);
204
+ --component-button-secondary-background: var(--base-color-accent-0);
205
+ --component-button-secondary-background-hover: var(--base-color-accent-50);
206
+ --component-button-secondary-background-pressed: var(--base-color-accent-100);
207
+ --component-button-secondary-foreground: var(--base-color-accent-600);
208
+ --component-button-secondary-foreground-hover: var(--base-color-accent-700);
209
+ --component-button-secondary-foreground-pressed: var(--base-color-accent-800);
210
+ --component-button-secondary-border: var(--base-color-accent-500);
211
+ --component-button-secondary-border-hover: var(--base-color-accent-700);
212
+ --component-button-secondary-border-pressed: var(--base-color-accent-800);
213
+ --component-button-tertiary-background: transparent;
214
+ --component-button-tertiary-background-hover: var(--base-color-accent-50);
215
+ --component-button-tertiary-background-pressed: var(--base-color-accent-100);
216
+ --component-button-tertiary-foreground: var(--base-color-accent-600);
217
+ --component-button-tertiary-foreground-hover: var(--base-color-accent-700);
218
+ --component-button-tertiary-foreground-pressed: var(--base-color-accent-800);
219
+ --component-button-tertiary-border: transparent;
220
+ --component-button-tertiary-border-hover: var(--base-color-accent-50);
221
+ --component-button-tertiary-border-pressed: var(--base-color-accent-100);
222
+ --component-button-focus-ring: var(--base-color-accent-300);
223
+ --base-radius-sm: 0.25rem;
224
+ --base-radius-md: 0.5rem;
225
+ --base-radius-lg: 0.625rem;
226
+ --base-radius-xl: 0.75rem;
227
+ --component-card-border-radius: 14px;
228
+ --component-dialog-border-radius: 16px;
229
+ --component-button-font-family: var(--theme-a1-aperture-font-family-body);
230
+ --component-paragraph-font-family: var(--theme-a1-aperture-font-family-body);
231
+ --component-heading-font-family-heading: var(--theme-a1-aperture-font-family-heading);
232
+ --component-heading-font-family-display: var(--theme-a1-aperture-font-family-display);
233
+ --semantic-font-weight-body: var(--theme-a1-aperture-font-weight-body);
234
+ --semantic-font-weight-heading: var(--theme-a1-aperture-font-weight-heading);
235
+ --semantic-font-weight-display: var(--theme-a1-aperture-font-weight-display);
236
+ --component-paragraph-font-weight: var(--theme-a1-aperture-font-weight-body);
237
+ --component-heading-font-weight-heading: var(--theme-a1-aperture-font-weight-heading);
238
+ --component-heading-font-weight-display: var(--theme-a1-aperture-font-weight-display);
239
+ }
240
+
241
+
96
242
  /* ────────────────────────────────────────────────────────────
97
243
  CatLympics
98
244
  Playful, pastel, bouncy theme for CatLympics Game. Apply .a1-theme-catlympics to <html>.
@@ -293,6 +439,151 @@ html.a1-theme-catlympics.a1-theme-light, html.a1-theme-light.a1-theme-catlympics
293
439
  }
294
440
 
295
441
 
442
+ /* ────────────────────────────────────────────────────────────
443
+ Crochet
444
+ A soft, cozy pastel theme — dusty-rose accents, sage / periwinkle / apricot pastels on warm cream surfaces, warm engaging serif (Fraunces) display & headings, and a slab-serif (Roboto Slab) body. Apply class="a1-theme-crochet" to <html>.
445
+ ──────────────────────────────────────────────────────────── */
446
+
447
+ html.a1-theme-crochet {
448
+ --base-color-accent-0: #FFFBFD;
449
+ --base-color-accent-50: #FBEFF5;
450
+ --base-color-accent-100: #F5DEEA;
451
+ --base-color-accent-200: #ECC2D6;
452
+ --base-color-accent-300: #DE9DBA;
453
+ --base-color-accent-400: #C9779B;
454
+ --base-color-accent-500: #B0567F;
455
+ --base-color-accent-600: #8E4063;
456
+ --base-color-accent-700: #6B2F4A;
457
+ --base-color-accent-800: #481E31;
458
+ --base-color-accent-900: #2B121D;
459
+ --base-color-accent-1000: #160910;
460
+ --base-color-info-0: #FBFCFF;
461
+ --base-color-info-50: #EFF2FB;
462
+ --base-color-info-100: #DFE5F6;
463
+ --base-color-info-200: #C2CCEC;
464
+ --base-color-info-300: #9CACDE;
465
+ --base-color-info-400: #7488C9;
466
+ --base-color-info-500: #5E73B0;
467
+ --base-color-info-600: #46588E;
468
+ --base-color-info-700: #34426B;
469
+ --base-color-info-800: #232C48;
470
+ --base-color-info-900: #14192B;
471
+ --base-color-info-1000: #0A0D16;
472
+ --base-color-success-0: #F9FDFB;
473
+ --base-color-success-50: #ECF6F0;
474
+ --base-color-success-100: #D9ECE2;
475
+ --base-color-success-200: #B7DCC7;
476
+ --base-color-success-300: #8DC4A6;
477
+ --base-color-success-400: #63A883;
478
+ --base-color-success-500: #418062;
479
+ --base-color-success-600: #34664E;
480
+ --base-color-success-700: #264C3A;
481
+ --base-color-success-800: #193326;
482
+ --base-color-success-900: #0E1E16;
483
+ --base-color-success-1000: #07100B;
484
+ --base-color-error-0: #FFFBFB;
485
+ --base-color-error-50: #FCEEEE;
486
+ --base-color-error-100: #F8DCDC;
487
+ --base-color-error-200: #F0BCBC;
488
+ --base-color-error-300: #E49494;
489
+ --base-color-error-400: #D26F6F;
490
+ --base-color-error-500: #BB4F4F;
491
+ --base-color-error-600: #963E3E;
492
+ --base-color-error-700: #712F2F;
493
+ --base-color-error-800: #4C1F1F;
494
+ --base-color-error-900: #2E1313;
495
+ --base-color-error-1000: #170909;
496
+ --base-color-warn-0: #FFFCF7;
497
+ --base-color-warn-50: #FBF1E3;
498
+ --base-color-warn-100: #F6E2C6;
499
+ --base-color-warn-200: #EEC891;
500
+ --base-color-warn-300: #E0A95C;
501
+ --base-color-warn-400: #C68B3C;
502
+ --base-color-warn-500: #9C6824;
503
+ --base-color-warn-600: #7D531D;
504
+ --base-color-warn-700: #5E3E16;
505
+ --base-color-warn-800: #3F2A0F;
506
+ --base-color-warn-900: #261907;
507
+ --base-color-warn-1000: #130D04;
508
+ --semantic-color-text-default: #3B2F2C;
509
+ --semantic-color-text-muted: #6B5C55;
510
+ --semantic-color-text-inverse: #FFFFFF;
511
+ --semantic-color-text-accent: var(--base-color-accent-600);
512
+ --semantic-color-surface-page: #FAF4EF;
513
+ --semantic-color-surface-card: #FFFFFF;
514
+ --semantic-color-surface-field: #FFFFFF;
515
+ --semantic-color-surface-panel: #FFFDFB;
516
+ --semantic-color-surface-raised: #F6ECE4;
517
+ --semantic-color-border-subtle: #EFE0D6;
518
+ --semantic-color-border-default: #DDC8BB;
519
+ --semantic-color-border-strong: #BCA294;
520
+ --semantic-color-action-background: var(--base-color-accent-500);
521
+ --semantic-color-action-background-hover: var(--base-color-accent-600);
522
+ --semantic-color-action-background-pressed: var(--base-color-accent-700);
523
+ --semantic-color-action-foreground: var(--base-color-accent-0);
524
+ --semantic-color-action-foreground-pressed: var(--base-color-accent-100);
525
+ --semantic-color-action-surface: var(--base-color-accent-50);
526
+ --semantic-color-action-border: var(--base-color-accent-300);
527
+ --semantic-color-status-error-background: var(--base-color-error-500);
528
+ --semantic-color-status-error-surface: var(--base-color-error-50);
529
+ --semantic-color-status-error-border: var(--base-color-error-300);
530
+ --semantic-color-status-error-foreground: var(--base-color-error-0);
531
+ --semantic-color-status-warn-background: var(--base-color-warn-500);
532
+ --semantic-color-status-warn-surface: var(--base-color-warn-50);
533
+ --semantic-color-status-warn-border: var(--base-color-warn-300);
534
+ --semantic-color-status-warn-foreground: var(--base-color-warn-0);
535
+ --semantic-color-status-success-background: var(--base-color-success-500);
536
+ --semantic-color-status-success-surface: var(--base-color-success-50);
537
+ --semantic-color-status-success-border: var(--base-color-success-300);
538
+ --semantic-color-status-success-foreground: var(--base-color-success-0);
539
+ --semantic-color-status-info-background: var(--base-color-info-500);
540
+ --semantic-color-status-info-surface: var(--base-color-info-50);
541
+ --semantic-color-status-info-border: var(--base-color-info-300);
542
+ --semantic-color-status-info-foreground: var(--base-color-info-0);
543
+ --component-button-primary-background: var(--semantic-color-action-background);
544
+ --component-button-primary-background-hover: var(--semantic-color-action-background-hover);
545
+ --component-button-primary-background-pressed: var(--semantic-color-action-background-pressed);
546
+ --component-button-primary-foreground: var(--base-color-accent-0);
547
+ --component-button-primary-foreground-hover: var(--base-color-accent-50);
548
+ --component-button-primary-foreground-pressed: var(--base-color-accent-100);
549
+ --component-button-primary-border: var(--semantic-color-action-background);
550
+ --component-button-secondary-background: var(--base-color-accent-0);
551
+ --component-button-secondary-background-hover: var(--base-color-accent-50);
552
+ --component-button-secondary-background-pressed: var(--base-color-accent-100);
553
+ --component-button-secondary-foreground: var(--base-color-accent-600);
554
+ --component-button-secondary-foreground-hover: var(--base-color-accent-700);
555
+ --component-button-secondary-foreground-pressed: var(--base-color-accent-800);
556
+ --component-button-secondary-border: var(--base-color-accent-500);
557
+ --component-button-secondary-border-hover: var(--base-color-accent-700);
558
+ --component-button-secondary-border-pressed: var(--base-color-accent-800);
559
+ --component-button-tertiary-background: transparent;
560
+ --component-button-tertiary-background-hover: var(--base-color-accent-50);
561
+ --component-button-tertiary-background-pressed: var(--base-color-accent-100);
562
+ --component-button-tertiary-foreground: var(--base-color-accent-600);
563
+ --component-button-tertiary-foreground-hover: var(--base-color-accent-700);
564
+ --component-button-tertiary-foreground-pressed: var(--base-color-accent-800);
565
+ --component-button-tertiary-border: transparent;
566
+ --component-button-tertiary-border-hover: var(--base-color-accent-50);
567
+ --component-button-tertiary-border-pressed: var(--base-color-accent-100);
568
+ --component-button-focus-ring: var(--base-color-accent-300);
569
+ --base-radius-md: 0.625rem;
570
+ --base-radius-lg: 0.875rem;
571
+ --base-radius-xl: 14px;
572
+ --component-card-border-radius: 16px;
573
+ --component-dialog-border-radius: 16px;
574
+ --component-button-font-family: var(--theme-a1-crochet-font-family-body);
575
+ --component-paragraph-font-family: var(--theme-a1-crochet-font-family-body);
576
+ --component-heading-font-family-heading: var(--theme-a1-crochet-font-family-heading);
577
+ --component-heading-font-family-display: var(--theme-a1-crochet-font-family-display);
578
+ --semantic-font-weight-body: var(--theme-a1-crochet-font-weight-body);
579
+ --semantic-font-weight-heading: var(--theme-a1-crochet-font-weight-heading);
580
+ --semantic-font-weight-display: var(--theme-a1-crochet-font-weight-display);
581
+ --component-paragraph-font-weight: var(--theme-a1-crochet-font-weight-body);
582
+ --component-heading-font-weight-heading: var(--theme-a1-crochet-font-weight-heading);
583
+ --component-heading-font-weight-display: var(--theme-a1-crochet-font-weight-display);
584
+ }
585
+
586
+
296
587
  /* ────────────────────────────────────────────────────────────
297
588
  Fresh
298
589
  A crisp, airy theme with sky-blue accents, Nunito body text (ExtraBold headings), Baskerville display typography, and a cool mint gradient background. Apply class="a1-theme-fresh" to <html>.
@@ -559,6 +850,8 @@ html.a1-theme-heritage {
559
850
  --component-button-tertiary-border-pressed: var(--base-color-accent-100);
560
851
  --component-button-focus-ring: var(--base-color-accent-300);
561
852
  --base-radius-control: 2px;
853
+ --base-radius-sm: 1px;
854
+ --base-radius-md: 2px;
562
855
  --base-radius-lg: 3px;
563
856
  --base-radius-xl: 4px;
564
857
  --component-button-border-radius: 2px;
package/src/tokens.css CHANGED
@@ -347,6 +347,13 @@
347
347
  --component-bottom-drawer-height: 3.5rem;
348
348
  --component-bottom-drawer-border-width: 1px;
349
349
  --component-bottom-drawer-z-index: 200;
350
+ --component-bottom-sheet-header-height: 3.5rem;
351
+ --component-bottom-sheet-border-radius: 0.5rem;
352
+ --component-bottom-sheet-handle-width: 2.5rem;
353
+ --component-bottom-sheet-handle-height: 0.25rem;
354
+ --component-bottom-sheet-padding: 1rem;
355
+ --component-bottom-sheet-background: #ffffff;
356
+ --component-bottom-sheet-z-index: 200;
350
357
  --component-calendar-month-gap: 2rem;
351
358
  --component-calendar-heading-padding-block: 0.75rem;
352
359
  --component-calendar-heading-padding-block-compact: 0.5rem;
@@ -658,9 +665,11 @@
658
665
  --component-segmented-padding: 0.1875rem;
659
666
  --component-segmented-gap: 0.125rem;
660
667
  --component-segmented-segment-padding-block: 0.25rem;
661
- --component-segmented-segment-padding-inline: 0.75rem;
668
+ --component-segmented-segment-padding-inline: 0.5rem;
662
669
  --component-segmented-segment-padding-block-sm: 0.125rem;
663
670
  --component-segmented-segment-padding-inline-sm: 0.5rem;
671
+ --component-segmented-segment-padding-block-lg: 0.5rem;
672
+ --component-segmented-segment-padding-inline-lg: 1rem;
664
673
  --component-segmented-border-width: 1px;
665
674
  --component-segmented-font-weight-default: 400;
666
675
  --component-segmented-font-weight-active: 500;
@@ -975,6 +984,12 @@
975
984
  --theme-a1-accessible-font-user-size-medium: 1rem;
976
985
  --theme-a1-accessible-font-user-size-large: 1.125rem;
977
986
  --theme-a1-accessible-font-user-size-xl: 1.25rem;
987
+ --theme-a1-aperture-font-family-body: 'Manrope', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
988
+ --theme-a1-aperture-font-family-heading: 'Playfair Display', Georgia, Cambria, 'Times New Roman', serif;
989
+ --theme-a1-aperture-font-family-display: 'Pinyon Script', 'Tangerine', 'Snell Roundhand', cursive;
990
+ --theme-a1-aperture-font-weight-body: 400;
991
+ --theme-a1-aperture-font-weight-heading: 600;
992
+ --theme-a1-aperture-font-weight-display: 400;
978
993
  --theme-a1-catlympics-font-family-body: 'Nunito Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
979
994
  --theme-a1-catlympics-font-family-heading: 'Patrick Hand SC', system-ui, -apple-system, sans-serif;
980
995
  --theme-a1-catlympics-font-family-display: 'Baloo 2', system-ui, -apple-system, sans-serif;
@@ -982,6 +997,12 @@
982
997
  --theme-a1-catlympics-font-weight-body: 400;
983
998
  --theme-a1-catlympics-font-weight-heading: 400;
984
999
  --theme-a1-catlympics-font-weight-display: 700;
1000
+ --theme-a1-crochet-font-family-body: 'Roboto Slab', 'Bitter', Rockwell, 'Roboto Slab', Georgia, serif;
1001
+ --theme-a1-crochet-font-family-heading: 'Libre Baskerville', Georgia, Cambria, 'Times New Roman', serif;
1002
+ --theme-a1-crochet-font-family-display: 'Fraunces', 'Playfair Display', Georgia, Cambria, 'Times New Roman', serif;
1003
+ --theme-a1-crochet-font-weight-body: 400;
1004
+ --theme-a1-crochet-font-weight-heading: 700;
1005
+ --theme-a1-crochet-font-weight-display: 600;
985
1006
  --theme-a1-fresh-font-family-body: Nunito, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
986
1007
  --theme-a1-fresh-font-family-heading: Nunito, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
987
1008
  --theme-a1-fresh-font-family-display: Baskerville, 'Baskerville Old Face', 'Libre Baskerville', Georgia, Cambria, serif;