@rojaostudio/ds 2.0.0-next.13 → 2.0.0-next.15

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
@@ -26,7 +26,7 @@ Add `dark` to `<html>` (or any element) for dark mode:
26
26
  <html class="dark">
27
27
  ```
28
28
 
29
- The stylesheet declares its layers first (`rds.theme`, `rds.tokens`, `rds.components`), so your own unlayered CSS
29
+ The stylesheet declares its layers first (`rds.legacy`, `rds.theme`, `rds.tokens`, `rds.components`), so your own unlayered CSS
30
30
  always wins over the design system without `!important`. The components need no Tailwind and no other stylesheet.
31
31
 
32
32
  ### Legacy: `base.css` (deprecated)
@@ -42,6 +42,41 @@ utilities (`bg-surface-*`, `text-fg-*`, `h-control-*`…) and its CSS variables,
42
42
  @import "@rojaostudio/ds/styles/rds.css";
43
43
  ```
44
44
 
45
+ Both stylesheets declare the same layer order, `rds.legacy, rds.theme, rds.tokens, rds.components`, and everything
46
+ in `base.css` (its variables, the primitives, the `h1`–`h6` rule, the `rojao-*` animations) lives in `rds.legacy`.
47
+ So, whatever the import order, the 2.0 wins wherever the two declare the same variable: 31 names, among them
48
+ `--surface-page`, `--text-muted`, `--text-disabled`, `--border-default`, `--border-strong`, `--radius-card`,
49
+ `--radius-control`, `--z-modal`, `--z-dropdown`, `--z-tooltip`, `--space-4` … `--space-64`, `--toast-text`,
50
+ `--toast-border`. A 1.x utility that reads one of them (`bg-surface-page`, `text-fg-muted` through
51
+ `--text-muted`) shows the 2.0 value while both are imported; the 1.x-only names (`--brand-primary`,
52
+ `--surface-default`…) keep theirs. Tailwind's `@utility` and `@theme` blocks stay at the top level, as Tailwind
53
+ requires, and the focus ring stays in Tailwind's `base` layer, so `outline-none` still wins over it. Your own
54
+ unlayered CSS wins over all of it.
55
+
56
+ ## Theme scopes
57
+
58
+ The shipped theme switches on `.dark`, `.ds-plate` and `.ds-scope`, and on three generic attributes:
59
+ `data-rds-mode="dark"`, `data-rds-plate` and `data-rds-scope`. The component tokens are declared again on each of
60
+ them (`RDS_SCOPE_SELECTORS` in `@rojaostudio/ds-core/generate`): a component token holds `var(--theme-role)`, which
61
+ resolves where it is declared, so a theme switched on an element none of them match would repaint the roles but
62
+ not the components inside.
63
+
64
+ ```html
65
+ <section data-rds-mode="dark">…</section> <!-- a dark section on a light page -->
66
+ ```
67
+
68
+ For your own theme, `emitRdsCss(theme, { scope, dark, plate })` checks each selector against that list and throws
69
+ on one the components would not follow:
70
+
71
+ ```ts
72
+ emitRdsCss(theme, { scope: ".my-scope[data-rds-scope]" }); // <div class="my-scope" data-rds-scope>
73
+ emitRdsCss(theme, { scope: ":root", dark: ':root[data-theme="dark"]' }); // next-themes, attribute="data-theme"
74
+ emitRdsCss(theme, { scope: ".my-scope" }); // throws: add data-rds-scope
75
+ ```
76
+
77
+ A dark selector anchored at the root (`:root[…]`, `html…`) is used as is, which is where next-themes puts its
78
+ attribute. `allowUncovered: true` skips the check, for a theme read only by your own CSS.
79
+
45
80
  ## Import the component, not the barrel
46
81
 
