@rojaostudio/ds 2.0.0-next.14 → 2.0.0-next.16

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.
@@ -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.14",
3
+ "version": "2.0.0-next.16",
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.7"
193
+ "@rojaostudio/ds-core": "1.1.0-next.8"
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",
@@ -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
  }
@@ -2672,10 +2677,10 @@ input:focus-visible + .rds-checkbox__box {
2672
2677
  * an 8 dot. Selected fills the card with the brand. Disabled is the same card at half opacity (as in Figma).
2673
2678
  * tile: a grid cell, 16 inside, centred: the icon, then the label 14/20 semibold and the description 12/16 (8 below
2674
2679
  * the icon). Selected fills it with the brand, the icon square at 10% of choice-card/icon/background/selected, the
2675
- * description at 70%, and a 16 check (11 glyph) 8 from the top right corner.
2680
+ * description at full opacity, and a 16 check (11 glyph) 8 from the top right corner.
2676
2681
  * preview: 8 inside, the picture on top (16:9, a 1px border, corners radius/container, a 24 placeholder icon), then
2677
2682
  * the label 16/24 semibold and the description 14/20, 4 in from the sides. Selected keeps the surface: a 2px border
2678
- * in the brand, the description at 70% and a 20 check (12 glyph) in the picture's bottom right corner.
2683
+ * in the brand, the description at full opacity and a 20 check (12 glyph) in the picture's bottom right corner.
2679
2684
  * The group stacks rows 8 apart; tiles and previews go in a grid (cells of at least 160 and 240), 8 apart.
2680
2685
  */
2681
2686
  .rds-choice-card-group {
@@ -2867,11 +2872,6 @@ input:focus-visible + .rds-checkbox__box {
2867
2872
  color: var(--choice-card-icon-color-selected);
2868
2873
  }
2869
2874
 
2870
- .rds-choice-card--tile.rds-choice-card--selected .rds-choice-card__description,
2871
- .rds-choice-card--preview.rds-choice-card--selected .rds-choice-card__description {
2872
- color: color-mix(in srgb, var(--_description) 70%, transparent);
2873
- }
2874
-
2875
2875
  .rds-choice-card--tile .rds-choice-card__check {
2876
2876
  position: absolute;
2877
2877
  top: calc(var(--space-8) - var(--border-width));
@@ -3229,7 +3229,7 @@ input:focus-visible + .rds-checkbox__box {
3229
3229
  .rds-color-input__swatch:focus-visible,
3230
3230
  .rds-color-input__swatch:has(.rds-color-input__native:focus-visible) {
3231
3231
  outline: var(--focus-ring-width) solid var(--_border-focus);
3232
- outline-offset: var(--border-width);
3232
+ outline-offset: var(--focus-ring-width);
3233
3233
  }
3234
3234
 
3235
3235
  .rds-color-input__native {
@@ -3296,14 +3296,15 @@ input:focus-visible + .rds-checkbox__box {
3296
3296
  cursor: pointer;
3297
3297
  }
3298
3298
 
3299
+ /* Selected and focus: the ring of Button and Checkbox, focus-ring-width wide and as far off the swatch (a gap). */
3299
3300
  .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);
3301
+ outline: var(--focus-ring-width) solid var(--color-input-swatch-selected);
3302
+ outline-offset: var(--focus-ring-width);
3302
3303
  }
3303
3304
 
3304
3305
  .rds-color-input__choice:focus-visible {
3305
3306
  outline: var(--focus-ring-width) solid var(--color-input-border-focus);
3306
- outline-offset: var(--border-width);
3307
+ outline-offset: var(--focus-ring-width);
3307
3308
  }
3308
3309
 
3309
3310
  @media (forced-colors: active) {
@@ -3578,23 +3579,29 @@ input:focus-visible + .rds-checkbox__box {
3578
3579
  /* components/data-table-header.css */
3579
3580
  /* @tokens data-table-header */
3580
3581
  /*
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.
3582
+ * DataTableHeader: no tokens of its own; the Input, FilterChip, Chip, Button, Separator, Checkbox, DropdownMenu,
3583
+ * Popover and Drawer bring theirs. One row, 8 apart, 12 above the table, packed to the right: the search on the left
3584
+ * takes the free width, at least 320 (never wider than the bar); the quick filters, the filters, the view control
3585
+ * and the actions follow it on the right, and what does not fit wraps. The wide parts show from 768, the narrow ones
3586
+ * below it. In the Popover and the Drawer the filters stack 16 apart, each one a caption-sized label over its chips.
3585
3587
  */
3586
3588
  .rds-data-table-header {
3587
3589
  display: flex;
3588
3590
  flex-wrap: wrap;
3589
3591
  align-items: center;
3592
+ justify-content: flex-end;
3590
3593
  gap: var(--space-8);
3591
3594
  margin-bottom: var(--space-12);
3592
3595
  }
3593
3596
 
3594
- .rds-data-table-header__search {
3595
- flex: 1 1 calc(var(--space-64) * 4);
3597
+ /* Scoped to the bar: the field's own `min-width: 0` (internal/field.css) comes later in the bundle. */
3598
+ .rds-data-table-header .rds-data-table-header__search {
3599
+ flex: 1 1 calc(var(--space-64) * 5);
3600
+ min-width: min(calc(var(--space-64) * 5), 100%);
3596
3601
  }
3597
3602
 
3603
+ .rds-data-table-header__quick,
3604
+ .rds-data-table-header__view,
3598
3605
  .rds-data-table-header__wide,
3599
3606
  .rds-data-table-header__actions,
3600
3607
  .rds-data-table-header__narrow {
@@ -4289,7 +4296,7 @@ input:focus-visible + .rds-checkbox__box {
4289
4296
  * FilterChip (Forms collection, filter-chip/*): 32 tall, pill, 12 inside, 4 between icon, label and count;
4290
4297
  * label 14/20 medium. inactive: card fill and a hairline; hover: muted fill, strong hairline; active: the brand
4291
4298
  * at 12% over what is behind, brand border and label; disabled: the whole chip at 50%, the label at 40%.
4292
- * The count reads at 60% of the label. Icon 14, in the label's colour.
4299
+ * The count reads in the label's colour, at full opacity. Icon 14, in the label's colour.
4293
4300
  */
4294
4301
  .rds-filter-chip-group {
4295
4302
  display: flex;
@@ -4380,7 +4387,6 @@ input:focus-visible + .rds-checkbox__box {
4380
4387
  }
4381
4388
 
4382
4389
  .rds-filter-chip__count {
4383
- color: color-mix(in srgb, currentColor 60%, transparent);
4384
4390
  font-variant-numeric: tabular-nums;
4385
4391
  }
4386
4392
 
@@ -7347,7 +7353,7 @@ body:has(.rds-modal) {
7347
7353
  /*
7348
7354
  * PageSkeleton and CardsSkeleton: no tokens of their own; the Skeleton and the Card bring theirs. Blocks 24 apart
7349
7355
  * (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
7356
+ * 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
7357
  * 1 (2 from 1024), 16 apart.
7352
7358
  */
7353
7359
  .rds-page-skeleton {
@@ -7379,7 +7385,7 @@ body:has(.rds-modal) {
7379
7385
  }
7380
7386
 
7381
7387
  .rds-page-skeleton__row--head {
7382
- background: var(--card-footer-background);
7388
+ background: var(--table-header-background);
7383
7389
  }
7384
7390
 
7385
7391
  .rds-page-skeleton__row .rds-skeleton {
@@ -8376,15 +8382,15 @@ input:focus-visible + .rds-radio__circle {
8376
8382
  /* @tokens savingbar */
8377
8383
  /*
8378
8384
  * 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
8385
+ * message (label, medium, at most 2 lines with an ellipsis) and the actions (8 apart). The Buttons use the inverse
8380
8386
  * tone, drawn for this band in both modes, so the bar needs no theme switch of its own.
8387
+ * Two arrangements, by the bar's own width (a size container, as the Figma's viewport mode): expanded from 1024,
8388
+ * the message grows (at least 160) beside the actions; compact below it, the message on top and Descartar and
8389
+ * Salvar under it, sharing the width.
8381
8390
  */
8382
8391
  .rds-savingbar {
8383
8392
  box-sizing: border-box;
8384
- display: flex;
8385
- flex-wrap: wrap;
8386
- align-items: center;
8387
- gap: var(--space-16);
8393
+ container-type: inline-size;
8388
8394
  width: 100%;
8389
8395
  min-width: min(320px, 100%);
8390
8396
  padding: var(--space-12) var(--space-24);
@@ -8393,18 +8399,34 @@ input:focus-visible + .rds-radio__circle {
8393
8399
  font-family: var(--type-font-stack);
8394
8400
  }
8395
8401
 
8402
+ .rds-savingbar__row {
8403
+ display: flex;
8404
+ align-items: center;
8405
+ gap: var(--space-16);
8406
+ }
8407
+
8396
8408
  .rds-savingbar__message {
8397
8409
  display: flex;
8398
- flex: 1;
8410
+ flex: 1 1 160px;
8399
8411
  align-items: center;
8400
8412
  gap: var(--space-12);
8401
- min-width: 0;
8413
+ min-width: 160px;
8402
8414
  margin: 0;
8403
8415
  font-size: var(--type-label-size);
8404
8416
  font-weight: 500;
8405
8417
  line-height: var(--type-label-line);
8406
8418
  }
8407
8419
 
8420
+ .rds-savingbar__text {
8421
+ display: -webkit-box;
8422
+ flex: 1;
8423
+ min-width: 0;
8424
+ overflow: hidden;
8425
+ -webkit-box-orient: vertical;
8426
+ -webkit-line-clamp: 2;
8427
+ line-clamp: 2;
8428
+ }
8429
+
8408
8430
  .rds-savingbar__icon {
8409
8431
  display: inline-flex;
8410
8432
  flex: none;
@@ -8435,10 +8457,27 @@ input:focus-visible + .rds-radio__circle {
8435
8457
 
8436
8458
  .rds-savingbar__actions {
8437
8459
  display: flex;
8438
- flex-wrap: wrap;
8460
+ flex: none;
8439
8461
  gap: var(--space-8);
8440
8462
  }
8441
8463
 
8464
+ @container (max-width: 1023px) {
8465
+ .rds-savingbar__row {
8466
+ flex-direction: column;
8467
+ align-items: stretch;
8468
+ }
8469
+
8470
+ .rds-savingbar__message {
8471
+ flex: none;
8472
+ min-width: 0;
8473
+ }
8474
+
8475
+ .rds-savingbar__actions > * {
8476
+ flex: 1 1 0;
8477
+ min-width: 0;
8478
+ }
8479
+ }
8480
+
8442
8481
  @media (forced-colors: active) {
8443
8482
  .rds-savingbar {
8444
8483
  border-top: var(--border-width) solid CanvasText;
@@ -8806,7 +8845,9 @@ input:focus-visible + .rds-radio__circle {
8806
8845
  /*
8807
8846
  * Sidebar (Navigation collection, sidebar/*): 240 wide (64 collapsed), 12 × 8 inside, a 1px border on the right.
8808
8847
  * 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.
8848
+ * icon (20) and label (14/20 medium), 4 apart; the current one on the brand tint, its label semibold in
8849
+ * sidebar/item/label/active and a 3 × 20 marker on the left in sidebar/item/indicator, so the current entry does not
8850
+ * rest on colour alone.
8810
8851
  * Section labels 11/14 bold, 16 above and 6 below, with a 14 chevron. Foot: who is signed in (12/16) and Sair.
8811
8852
  * dark (deprecated in the Figma) reads sidebar/dark/*; the current entry stays the light pill.
8812
8853
  */
@@ -8911,6 +8952,7 @@ input:focus-visible + .rds-radio__circle {
8911
8952
  }
8912
8953
 
8913
8954
  .rds-sidebar__item {
8955
+ position: relative;
8914
8956
  box-sizing: border-box;
8915
8957
  display: flex;
8916
8958
  align-items: center;
@@ -8970,8 +9012,21 @@ input:focus-visible + .rds-radio__circle {
8970
9012
  color: var(--sidebar-item-label-active);
8971
9013
  }
8972
9014
 
8973
- .rds-sidebar__item[aria-current='page'] .rds-sidebar__count {
8974
- color: var(--sidebar-item-label-active);
9015
+ .rds-sidebar__item[aria-current='page'] .rds-sidebar__label {
9016
+ font-weight: 600;
9017
+ }
9018
+
9019
+ /* Figma .sidebar/item state=active: the marker, 3 × 20, on the left edge, vertically centred, radius 2. */
9020
+ .rds-sidebar__item[aria-current='page']::before {
9021
+ content: '';
9022
+ position: absolute;
9023
+ inset-inline-start: 0;
9024
+ top: 50%;
9025
+ width: 3px;
9026
+ height: var(--size-20);
9027
+ border-radius: 2px;
9028
+ background: var(--sidebar-item-indicator);
9029
+ transform: translateY(-50%);
8975
9030
  }
8976
9031
 
8977
9032
  .rds-sidebar__item:focus-visible,
@@ -9040,6 +9095,10 @@ input:focus-visible + .rds-radio__circle {
9040
9095
  .rds-sidebar__item[aria-current='page'] {
9041
9096
  outline: var(--border-width) solid CanvasText;
9042
9097
  }
9098
+
9099
+ .rds-sidebar__item[aria-current='page']::before {
9100
+ background: Highlight;
9101
+ }
9043
9102
  }
9044
9103
 
9045
9104
  /* components/skeleton.css */
@@ -183,7 +183,7 @@
183
183
  /* chat */
184
184
  --attachment-background: var(--surface-card);
185
185
  --attachment-border: var(--border-default);
186
- --attachment-border-error: var(--colors-state-error);
186
+ --attachment-border-error: var(--border-error);
187
187
  --attachment-description: var(--text-muted);
188
188
  --attachment-error: var(--text-error);
189
189
  --attachment-media: var(--surface-muted);
@@ -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;
@@ -550,7 +551,7 @@
550
551
  --input-border-default: var(--border-strong);
551
552
  --input-border-hover: var(--border-strong-hover);
552
553
  --input-border-focus: var(--focus-ring);
553
- --input-border-error: var(--colors-state-error);
554
+ --input-border-error: var(--border-error);
554
555
  --input-border-disabled: var(--border-default);
555
556
  --input-value-default: var(--text-body);
556
557
  --input-value-disabled: var(--text-disabled);
@@ -579,7 +580,7 @@
579
580
  --textarea-border-default: var(--border-strong);
580
581
  --textarea-border-hover: var(--border-strong-hover);
581
582
  --textarea-border-focus: var(--focus-ring);
582
- --textarea-border-error: var(--colors-state-error);
583
+ --textarea-border-error: var(--border-error);
583
584
  --textarea-border-disabled: var(--border-default);
584
585
  --textarea-value-default: var(--text-body);
585
586
  --textarea-value-disabled: var(--text-disabled);
@@ -600,7 +601,7 @@
600
601
  --select-border-default: var(--border-strong);
601
602
  --select-border-hover: var(--border-strong-hover);
602
603
  --select-border-focus: var(--focus-ring);
603
- --select-border-error: var(--colors-state-error);
604
+ --select-border-error: var(--border-error);
604
605
  --select-border-disabled: var(--border-default);
605
606
  --select-value-default: var(--text-body);
606
607
  --select-value-disabled: var(--text-disabled);
@@ -628,7 +629,7 @@
628
629
  --checkbox-control-background-checked-disabled: var(--text-disabled);
629
630
  --checkbox-control-border-default: var(--border-strong);
630
631
  --checkbox-control-border-hover: var(--border-strong-hover);
631
- --checkbox-control-border-error: var(--colors-state-error);
632
+ --checkbox-control-border-error: var(--border-error);
632
633
  --checkbox-control-border-disabled: var(--border-default);
633
634
  --checkbox-control-mark: var(--text-on-secondary);
634
635
  --checkbox-control-mark-disabled: var(--surface-card);
@@ -649,7 +650,7 @@
649
650
  --radio-control-background-checked-disabled: var(--text-disabled);
650
651
  --radio-control-border-default: var(--border-strong);
651
652
  --radio-control-border-hover: var(--border-strong-hover);
652
- --radio-control-border-error: var(--colors-state-error);
653
+ --radio-control-border-error: var(--border-error);
653
654
  --radio-control-border-disabled: var(--border-default);
654
655
  --radio-control-dot: var(--text-on-secondary);
655
656
  --radio-control-dot-disabled: var(--surface-card);
@@ -716,7 +717,7 @@
716
717
  --otp-slot-background-disabled: var(--surface-disabled);
717
718
  --otp-slot-border-default: var(--border-strong);
718
719
  --otp-slot-border-active: var(--focus-ring);
719
- --otp-slot-border-error: var(--colors-state-error);
720
+ --otp-slot-border-error: var(--border-error);
720
721
  --otp-slot-border-disabled: var(--border-default);
721
722
  --combobox-empty: var(--text-muted);
722
723
  --calendar-background: var(--surface-card);
@@ -748,7 +749,7 @@
748
749
  --file-input-area-border-default: var(--border-strong);
749
750
  --file-input-area-border-hover: var(--focus-ring);
750
751
  --file-input-area-border-focus: var(--focus-ring);
751
- --file-input-area-border-error: var(--colors-state-error);
752
+ --file-input-area-border-error: var(--border-error);
752
753
  --file-input-area-border-disabled: var(--border-default);
753
754
  --file-input-area-icon-default: var(--colors-primary-default);
754
755
  --file-input-area-icon-disabled: var(--text-disabled);
@@ -771,7 +772,7 @@
771
772
  --chip-input-border-default: var(--border-strong);
772
773
  --chip-input-border-hover: var(--border-strong-hover);
773
774
  --chip-input-border-focus: var(--focus-ring);
774
- --chip-input-border-error: var(--colors-state-error);
775
+ --chip-input-border-error: var(--border-error);
775
776
  --chip-input-border-disabled: var(--border-default);
776
777
  --chip-input-value-default: var(--text-body);
777
778
  --chip-input-value-disabled: var(--text-disabled);
@@ -790,7 +791,7 @@
790
791
  --number-input-border-default: var(--border-strong);
791
792
  --number-input-border-hover: var(--border-strong-hover);
792
793
  --number-input-border-focus: var(--focus-ring);
793
- --number-input-border-error: var(--colors-state-error);
794
+ --number-input-border-error: var(--border-error);
794
795
  --number-input-border-disabled: var(--border-default);
795
796
  --number-input-value-default: var(--text-body);
796
797
  --number-input-value-disabled: var(--text-disabled);
@@ -811,7 +812,7 @@
811
812
  --color-input-border-default: var(--border-strong);
812
813
  --color-input-border-hover: var(--border-strong-hover);
813
814
  --color-input-border-focus: var(--focus-ring);
814
- --color-input-border-error: var(--colors-state-error);
815
+ --color-input-border-error: var(--border-error);
815
816
  --color-input-border-disabled: var(--border-default);
816
817
  --color-input-value-default: var(--text-body);
817
818
  --color-input-value-disabled: var(--text-disabled);
@@ -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);
@@ -972,11 +973,12 @@
972
973
  --navmenu-trigger-background-open: var(--surface-muted);
973
974
  --navmenu-trigger-label: var(--text-body);
974
975
  --tabs-soon-background: var(--surface-muted);
975
- --tabs-soon-text: var(--text-disabled);
976
+ --tabs-soon-text: var(--text-subtle);
976
977
  --tabs-dot-background: var(--colors-state-success);
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);
@@ -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: #ffffff;
68
+ --text-on-info: #000000;
69
69
  --colors-state-warning: #ff9800;
70
70
  --colors-state-warning-strong: #dc7f00;
71
71
  --text-on-warning: #000000;
@@ -80,7 +80,7 @@
80
80
  --surface-neutral: #f4f4f5;
81
81
  --text-neutral: #27272a;
82
82
  --chart-series-1: #5a6478;
83
- --chart-series-2: #dc7f00;
83
+ --chart-series-2: #bd6a00;
84
84
  --chart-series-3: #009688;
85
85
  --chart-series-4: #bc4ad0;
86
86
  --chart-series-5: #379c3d;
@@ -104,6 +104,7 @@
104
104
  --colors-state-neutral-strong: #52525b;
105
105
  --text-on-primary-subtle: #ffffff4d;
106
106
  --surface-tint-subtle: #f4f6f9;
107
+ --border-error: #c50003;
107
108
  --rojao-primary: #1b2a4a;
108
109
  --rojao-secondary: #1b2a4a;
109
110
  --rojao-accent: #ff6a00;
@@ -186,6 +187,7 @@
186
187
  --colors-state-neutral-strong: #a1a1aa;
187
188
  --text-on-primary-subtle: #0000004d;
188
189
  --surface-tint-subtle: #002445;
190
+ --border-error: #ff6c5c;
189
191
  }
190
192
 
191
193
  .ds-plate, [data-rds-plate] {
@@ -265,5 +267,6 @@
265
267
  --colors-state-info-strong: #8cc6ff;
266
268
  --colors-state-neutral-strong: #a1a1aa;
267
269
  --surface-tint-subtle: #ffffff0d;
270
+ --border-error: #ffa598;
268
271
  }
269
272
  }