47
82
  ```tsx
@@ -1,13 +1,17 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- type CardSurface = 'default' | 'tint';
4
+ type CardSurface = 'default' | 'outline' | 'tint';
5
5
  type CardSize = 'default' | 'sm';
6
6
  type Heading = 'h2' | 'h3' | 'h4';
7
7
  interface CardProps extends HTMLAttributes<HTMLElement> {
8
- /** tint is the brand's light background, with no border, for a card that stands out. */
8
+ /**
9
+ * default: white, with a border and elevation/raised; the default, for a topic on its own on the page.
10
+ * outline: only the border, no fill nor shadow, it takes the surface underneath; for cards side by side in a grid,
11
+ * inside a panel or a list. tint: the brand's light plate, no border nor shadow; a rare highlight, one per screen.
12
+ */
9
13
  surface?: CardSurface;
10
- /** sm aligns everything on 12 and makes the header text smaller, for dense lists and indicators. */
14
+ /** sm pads 16 (default 24) and makes the header text smaller, for dense lists and indicators. */
11
15
  size?: CardSize;
12
16
  /** article (default) for a topic that reads on its own; section or div when it is part of something larger. */
13
17
  as?: 'article' | 'section' | 'div';
@@ -31,7 +35,7 @@ interface CardHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
31
35
  description?: ReactNode;
32
36
  /** A Tile before the text (Figma: `showIcon`): variant soft, size default (sm on a small card). */
33
37
  icon?: ReactNode;
34
- /** One action on the right (Figma: `showAction` + `action`): a ghost Button or an IconButton. */
38
+ /** Opt-in: one action on the right (Figma: `showAction` + `action`), a ghost Button or an IconButton. None by default. */
35
39
  action?: ReactNode;
36
40
  /** start: side by side; center: stacked and centred. */
37
41
  align?: 'start' | 'center';
@@ -42,14 +46,17 @@ type CardContentProps = HTMLAttributes<HTMLDivElement>;
42
46
  /** The card's content (Figma: the `cardContent` slot). */
43
47
  declare function CardContent({ className, ...rest }: CardContentProps): react.JSX.Element;
44
48
  interface CardFooterProps extends HTMLAttributes<HTMLElement> {
45
- /** One or two Buttons (Figma: `actions` one · two). A third action goes into the content, as a link. */
49
+ /**
50
+ * One or two Buttons (Figma: `actions` one · two), side by side: the main one (action fill) last, the secondary one
51
+ * a neutral ghost Button before it. A third action goes into the content, as a link.
52
+ */
46
53
  children: ReactNode;
47
- /** start, end, or full (buttons stacked across the whole width). */
54
+ /** start, end (default), or full (the two side by side, half each, for a narrow card on a phone). */
48
55
  align?: 'start' | 'end' | 'full';
49
56
  /** A line under the buttons (Figma: `showTertiaryContent` + `tertiaryContent`), such as a sign-up link. */
50
57
  note?: ReactNode;
51
58
  }
52
- /** The card's footer, with its actions (Figma: .card/footer). */
59
+ /** The card's footer, with its actions (Figma: .card/footer). No band and no rule: spacing sets it apart. */
53
60
  declare function CardFooter({ align, note, className, children, ...rest }: CardFooterProps): react.JSX.Element;
54
61
 
55
62
  export { Card, CardContent, type CardContentProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, type CardSize, type CardSurface };
@@ -20,19 +20,21 @@ type DataTableFilterDef = {
20
20
  options: DataTableFilterOption[];
21
21
  onChange: (v: string) => void;
22
22
  };
23
- type DataTablePillDef = {
24
- key: string;
25
- label: string;
26
- active: boolean;
27
- count?: number;
28
- onClick: () => void;
29
- };
30
23
  type DataTableHeaderProps = {
31
24
  search?: DataTableHeaderSearch;
32
25
  filters?: DataTableFilterDef[];
33
- /** Quick filters, always in view: FilterChips. */
34
- pillFilters?: DataTablePillDef[];
26
+ /**
27
+ * Quick filters, always in view (Figma: `showQuickFilters` + the `quickFilters` slot): up to three, a
28
+ * FilterChipGroup with its FilterChips; four or more, one Button with a menu (DropdownMenu), "Categoria: Todas".
29
+ */
30
+ quickFilters?: ReactNode;
31
+ /** Clears the `filters` (the quick filters are cleared where they are, in view). */
35
32
  onClear?: () => void;
33
+ /**
34
+ * A view control after the filters and before the actions (Figma: `showView` + the `view` slot), such as a
35
+ * Checkbox "Agrupar por produto". In view on a narrow screen too.
36
+ */
37
+ view?: ReactNode;
36
38
  actions?: ReactNode;
37
39
  className?: string;
38
40
  /** On a narrow screen, moves the filters and the actions into a Drawer. The quick filters stay in view. */
@@ -45,10 +47,13 @@ declare function FilterDropdown({ f, placement }: {
45
47
  }): react.JSX.Element;
46
48
  /**
47
49
  * DataTableHeader — a composition of the Input (search), FilterChips, Buttons, the DropdownMenu, the Popover and
48
- * the Drawer: the bar above a table. The search fills the row; quick filters are FilterChips; one filter is a
49
- * dropdown, two or more collapse into "Filtros" (the active ones stay in view as removable Chips). From 768 the
50
- * wide layout shows; below it, the filters open in a Drawer or a Popover. Styles: data-table-header.css.
50
+ * the Drawer: the bar above a table. The search is always on the left and takes the free width (at least 320); the
51
+ * filters are always on the right; what does not fit wraps. Quick filters go in the `quickFilters` slot; one filter
52
+ * is a dropdown, two or more collapse into "Filtros" (the active ones stay in view as removable Chips); the `view`
53
+ * control comes after the filters, before the actions. From 768 the wide layout shows; below it, the filters open
54
+ * in a Drawer or a Popover. "Filtros · N" counts the active `filters`, the ones that button opens.
55
+ * Styles: data-table-header.css.
51
56
  */
52
- declare function DataTableHeader({ search, filters, pillFilters, onClear, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
57
+ declare function DataTableHeader({ search, filters, quickFilters, onClear, view, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
53
58
 
54
- export { type DataTableFilterDef, type DataTableFilterOption, DataTableHeader, type DataTableHeaderProps, type DataTableHeaderSearch, type DataTablePillDef, FilterDropdown };
59
+ export { type DataTableFilterDef, type DataTableFilterOption, DataTableHeader, type DataTableHeaderProps, type DataTableHeaderSearch, FilterDropdown };
@@ -100,19 +100,20 @@ function MobileSingleFilter({ f }) {
100
100
  function DataTableHeader({
101
101
  search,
102
102
  filters = [],
103
- pillFilters = [],
103
+ quickFilters,
104
104
  onClear,
105
+ view,
105
106
  actions,
106
107
  className,
107
108
  mobileCollapse = false
108
109
  }) {
109
110
  var _a, _b;
110
111
  const [sheetOpen, setSheetOpen] = useState(false);
111
- const activeFilterCount = filters.filter((f) => f.value !== "").length + pillFilters.filter((p) => p.active).length;
112
+ const activeFilterCount = filters.filter((f) => f.value !== "").length;
112
113
  const collapseDesktop = filters.length >= 2;
113
114
  const activeFilters = filters.filter((f) => f.value !== "");
114
115
  const singleFilter = filters.length === 1 ? filters[0] : null;
115
- const lead = Boolean(search || pillFilters.length > 0);
116
+ const lead = Boolean(search || quickFilters);
116
117
  return /* @__PURE__ */ jsxs("div", { className: ["rds-data-table-header", className].filter(Boolean).join(" "), children: [
117
118
  search && /* @__PURE__ */ jsx(
118
119
  Input,
@@ -128,7 +129,7 @@ function DataTableHeader({
128
129
  onChange: (e) => search.onChange(e.target.value)
129
130
  }
130
131
  ),
131
- pillFilters.length > 0 && /* @__PURE__ */ jsx(FilterChipGroup, { "aria-label": "Filtros r\xE1pidos", "data-pill-filter": "", children: pillFilters.map((p) => /* @__PURE__ */ jsx(FilterChip, { active: p.active, count: p.count, onClick: p.onClick, children: p.label }, p.key)) }),
132
+ quickFilters && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__quick", children: quickFilters }),
132
133
  filters.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__wide", children: [
133
134
  lead && /* @__PURE__ */ jsx(Separator, { orientation: "vertical" }),
134
135
  collapseDesktop ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -176,6 +177,7 @@ function DataTableHeader({
176
177
  actions && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__drawer-actions", children: actions })
177
178
  ] }) })
178
179
  ] }),
180
+ view && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__view", children: view }),
179
181
  actions && /* @__PURE__ */ jsx("div", { className: mobileCollapse ? "rds-data-table-header__wide" : "rds-data-table-header__actions", children: actions })
180
182
  ] });
181
183
  }
@@ -8,7 +8,7 @@ export { DropdownMenu, DropdownMenuAlign, DropdownMenuItem, DropdownMenuItemProp
8
8
  export { ContextMenu, ContextMenuItem, ContextMenuItemProps, ContextMenuItemTone, ContextMenuProps, ContextMenuSeparator } from './context-menu.js';
9
9
  export { Command, CommandGroup, CommandGroupProps, CommandItem, CommandItemProps, CommandProps } from './command.js';
10
10
  export { FilterChip, FilterChipGroup, FilterChipGroupProps, FilterChipProps } from './filter-chip.js';
11
- export { DataTableFilterDef, DataTableFilterOption, DataTableHeader, DataTableHeaderProps, DataTableHeaderSearch, DataTablePillDef, FilterDropdown } from './data-table-header.js';
11
+ export { DataTableFilterDef, DataTableFilterOption, DataTableHeader, DataTableHeaderProps, DataTableHeaderSearch, FilterDropdown } from './data-table-header.js';
12
12
  export { Button, ButtonIconPosition, ButtonProps } from './button.js';
13
13
  export { Badge, BadgeProps, BadgeTone, BadgeVariant, formatBadgeValue } from './badge.js';
14
14
  export { Status, StatusProps, StatusSize, StatusTone, StatusVariant } from './status.js';
@@ -34,24 +34,24 @@ function SavingBar(_a) {
34
34
  ]);
35
35
  const saving = status === "saving";
36
36
  const error = status === "error";
37
- return /* @__PURE__ */ jsxs(
37
+ return /* @__PURE__ */ jsx(
38
38
  "div",
39
39
  __spreadProps(__spreadValues({
40
40
  role: "region",
41
41
  "aria-label": "Salvar altera\xE7\xF5es"
42
42
  }, rest), {
43
43
  className: ["rds-savingbar", className].filter(Boolean).join(" "),
44
- children: [
44
+ children: /* @__PURE__ */ jsxs("div", { className: "rds-savingbar__row", children: [
45
45
  /* @__PURE__ */ jsxs("p", { className: "rds-savingbar__message", role: "status", children: [
46
46
  saving && /* @__PURE__ */ jsx("span", { className: "rds-savingbar__icon rds-savingbar__loader", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Loader, {}) }),
47
47
  error && /* @__PURE__ */ jsx("span", { className: "rds-savingbar__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(AlertIcon, {}) }),
48
- /* @__PURE__ */ jsx("span", { children: saving ? savingMessage : error ? errorMessage : message })
48
+ /* @__PURE__ */ jsx("span", { className: "rds-savingbar__text", children: saving ? savingMessage : error ? errorMessage : message })
49
49
  ] }),
50
50
  /* @__PURE__ */ jsxs("div", { className: "rds-savingbar__actions", children: [
51
51
  onDiscard && /* @__PURE__ */ jsx(Button, { tone: "inverse", variant: "ghost", disabled: saving, onClick: onDiscard, children: discardLabel }),
52
52
  /* @__PURE__ */ jsx(Button, { tone: "inverse", variant: "fill", disabled: saving, onClick: onSave, children: error ? retryLabel : saveLabel })
53
53
  ] })
54
- ]
54
+ ] })
55
55
  })
56
56
  );
57
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rojaostudio/ds",
3
- "version": "2.0.0-next.13",
3
+ "version": "2.0.0-next.15",
4
4
  "type": "module",
5
5
  "description": "Rojão Design System — componentes React, estilos e alvo React Native. O motor vive em @rojaostudio/ds-core.",
6
6
  "license": "MIT",
@@ -190,7 +190,7 @@
190
190
  "@radix-ui/react-toggle": "^1.1.18",
191
191
  "@radix-ui/react-toggle-group": "^1.1.19",
192
192
  "@radix-ui/react-tooltip": "^1.2.16",
193
- "@rojaostudio/ds-core": "1.1.0-next.6"
193
+ "@rojaostudio/ds-core": "1.1.0-next.7"
194
194
  },
195
195
  "scripts": {
196
196
  "build": "pnpm run build:tokens && pnpm run build:themes && pnpm run build:rds && pnpm run build:native && tsup",
package/styles/base.css CHANGED
@@ -26,9 +26,17 @@
26
26
  Run `pnpm build:tokens` in the DS to regenerate.
27
27
  ───────────────────────────────────────────────────────────── */
28
28
 
29
+ /* Cascade layers, lowest first: the same order rds.css declares, whichever of the two is imported first.
30
+ Everything of this file except Tailwind's @utility and @theme blocks (which Tailwind wants at the top level)
31
+ lives in rds.legacy, below rds.theme: with rds.css also imported, the 2.0 variables win wherever the names
32
+ collide (--surface-page, --text-muted, --border-default, --radius-card, --z-modal, --space-*, --toast-text…)
33
+ and the h1–h6 rule loses to the 2.0 components. */
34
+ @layer rds.legacy, rds.theme, rds.tokens, rds.components;
35
+
29
36
  /* Primitives — auto-generated from tokens/index.ts */
30
- @import "./_primitives.generated.css";
37
+ @import "./_primitives.generated.css" layer(rds.legacy);
31
38
 
39
+ @layer rds.legacy {
32
40
  /* ── CSS Custom Properties — light (default, neutral theme) ── */
33
41
  /* .ds-scope: qualquer wrapper que precise recalcular tokens de COMPONENTE (ex.
34
42
  --option-tile-bg) sob um override local de token SEMÂNTICO (ex. --surface-default)
@@ -724,6 +732,7 @@ h1, h2, h3, h4, h5, h6 {
724
732
  .rojao-toast--enter-top, .rojao-toast--enter-bottom,
725
733
  .rojao-toast--exit-top, .rojao-toast--exit-bottom { animation: none; }
726
734
  }
735
+ } /* @layer rds.legacy */
727
736
 
728
737
  /* ── Control size utilities — h-control-sm/md/lg, size-control-sm/md/lg ── */
729
738
  @utility h-control-sm { height: var(--space-control-height-sm); }
@@ -925,6 +934,9 @@ h1, h2, h3, h4, h5, h6 {
925
934
  * sem ele, num botão com borda da mesma família de cor, o anel some dentro da
926
935
  * borda. E ele é desenhado com a cor da superfície, então funciona igual sobre
927
936
  * fundo claro e sobre o escuro do chrome.
937
+ *
938
+ * Stays in Tailwind's `base` layer, not in rds.legacy: it sets no variable, and in `base` Tailwind's utilities
939
+ * (`outline-none`) still win over it, as they did in 1.x. Both layers sit below the rds.* ones.
928
940
  */
929
941
  @layer base {
930
942
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
@@ -1749,34 +1749,45 @@ button.rds-breadcrumb__link:focus-visible {
1749
1749
  /* components/card.css */
1750
1750
  /* @tokens card */
1751
1751
  /*
1752
- * Card (Content collection, card/*): header, content and footer. default pads 16, sm pads 12. tint is the brand's
1753
- * light background, with no border. Corners in radius/container, shadow elevation/raised.
1752
+ * Card (Content collection, card/*): header, content and footer. default pads 24, sm pads 16; 24 between the
1753
+ * header, the content and the actions (sm: 16). Corners in radius/container.
1754
+ * default: card/background, a card/border hairline and elevation/raised.
1755
+ * outline: only the hairline, no fill, no shadow; it takes the surface underneath (cards side by side in a grid,
1756
+ * inside a panel or a list, where stacked shadows turn into noise).
1757
+ * tint: the brand's light plate (card/tint/background), no border, no shadow, title in card/tint/title.
1758
+ * The footer has no band and no rule: the actions sit side by side, the main one last (on the right). The
1759
+ * card/footer/background tokens are obsolete in Figma (03/10/2026) and not read here.
1754
1760
  */
1755
1761
  .rds-card {
1756
- --_pad: var(--space-16);
1757
- --_background: var(--card-background);
1758
- --_footer: var(--card-footer-background);
1759
- --_border: var(--card-border);
1762
+ --_pad: var(--space-24);
1763
+ --_title: var(--card-title);
1760
1764
 
1761
1765
  box-sizing: border-box;
1762
1766
  display: flex;
1763
1767
  flex-direction: column;
1764
1768
  overflow: hidden;
1765
- border: var(--border-width) solid var(--_border);
1769
+ border: var(--border-width) solid var(--card-border);
1766
1770
  border-radius: var(--radius-container);
1767
- background: var(--_background);
1771
+ background: var(--card-background);
1768
1772
  box-shadow: var(--elevation-raised);
1769
1773
  font-family: var(--type-font-stack);
1770
1774
  }
1771
1775
 
1772
1776
  .rds-card--sm {
1773
- --_pad: var(--space-12);
1777
+ --_pad: var(--space-16);
1778
+ }
1779
+
1780
+ .rds-card--outline {
1781
+ background: transparent;
1782
+ box-shadow: none;
1774
1783
  }
1775
1784
 
1776
1785
  .rds-card--tint {
1777
- --_background: var(--card-tint-background);
1778
- --_footer: var(--card-tint-footer-background);
1779
- --_border: transparent;
1786
+ --_title: var(--card-tint-title);
1787
+
1788
+ border-color: transparent;
1789
+ background: var(--card-tint-background);
1790
+ box-shadow: none;
1780
1791
  }
1781
1792
 
1782
1793
  .rds-card__header {
@@ -1807,7 +1818,7 @@ button.rds-breadcrumb__link:focus-visible {
1807
1818
 
1808
1819
  .rds-card__title {
1809
1820
  margin: 0;
1810
- color: var(--card-title);
1821
+ color: var(--_title);
1811
1822
  font-size: var(--type-label-size);
1812
1823
  line-height: var(--type-label-line);
1813
1824
  font-weight: 500;
@@ -1846,32 +1857,27 @@ button.rds-breadcrumb__link:focus-visible {
1846
1857
  display: flex;
1847
1858
  flex-direction: column;
1848
1859
  gap: var(--space-16);
1849
- padding: var(--_pad);
1850
- border-top: var(--border-width) solid var(--card-border);
1851
- background: var(--_footer);
1852
- }
1853
-
1854
- .rds-card--tint .rds-card__footer {
1855
- border-top-color: transparent;
1860
+ padding: 0 var(--_pad) var(--_pad);
1856
1861
  }
1857
1862
 
1858
1863
  .rds-card__actions {
1859
1864
  display: flex;
1860
1865
  flex-wrap: wrap;
1861
- gap: var(--space-16);
1866
+ gap: var(--space-12);
1862
1867
  }
1863
1868
 
1864
1869
  .rds-card__footer--end .rds-card__actions {
1865
1870
  justify-content: flex-end;
1866
1871
  }
1867
1872
 
1873
+ /* full: the two actions side by side, half each, for a narrow card on a phone. */
1868
1874
  .rds-card__footer--full .rds-card__actions {
1869
- flex-direction: column;
1870
- gap: var(--space-8);
1875
+ flex-wrap: nowrap;
1871
1876
  }
1872
1877
 
1873
1878
  .rds-card__footer--full .rds-card__actions > * {
1874
- width: 100%;
1879
+ flex: 1 1 0;
1880
+ min-width: 0;
1875
1881
  }
1876
1882
 
1877
1883
  .rds-card__note {
@@ -1882,8 +1888,7 @@ button.rds-breadcrumb__link:focus-visible {
1882
1888
  }
1883
1889
 
1884
1890
  @media (forced-colors: active) {
1885
- .rds-card,
1886
- .rds-card--tint .rds-card__footer {
1891
+ .rds-card {
1887
1892
  border-color: CanvasText;
1888
1893
  }
1889
1894
  }
@@ -3229,7 +3234,7 @@ input:focus-visible + .rds-checkbox__box {
3229
3234
  .rds-color-input__swatch:focus-visible,
3230
3235
  .rds-color-input__swatch:has(.rds-color-input__native:focus-visible) {
3231
3236
  outline: var(--focus-ring-width) solid var(--_border-focus);
3232
- outline-offset: var(--border-width);
3237
+ outline-offset: var(--focus-ring-width);
3233
3238
  }
3234
3239
 
3235
3240
  .rds-color-input__native {
@@ -3296,14 +3301,15 @@ input:focus-visible + .rds-checkbox__box {
3296
3301
  cursor: pointer;
3297
3302
  }
3298
3303
 
3304
+ /* Selected and focus: the ring of Button and Checkbox, focus-ring-width wide and as far off the swatch (a gap). */
3299
3305
  .rds-color-input__choice[aria-pressed='true'] {
3300
- outline: calc(var(--border-width) * 2) solid var(--color-input-swatch-selected);
3301
- outline-offset: var(--border-width);
3306
+ outline: var(--focus-ring-width) solid var(--color-input-swatch-selected);
3307
+ outline-offset: var(--focus-ring-width);
3302
3308
  }
3303
3309
 
3304
3310
  .rds-color-input__choice:focus-visible {
3305
3311
  outline: var(--focus-ring-width) solid var(--color-input-border-focus);
3306
- outline-offset: var(--border-width);
3312
+ outline-offset: var(--focus-ring-width);
3307
3313
  }
3308
3314
 
3309
3315
  @media (forced-colors: active) {
@@ -3578,23 +3584,29 @@ input:focus-visible + .rds-checkbox__box {
3578
3584
  /* components/data-table-header.css */
3579
3585
  /* @tokens data-table-header */
3580
3586
  /*
3581
- * DataTableHeader: no tokens of its own; the Input, FilterChip, Chip, Button, Separator, DropdownMenu,
3582
- * Popover and Drawer bring theirs. One row, 8 apart, 12 above the table; the search takes the free width. The wide
3583
- * parts show from 768, the narrow ones below it. In the Popover and the Drawer the filters stack 16 apart, each
3584
- * one a caption-sized label over its chips.
3587
+ * DataTableHeader: no tokens of its own; the Input, FilterChip, Chip, Button, Separator, Checkbox, DropdownMenu,
3588
+ * Popover and Drawer bring theirs. One row, 8 apart, 12 above the table, packed to the right: the search on the left
3589
+ * takes the free width, at least 320 (never wider than the bar); the quick filters, the filters, the view control
3590
+ * and the actions follow it on the right, and what does not fit wraps. The wide parts show from 768, the narrow ones
3591
+ * below it. In the Popover and the Drawer the filters stack 16 apart, each one a caption-sized label over its chips.
3585
3592
  */
3586
3593
  .rds-data-table-header {
3587
3594
  display: flex;
3588
3595
  flex-wrap: wrap;
3589
3596
  align-items: center;
3597
+ justify-content: flex-end;
3590
3598
  gap: var(--space-8);
3591
3599
  margin-bottom: var(--space-12);
3592
3600
  }
3593
3601
 
3594
- .rds-data-table-header__search {
3595
- flex: 1 1 calc(var(--space-64) * 4);
3602
+ /* Scoped to the bar: the field's own `min-width: 0` (internal/field.css) comes later in the bundle. */
3603
+ .rds-data-table-header .rds-data-table-header__search {
3604
+ flex: 1 1 calc(var(--space-64) * 5);
3605
+ min-width: min(calc(var(--space-64) * 5), 100%);
3596
3606
  }
3597
3607
 
3608
+ .rds-data-table-header__quick,
3609
+ .rds-data-table-header__view,
3598
3610
  .rds-data-table-header__wide,
3599
3611
  .rds-data-table-header__actions,
3600
3612
  .rds-data-table-header__narrow {
@@ -7347,7 +7359,7 @@ body:has(.rds-modal) {
7347
7359
  /*
7348
7360
  * PageSkeleton and CardsSkeleton: no tokens of their own; the Skeleton and the Card bring theirs. Blocks 24 apart
7349
7361
  * (24 padding when padded). The Cards keep their elevation/raised, as in the Figma. The table is a small Card: the
7350
- * header row on the card's footer background, a line between rows. The cards: 2 per row (4 from 1024), the charts
7362
+ * header row on the table header background (table/header/background), a line between rows. The cards: 2 per row (4 from 1024), the charts
7351
7363
  * 1 (2 from 1024), 16 apart.
7352
7364
  */
7353
7365
  .rds-page-skeleton {
@@ -7379,7 +7391,7 @@ body:has(.rds-modal) {
7379
7391
  }
7380
7392
 
7381
7393
  .rds-page-skeleton__row--head {
7382
- background: var(--card-footer-background);
7394
+ background: var(--table-header-background);
7383
7395
  }
7384
7396
 
7385
7397
  .rds-page-skeleton__row .rds-skeleton {
@@ -8376,15 +8388,15 @@ input:focus-visible + .rds-radio__circle {
8376
8388
  /* @tokens savingbar */
8377
8389
  /*
8378
8390
  * SavingBar (Actions collection, savingbar/*): full width (at least 320), 12 24 padding, 16 between the
8379
- * message (label, medium) and the actions (8 apart). The message grows. The Buttons use the inverse
8391
+ * message (label, medium, at most 2 lines with an ellipsis) and the actions (8 apart). The Buttons use the inverse
8380
8392
  * tone, drawn for this band in both modes, so the bar needs no theme switch of its own.
8393
+ * Two arrangements, by the bar's own width (a size container, as the Figma's viewport mode): expanded from 1024,
8394
+ * the message grows (at least 160) beside the actions; compact below it, the message on top and Descartar and
8395
+ * Salvar under it, sharing the width.
8381
8396
  */
8382
8397
  .rds-savingbar {
8383
8398
  box-sizing: border-box;
8384
- display: flex;
8385
- flex-wrap: wrap;
8386
- align-items: center;
8387
- gap: var(--space-16);
8399
+ container-type: inline-size;
8388
8400
  width: 100%;
8389
8401
  min-width: min(320px, 100%);
8390
8402
  padding: var(--space-12) var(--space-24);
@@ -8393,18 +8405,34 @@ input:focus-visible + .rds-radio__circle {
8393
8405
  font-family: var(--type-font-stack);
8394
8406
  }
8395
8407
 
8408
+ .rds-savingbar__row {
8409
+ display: flex;
8410
+ align-items: center;
8411
+ gap: var(--space-16);
8412
+ }
8413
+
8396
8414
  .rds-savingbar__message {
8397
8415
  display: flex;
8398
- flex: 1;
8416
+ flex: 1 1 160px;
8399
8417
  align-items: center;
8400
8418
  gap: var(--space-12);
8401
- min-width: 0;
8419
+ min-width: 160px;
8402
8420
  margin: 0;
8403
8421
  font-size: var(--type-label-size);
8404
8422
  font-weight: 500;
8405
8423
  line-height: var(--type-label-line);
8406
8424
  }
8407
8425
 
8426
+ .rds-savingbar__text {
8427
+ display: -webkit-box;
8428
+ flex: 1;
8429
+ min-width: 0;
8430
+ overflow: hidden;
8431
+ -webkit-box-orient: vertical;
8432
+ -webkit-line-clamp: 2;
8433
+ line-clamp: 2;
8434
+ }
8435
+
8408
8436
  .rds-savingbar__icon {
8409
8437
  display: inline-flex;
8410
8438
  flex: none;
@@ -8435,10 +8463,27 @@ input:focus-visible + .rds-radio__circle {
8435
8463
 
8436
8464
  .rds-savingbar__actions {
8437
8465
  display: flex;
8438
- flex-wrap: wrap;
8466
+ flex: none;
8439
8467
  gap: var(--space-8);
8440
8468
  }
8441
8469
 
8470
+ @container (max-width: 1023px) {
8471
+ .rds-savingbar__row {
8472
+ flex-direction: column;
8473
+ align-items: stretch;
8474
+ }
8475
+
8476
+ .rds-savingbar__message {
8477
+ flex: none;
8478
+ min-width: 0;
8479
+ }
8480
+
8481
+ .rds-savingbar__actions > * {
8482
+ flex: 1 1 0;
8483
+ min-width: 0;
8484
+ }
8485
+ }
8486
+
8442
8487
  @media (forced-colors: active) {
8443
8488
  .rds-savingbar {
8444
8489
  border-top: var(--border-width) solid CanvasText;
@@ -8806,7 +8851,9 @@ input:focus-visible + .rds-radio__circle {
8806
8851
  /*
8807
8852
  * Sidebar (Navigation collection, sidebar/*): 240 wide (64 collapsed), 12 × 8 inside, a 1px border on the right.
8808
8853
  * Header: the brand mark (24) and the module (16/24 medium), 10 apart, 44 tall. Entries of 44, 12 inside, 12 between
8809
- * icon (20) and label (14/20 medium), 4 apart; the current one on the brand tint with the label in colors/primary.
8854
+ * icon (20) and label (14/20 medium), 4 apart; the current one on the brand tint, its label semibold in
8855
+ * sidebar/item/label/active and a 3 × 20 marker on the left in sidebar/item/indicator, so the current entry does not
8856
+ * rest on colour alone.
8810
8857
  * Section labels 11/14 bold, 16 above and 6 below, with a 14 chevron. Foot: who is signed in (12/16) and Sair.
8811
8858
  * dark (deprecated in the Figma) reads sidebar/dark/*; the current entry stays the light pill.
8812
8859
  */
@@ -8911,6 +8958,7 @@ input:focus-visible + .rds-radio__circle {
8911
8958
  }
8912
8959
 
8913
8960
  .rds-sidebar__item {
8961
+ position: relative;
8914
8962
  box-sizing: border-box;
8915
8963
  display: flex;
8916
8964
  align-items: center;
@@ -8970,8 +9018,21 @@ input:focus-visible + .rds-radio__circle {
8970
9018
  color: var(--sidebar-item-label-active);
8971
9019
  }
8972
9020
 
8973
- .rds-sidebar__item[aria-current='page'] .rds-sidebar__count {
8974
- color: var(--sidebar-item-label-active);
9021
+ .rds-sidebar__item[aria-current='page'] .rds-sidebar__label {
9022
+ font-weight: 600;
9023
+ }
9024
+
9025
+ /* Figma .sidebar/item state=active: the marker, 3 × 20, on the left edge, vertically centred, radius 2. */
9026
+ .rds-sidebar__item[aria-current='page']::before {
9027
+ content: '';
9028
+ position: absolute;
9029
+ inset-inline-start: 0;
9030
+ top: 50%;
9031
+ width: 3px;
9032
+ height: var(--size-20);
9033
+ border-radius: 2px;
9034
+ background: var(--sidebar-item-indicator);
9035
+ transform: translateY(-50%);
8975
9036
  }
8976
9037
 
8977
9038
  .rds-sidebar__item:focus-visible,
@@ -9040,6 +9101,10 @@ input:focus-visible + .rds-radio__circle {
9040
9101
  .rds-sidebar__item[aria-current='page'] {
9041
9102
  outline: var(--border-width) solid CanvasText;
9042
9103
  }
9104
+
9105
+ .rds-sidebar__item[aria-current='page']::before {
9106
+ background: Highlight;
9107
+ }
9043
9108
  }
9044
9109
 
9045
9110
  /* components/skeleton.css */
@@ -1,6 +1,6 @@
1
1
  /* GENERATED by scripts/build-rds-tokens.ts from tokens/figma/*.txt. Do not edit. */
2
2
  @layer rds.tokens {
3
- :root, .ds-scope, .dark, .ds-plate {
3
+ :root, .ds-scope, [data-rds-scope], .dark, [data-rds-mode], .ds-plate, [data-rds-plate] {
4
4
  /* actions */
5
5
  --actionbar-background: var(--colors-primary-default);
6
6
  --actionbar-divider: var(--colors-primary-light);
@@ -292,9 +292,6 @@
292
292
  --chart-tooltip-border: var(--border-default);
293
293
  --chart-label: var(--text-body);
294
294
  --chart-tooltip-title: var(--text-heading);
295
- --chart-bar-hover: var(--surface-muted);
296
- --chart-focus-ring: var(--focus-ring);
297
- --chart-tick: var(--border-strong);
298
295
  --carousel-slide-background: var(--surface-muted);
299
296
  --carousel-dot: var(--border-strong);
300
297
  --carousel-dot-active: var(--colors-primary-default);
@@ -374,6 +371,9 @@
374
371
  --choice-card-preview-background: var(--surface-muted);
375
372
  --choice-card-preview-border: var(--border-default);
376
373
  --choice-card-preview-icon: var(--text-subtle);
374
+ --chart-bar-hover: var(--surface-muted);
375
+ --chart-focus-ring: var(--focus-ring);
376
+ --chart-tick: var(--border-strong);
377
377
  --choice-list-item-background-hover: var(--surface-muted);
378
378
  --choice-list-item-background-selected: var(--surface-tint-default);
379
379
  --choice-list-item-indicator: var(--colors-primary-default);
@@ -385,9 +385,10 @@
385
385
  --choice-list-item-trailing-default: var(--text-body);
386
386
  --choice-list-item-trailing-disabled: var(--text-disabled);
387
387
  --choice-list-focus-ring: var(--focus-ring);
388
- --choice-list-item-description-selected: var(--text-on-tint);
389
388
  --heading-default: var(--text-heading);
390
389
  --heading-accent: var(--colors-accent-default);
390
+ --choice-list-item-description-selected: var(--text-on-tint);
391
+ --card-tint-title: var(--text-on-tint);
391
392
 
392
393
  /* external */
393
394
  --google-button-light-background: #ffffff;
@@ -939,7 +940,7 @@
939
940
  --sidebar-item-background-active: var(--surface-tint-default);
940
941
  --sidebar-item-label-default: var(--text-muted);
941
942
  --sidebar-item-label-hover: var(--text-body);
942
- --sidebar-item-label-active: var(--colors-primary-default);
943
+ --sidebar-item-label-active: var(--text-on-tint);
943
944
  --sidebar-module: var(--text-heading);
944
945
  --sidebar-user: var(--text-muted);
945
946
  --pagination-focus-ring: var(--focus-ring);
@@ -977,6 +978,7 @@
977
978
  --tabs-dot-indicator: var(--colors-state-success);
978
979
  --sidebar-section-label: var(--text-subtle);
979
980
  --sidebar-dark-section-label: var(--text-on-primary);
981
+ --sidebar-item-indicator: var(--colors-primary-default);
980
982
 
981
983
  /* overlays */
982
984
  --menu-background: var(--surface-card);
@@ -1,6 +1,6 @@
1
1
  /* GENERATED by scripts/build-rds-tokens.ts from ds-core/figma/foundation.txt. Do not edit. */
2
2
  @layer rds.tokens {
3
- :root, .ds-scope, .dark, .ds-plate {
3
+ :root, .ds-scope, [data-rds-scope], .dark, [data-rds-mode], .ds-plate, [data-rds-plate] {
4
4
  --radius-large: 12px;
5
5
  --radius-small: 8px;
6
6
  --radius-full: 9999px;
@@ -1,13 +1,13 @@
1
- /* GENERATED by scripts/build-rds-tokens.ts from ds-core/figma/theme.txt. Do not edit. */
1
+ /* GENERATED by scripts/build-rds-tokens.ts from ds-core/figma/brands/rojao.rds.json (the Figma [RDS] brand table, figma/export-brand.js). Do not edit. */
2
2
  @layer rds.theme {
3
- :root, .ds-scope {
3
+ :root, .ds-scope, [data-rds-scope] {
4
4
  --colors-primary-light: #6b7488;
5
5
  --colors-primary-default: #1b2a4a;
6
6
  --colors-primary-dark: #1b2a4a;
7
7
  --colors-secondary-light: #6b7488;
8
8
  --colors-secondary-default: #1b2a4a;
9
9
  --colors-secondary-active: #26344f;
10
- --colors-accent-highlight: #ffca96;
10
+ --colors-accent-highlight: #ffe2c6;
11
11
  --colors-accent-default: #ff6a00;
12
12
  --colors-accent-hover: #ff9640;
13
13
  --colors-accent-invert: #ffffff;
@@ -18,15 +18,15 @@
18
18
  --surface-card: #ffffff;
19
19
  --surface-panel: #fafafa;
20
20
  --border-default: #e4e4e7;
21
- --surface-tint-default: #ffca96;
21
+ --surface-tint-default: #e2f0ff;
22
22
  --text-on-action-tonal: #3a465f;
23
23
  --text-on-primary: #ffffff;
24
24
  --text-on-secondary: #ffffff;
25
- --text-on-accent: #000000;
26
- --text-on-tint: #000000;
25
+ --text-on-accent: #1b2a4a;
26
+ --text-on-tint: #1b2a4a;
27
27
  --colors-state-error: #c50003;
28
28
  --colors-state-error-strong: #6f0000;
29
- --surface-tint-strong: #ffb066;
29
+ --surface-tint-strong: #bddeff;
30
30
  --text-on-error: #ffffff;
31
31
  --surface-action-default: #e2f0ff;
32
32
  --surface-action-strong: #bddeff;
@@ -52,8 +52,8 @@
52
52
  --colors-state-success: #4caf50;
53
53
  --text-on-success: #000000;
54
54
  --colors-state-success-strong: #0a7e1c;
55
- --surface-cover: #ff6a00;
56
- --text-on-cover: #000000;
55
+ --surface-cover: #00518d;
56
+ --text-on-cover: #ffffff;
57
57
  --text-subtle: #52525b;
58
58
  --surface-muted: #f4f4f5;
59
59
  --surface-error: #ffe8e5;
@@ -65,7 +65,7 @@
65
65
  --border-strong: #71717a;
66
66
  --border-strong-hover: #52525b;
67
67
  --colors-state-info: #2196f3;
68
- --text-on-info: #000000;
68
+ --text-on-info: #ffffff;
69
69
  --colors-state-warning: #ff9800;
70
70
  --colors-state-warning-strong: #dc7f00;
71
71
  --text-on-warning: #000000;
@@ -84,8 +84,8 @@
84
84
  --chart-series-3: #009688;
85
85
  --chart-series-4: #bc4ad0;
86
86
  --chart-series-5: #379c3d;
87
- --colors-accent-mark: #ff9640;
88
- --text-on-accent-mark: #000000;
87
+ --colors-accent-mark: #006bb5;
88
+ --text-on-accent-mark: #ffffff;
89
89
  --type-font-mono: "Roboto Mono", monospace;
90
90
  --surface-scrim: #00000080;
91
91
  --shadow-ambient: #0000000d;
@@ -103,16 +103,20 @@
103
103
  --colors-state-info-strong: #2196f3;
104
104
  --colors-state-neutral-strong: #52525b;
105
105
  --text-on-primary-subtle: #ffffff4d;
106
- --surface-tint-subtle: #ffe2c6;
106
+ --surface-tint-subtle: #f4f6f9;
107
+ --rojao-primary: #1b2a4a;
108
+ --rojao-secondary: #1b2a4a;
109
+ --rojao-accent: #ff6a00;
110
+ --rojao-invert: #ffffff;
107
111
  }
108
112
 
109
- :root.dark, .dark, .ds-scope.dark, .dark .ds-scope {
113
+ :root.dark, .dark, :root[data-rds-mode="dark"], [data-rds-mode="dark"], .ds-scope.dark, .dark .ds-scope, .ds-scope[data-rds-mode="dark"], [data-rds-mode="dark"] .ds-scope, [data-rds-scope].dark, .dark [data-rds-scope], [data-rds-scope][data-rds-mode="dark"], [data-rds-mode="dark"] [data-rds-scope] {
110
114
  --colors-primary-light: #8a91a1;
111
115
  --colors-primary-default: #c9cdd8;
112
116
  --colors-primary-dark: #e4e6ec;
113
- --colors-secondary-default: #8a91a1;
114
- --colors-secondary-active: #c9cdd8;
115
- --colors-accent-highlight: #d95a00;
117
+ --colors-secondary-default: #8cc6ff;
118
+ --colors-secondary-active: #44a7ff;
119
+ --colors-accent-highlight: #3a465f;
116
120
  --colors-accent-default: #ffb066;
117
121
  --colors-accent-hover: #ffca96;
118
122
  --text-heading: #fafafa;
@@ -122,13 +126,14 @@
122
126
  --surface-card: #18181b;
123
127
  --surface-panel: #18181b;
124
128
  --border-default: #27272a;
125
- --surface-tint-default: #b34b00;
129
+ --surface-tint-default: #003966;
126
130
  --text-on-action-tonal: #c9cdd8;
127
- --text-on-primary: #000000;
128
- --text-on-secondary: #000000;
131
+ --text-on-primary: #1b2a4a;
132
+ --text-on-secondary: #1b2a4a;
133
+ --text-on-accent: #000000;
129
134
  --text-on-tint: #ffffff;
130
135
  --colors-state-error-strong: #ff6c5c;
131
- --surface-tint-strong: #d95a00;
136
+ --surface-tint-strong: #00518d;
132
137
  --surface-action-default: #002445;
133
138
  --surface-action-strong: #003966;
134
139
  --focus-ring: #f4f4f5;
@@ -142,7 +147,7 @@
142
147
  --text-on-lift-action: #ffffff;
143
148
  --surface-lift-action-strong: #3a465f;
144
149
  --text-on-primary-strong: #000000;
145
- --colors-secondary-hover: #aeb6c4;
150
+ --colors-secondary-hover: #bddeff;
146
151
  --colors-state-success-strong: #82d982;
147
152
  --text-subtle: #a1a1aa;
148
153
  --surface-muted: #27272a;
@@ -166,7 +171,8 @@
166
171
  --chart-series-3: #45b7a8;
167
172
  --chart-series-4: #db6def;
168
173
  --chart-series-5: #4caf50;
169
- --colors-accent-mark: #ffb066;
174
+ --colors-accent-mark: #8cc6ff;
175
+ --text-on-accent-mark: #000000;
170
176
  --surface-scrim: #000000b3;
171
177
  --shadow-ambient: #00000033;
172
178
  --shadow-key: #00000066;
@@ -179,30 +185,31 @@
179
185
  --colors-state-info-strong: #8cc6ff;
180
186
  --colors-state-neutral-strong: #a1a1aa;
181
187
  --text-on-primary-subtle: #0000004d;
182
- --surface-tint-subtle: #b34b00;
188
+ --surface-tint-subtle: #002445;
183
189
  }
184
190
 
185
- .ds-plate {
191
+ .ds-plate, [data-rds-plate] {
186
192
  --colors-primary-light: #aeb6c4;
187
193
  --colors-primary-default: #ffffff;
188
194
  --colors-primary-dark: #e4e6ec;
189
195
  --colors-secondary-light: #aeb6c4;
190
196
  --colors-secondary-default: #ffffff;
191
197
  --colors-secondary-active: #c9cdd8;
192
- --colors-accent-highlight: #d95a00;
198
+ --colors-accent-highlight: #3a465f;
193
199
  --colors-accent-default: #ffb066;
194
200
  --colors-accent-hover: #ffca96;
195
201
  --text-heading: #ffffff;
196
202
  --text-body: #ffffff;
197
203
  --text-link: #ffffff;
198
204
  --surface-page: #1b2a4a;
199
- --surface-card: #6b7488;
205
+ --surface-card: #26344f;
200
206
  --surface-panel: #1b2a4a;
201
207
  --border-default: #ffffff33;
202
208
  --surface-tint-default: #ffffff1a;
203
209
  --text-on-action-tonal: #ffffff;
204
210
  --text-on-primary: #1b2a4a;
205
211
  --text-on-secondary: #1b2a4a;
212
+ --text-on-accent: #000000;
206
213
  --text-on-tint: #ffffff;
207
214
  --colors-state-error-strong: #ff6c5c;
208
215
  --surface-tint-strong: #ffffff33;
@@ -244,7 +251,8 @@
244
251
  --chart-series-3: #45b7a8;
245
252
  --chart-series-4: #db6def;
246
253
  --chart-series-5: #4caf50;
247
- --colors-accent-mark: #ffb066;
254
+ --colors-accent-mark: #8cc6ff;
255
+ --text-on-accent-mark: #000000;
248
256
  --surface-scrim: #000000b3;
249
257
  --shadow-ambient: #00000033;
250
258
  --shadow-key: #00000066;
package/styles/rds.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /* GENERATED by scripts/build-rds-tokens.ts. Import once: @import "@rojaostudio/ds/styles/rds.css". */
2
- @layer rds.theme, rds.tokens, rds.components;
2
+ @layer rds.legacy, rds.theme, rds.tokens, rds.components;
3
3
  @import "./rds/theme.css";
4
4
  @import "./rds/foundation.css";
5
5
  @import "./rds/components.css";