@teamblind-chorus/ui 1.2.0 → 2.0.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 (141) hide show
  1. package/README.md +3 -3
  2. package/agents/AGENTS.md +6 -6
  3. package/agents/DESIGN.md +245 -244
  4. package/agents/LOVABLE.md +40 -11
  5. package/agents/catalog.md +4 -4
  6. package/agents/components/avatar-rail/avatar-rail.md +2 -4
  7. package/agents/components/avatar-rail/avatar-rail.spec.json +10 -14
  8. package/agents/components/badge/role.md +7 -9
  9. package/agents/components/badge/role.spec.json +6 -6
  10. package/agents/components/badge/update.md +6 -8
  11. package/agents/components/badge/update.spec.json +5 -5
  12. package/agents/components/banner/banner.md +16 -18
  13. package/agents/components/banner/banner.spec.json +14 -14
  14. package/agents/components/bottom-sheet/bottom-sheet.md +4 -6
  15. package/agents/components/bottom-sheet/bottom-sheet.spec.json +5 -5
  16. package/agents/components/bubble/bubble.md +8 -10
  17. package/agents/components/bubble/bubble.spec.json +11 -11
  18. package/agents/components/button/button.md +1 -1
  19. package/agents/components/button/check.md +9 -11
  20. package/agents/components/button/check.spec.json +8 -10
  21. package/agents/components/button/fab.md +7 -9
  22. package/agents/components/button/fab.spec.json +10 -12
  23. package/agents/components/button/group.spec.json +4 -4
  24. package/agents/components/button/icon.md +21 -23
  25. package/agents/components/button/icon.spec.json +12 -14
  26. package/agents/components/button/standard.md +40 -42
  27. package/agents/components/button/standard.spec.json +20 -22
  28. package/agents/components/button/text.md +21 -23
  29. package/agents/components/button/text.spec.json +13 -15
  30. package/agents/components/button/toggle.md +7 -9
  31. package/agents/components/button/toggle.spec.json +10 -12
  32. package/agents/components/button/toolbar.md +24 -26
  33. package/agents/components/button/toolbar.spec.json +10 -12
  34. package/agents/components/carousel/carousel.md +1 -1
  35. package/agents/components/carousel/post.md +15 -21
  36. package/agents/components/carousel/post.spec.json +17 -17
  37. package/agents/components/carousel/profile.md +9 -45
  38. package/agents/components/carousel/profile.spec.json +17 -17
  39. package/agents/components/chip/chip.md +1 -1
  40. package/agents/components/chip/filter.md +22 -24
  41. package/agents/components/chip/filter.spec.json +17 -13
  42. package/agents/components/chip/tag.md +22 -24
  43. package/agents/components/chip/tag.spec.json +19 -15
  44. package/agents/components/dialog/dialog.md +1 -3
  45. package/agents/components/dialog/dialog.spec.json +3 -3
  46. package/agents/components/directory-list/directory-list.md +1 -3
  47. package/agents/components/directory-list/directory-list.spec.json +2 -2
  48. package/agents/components/divider/divider.family.json +1 -1
  49. package/agents/components/divider/divider.md +12 -14
  50. package/agents/components/divider/divider.spec.json +8 -8
  51. package/agents/components/empty-state/empty-state.md +9 -9
  52. package/agents/components/empty-state/empty-state.spec.json +14 -14
  53. package/agents/components/feed/ad.md +2 -4
  54. package/agents/components/feed/ad.spec.json +10 -10
  55. package/agents/components/feed/post.md +41 -43
  56. package/agents/components/feed/post.spec.json +35 -39
  57. package/agents/components/form-field/form-field.md +1 -1
  58. package/agents/components/form-field/input.md +32 -34
  59. package/agents/components/form-field/input.spec.json +34 -33
  60. package/agents/components/form-field/search.md +2 -4
  61. package/agents/components/form-field/search.spec.json +19 -18
  62. package/agents/components/form-field/select.md +18 -20
  63. package/agents/components/form-field/select.spec.json +30 -29
  64. package/agents/components/form-field/textarea.md +3 -5
  65. package/agents/components/form-field/textarea.spec.json +32 -31
  66. package/agents/components/header/main.md +4 -6
  67. package/agents/components/header/main.spec.json +3 -3
  68. package/agents/components/header/sub.md +6 -8
  69. package/agents/components/header/sub.spec.json +3 -3
  70. package/agents/components/list/accordion.md +34 -45
  71. package/agents/components/list/accordion.spec.json +20 -20
  72. package/agents/components/list/entry.md +59 -81
  73. package/agents/components/list/entry.spec.json +20 -23
  74. package/agents/components/list/list.md +2 -2
  75. package/agents/components/list/radio.md +13 -20
  76. package/agents/components/list/radio.spec.json +16 -20
  77. package/agents/components/list/standard.md +50 -72
  78. package/agents/components/list/standard.spec.json +18 -21
  79. package/agents/components/metadata/compact.md +4 -6
  80. package/agents/components/metadata/compact.spec.json +6 -6
  81. package/agents/components/metadata/metadata.md +1 -1
  82. package/agents/components/metadata/standard.md +12 -14
  83. package/agents/components/metadata/standard.spec.json +10 -10
  84. package/agents/components/nav-card/nav-card.md +25 -27
  85. package/agents/components/nav-card/nav-card.spec.json +19 -19
  86. package/agents/components/nav-list/nav-list.md +2 -8
  87. package/agents/components/nav-list/nav-list.spec.json +3 -3
  88. package/agents/components/navigation-bar/main.md +9 -11
  89. package/agents/components/navigation-bar/main.spec.json +6 -6
  90. package/agents/components/navigation-bar/search.md +6 -8
  91. package/agents/components/navigation-bar/search.spec.json +9 -9
  92. package/agents/components/navigation-bar/sub.md +9 -11
  93. package/agents/components/navigation-bar/sub.spec.json +7 -7
  94. package/agents/components/pagination/pagination.family.json +1 -1
  95. package/agents/components/pagination/pagination.md +3 -3
  96. package/agents/components/pagination/pagination.spec.json +5 -5
  97. package/agents/components/profile-header/profile-header.md +9 -11
  98. package/agents/components/profile-header/profile-header.spec.json +9 -9
  99. package/agents/components/progress/progress.family.json +1 -1
  100. package/agents/components/progress/progress.md +5 -5
  101. package/agents/components/progress/progress.spec.json +8 -8
  102. package/agents/components/side-sheet/side-sheet.md +11 -13
  103. package/agents/components/side-sheet/side-sheet.spec.json +3 -3
  104. package/agents/components/skeleton/skeleton.md +7 -9
  105. package/agents/components/skeleton/skeleton.spec.json +5 -5
  106. package/agents/components/spinner/spinner.family.json +1 -1
  107. package/agents/components/spinner/spinner.md +8 -10
  108. package/agents/components/spinner/spinner.spec.json +9 -9
  109. package/agents/components/status-tag/status-tag.md +7 -9
  110. package/agents/components/status-tag/status-tag.spec.json +5 -5
  111. package/agents/components/suggestion-list/suggestion-list.md +3 -7
  112. package/agents/components/suggestion-list/suggestion-list.spec.json +8 -12
  113. package/agents/components/switch/switch.md +12 -14
  114. package/agents/components/switch/switch.spec.json +17 -18
  115. package/agents/components/tab-bar/tab-bar.md +9 -11
  116. package/agents/components/tab-bar/tab-bar.spec.json +25 -27
  117. package/agents/components/tabs/rounded.md +6 -8
  118. package/agents/components/tabs/rounded.spec.json +17 -15
  119. package/agents/components/tabs/segmented.md +4 -6
  120. package/agents/components/tabs/segmented.spec.json +4 -8
  121. package/agents/components/tabs/underline.md +9 -11
  122. package/agents/components/tabs/underline.spec.json +14 -16
  123. package/agents/components/thumbnail/thumbnail.md +5 -7
  124. package/agents/components/thumbnail/thumbnail.spec.json +8 -8
  125. package/agents/components/toast/toast.md +5 -7
  126. package/agents/components/toast/toast.spec.json +3 -3
  127. package/agents/components/tooltip/tooltip.md +6 -8
  128. package/agents/components/tooltip/tooltip.spec.json +4 -4
  129. package/agents/tokens.usage.json +71 -226
  130. package/dist/index.cjs +212 -223
  131. package/dist/index.cjs.map +1 -1
  132. package/dist/index.d.cts +16 -16
  133. package/dist/index.d.ts +16 -16
  134. package/dist/index.js +212 -223
  135. package/dist/index.js.map +1 -1
  136. package/dist/styles.css +386 -387
  137. package/eslint/rules.js +7 -7
  138. package/package.json +2 -3
  139. package/agents/anti-patterns.md +0 -533
  140. package/agents/compose.md +0 -240
  141. package/agents/images.md +0 -66
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "card": {
28
28
  "required": true,
29
- "description": "One profile card per page. **Width is fixed at 176px** — every card paints the same footprint regardless of how many entries the rail carries. Vertical stack: cover band → avatar (overlapping) → name → followers → metrics row → follow toggle. `sys.color.surface` fill, `sys.radius.md` corner, `sys.borderWidth.hairline sys.color.outlineVariant` inset outline. `scroll-snap-align: start`.",
29
+ "description": "One profile card per page. **Width is fixed at 176px** — every card paints the same footprint regardless of how many entries the rail carries. Vertical stack: cover band → avatar (overlapping) → name → followers → metrics row → follow toggle. `sys.color.surface.default` fill, `sys.radius.md` corner, `sys.borderWidth.hairline sys.color.border.default` inset outline. `scroll-snap-align: start`.",
30
30
  "intrinsic": true
31
31
  },
32
32
  "cover": {
@@ -46,33 +46,33 @@
46
46
  },
47
47
  "name": {
48
48
  "required": true,
49
- "description": "Entity name (channel / profile / company). `sys.typo.label.md` / Semibold / `sys.color.onSurface`. Centered; single line, truncates with ellipsis.",
49
+ "description": "Entity name (channel / profile / company). `sys.typo.label.md` / Semibold / `sys.color.text.default`. Centered; single line, truncates with ellipsis.",
50
50
  "accepts": [
51
51
  "text"
52
52
  ]
53
53
  },
54
54
  "followers": {
55
55
  "required": true,
56
- "description": "Follower count line. `sys.typo.label.sm` / Semibold / `sys.color.onSurfaceVariant`. Centered; single line.",
56
+ "description": "Follower count line. `sys.typo.label.sm` / Semibold / `sys.color.text.subtle`. Centered; single line.",
57
57
  "accepts": [
58
58
  "text"
59
59
  ]
60
60
  },
61
61
  "metrics": {
62
62
  "required": false,
63
- "description": "Row of metric chips below the name / followers stack. Each chip is `icon + value` painted in `sys.typo.label.sm` / `sys.color.onSurface`. Three default kinds: { icon: 'star', … } → `StarFillIcon` in `sys.color.icon.yellow`; { icon: 'pulse', … } → `PulseFillIcon` in `sys.color.success`; { icon: 'heart', … } → `HeartFillIcon` in `sys.color.icon.red`. Consumers may pass custom { icon: <ReactNode>, value, color? } entries for other shapes. Mutually exclusive with `description` — when both are present `description` wins.",
63
+ "description": "Row of metric chips below the name / followers stack. Each chip is `icon + value` painted in `sys.typo.label.sm` / `sys.color.text.default`. Three default kinds: { icon: 'star', … } → `StarFillIcon` in `sys.color.icon.accent.yellow.default`; { icon: 'pulse', … } → `PulseFillIcon` in `sys.color.text.success`; { icon: 'heart', … } → `HeartFillIcon` in `sys.color.icon.accent.red.default`. Consumers may pass custom { icon: <ReactNode>, value, color? } entries for other shapes. Mutually exclusive with `description` — when both are present `description` wins.",
64
64
  "intrinsic": true
65
65
  },
66
66
  "description": {
67
67
  "required": false,
68
- "description": "Two-line clamped descriptive paragraph that replaces the metrics row when present. `sys.typo.label.sm` / `sys.color.onSurfaceVariant`, centered. The slot reserves a fixed height of two `label.sm` lines so card height stays consistent across cards that carry metrics and cards that carry copy — extra content clamps with a trailing ellipsis.",
68
+ "description": "Two-line clamped descriptive paragraph that replaces the metrics row when present. `sys.typo.label.sm` / `sys.color.text.subtle`, centered. The slot reserves a fixed height of two `label.sm` lines so card height stays consistent across cards that carry metrics and cards that carry copy — extra content clamps with a trailing ellipsis.",
69
69
  "accepts": [
70
70
  "text"
71
71
  ]
72
72
  },
73
73
  "followAction": {
74
74
  "required": true,
75
- "description": "Trailing full-width [Toggle Button](../button/text.md) at the foot of the card. `Follow` (inactive) → `Following` (active). The carousel does not paint its own follow chrome — every state binding lives on the Toggle Button (Chip-toggle) contract, which paints `sys.color.primary` while inactive and a `transparent` fill with a hairline outline while active so the followed state recedes against the card's own `surface` tier without re-painting a tone that would clash.",
75
+ "description": "Trailing full-width [Toggle Button](../button/text.md) at the foot of the card. `Follow` (inactive) → `Following` (active). The carousel does not paint its own follow chrome — every state binding lives on the Toggle Button (Chip-toggle) contract, which paints `sys.color.background.primary` while inactive and a `transparent` fill with a hairline outline while active so the followed state recedes against the card's own `surface` tier without re-painting a tone that would clash.",
76
76
  "accepts": [
77
77
  "button"
78
78
  ],
@@ -90,8 +90,8 @@
90
90
  "pagePeek": "ref.space.500",
91
91
  "pagePeekNote": "Guaranteed minimum visibility of the next card at the trailing edge — pinned to 40px (ref.space.500). Identical contract to PostCarousel.",
92
92
  "pageSnapAnchor": "Cards stick to the leading edge of the pager (the pager's own `padding-left`, the 16 rail). `scroll-snap-align: start` plus the pager's `scroll-padding-left: sys.layout.container.md` produce this anchor.",
93
- "cardFill": "sys.color.surface",
94
- "cardOutline": "sys.borderWidth.hairline sys.color.outlineVariant",
93
+ "cardFill": "sys.color.surface.default",
94
+ "cardOutline": "sys.borderWidth.hairline sys.color.border.default",
95
95
  "cardOutlineComposition": "overlay",
96
96
  "cardOutlineCompositionNote": "Painted on a dedicated `::after` overlay layer (`position: absolute; inset: 0; z-index: 2; pointer-events: none`), not as an inset `box-shadow` on the card box itself. The card hosts an opaque full-bleed cover band at the top; an inset shadow on the card would be masked by that fill at the top edge. Same overlay idiom DESIGN.md prescribes for the focus ring — so the stroke renders above every child regardless of edge-painting content.",
97
97
  "cardRadius": "sys.radius.md",
@@ -99,25 +99,25 @@
99
99
  "cardWidthNote": "Fixed pixel width — every profile card paints the same 176px footprint regardless of card count or screen width. The pager scrolls horizontally so the 176px footprint never reflows.",
100
100
  "cardStackGap": "sys.layout.stack.sm",
101
101
  "coverHeight": "88px",
102
- "coverFill": "sys.color.surfaceContainerHigh (background underlay — the placeholder image paints on top via `object-fit: cover`)",
102
+ "coverFill": "sys.color.surface.default (background underlay — the placeholder image paints on top via `object-fit: cover`)",
103
103
  "coverImageSource": "Same `/placeholder.png` asset every Chorus image-area slot falls back to. Cropped to fill the 88px band via `object-fit: cover` — the placeholder's centered 'blind' wordmark stays visually centered. Decorative — `aria-hidden`. Consumers can override per-item via `items[i].cover.src` (any image URL preserving the same `object-fit: cover` crop).",
104
104
  "avatarSize": 64,
105
- "avatarOverlap": "Avatar's vertical center sits on the cover band's bottom edge — the bottom half of the avatar bleeds onto the card surface. The 2-token (`sys.borderWidth.thin`) `sys.color.surface` halo separating the avatar from the cover band is owned by Thumbnail's `outlined={true}` case (see [Thumbnail § With surface outline](../thumbnail/thumbnail.md#with-surface-outline)) — outset `box-shadow`, not a wrapper border. Same contract as ProfileHeader's avatar.",
105
+ "avatarOverlap": "Avatar's vertical center sits on the cover band's bottom edge — the bottom half of the avatar bleeds onto the card surface. The 2-token (`sys.borderWidth.thin`) `sys.color.surface.default` halo separating the avatar from the cover band is owned by Thumbnail's `outlined={true}` case (see [Thumbnail § With surface outline](../thumbnail/thumbnail.md#with-surface-outline)) — outset `box-shadow`, not a wrapper border. Same contract as ProfileHeader's avatar.",
106
106
  "nameTypo": "sys.typo.label.md",
107
- "nameColor": "sys.color.onSurface",
107
+ "nameColor": "sys.color.text.default",
108
108
  "followersTypo": "sys.typo.label.sm",
109
- "followersColor": "sys.color.onSurfaceVariant",
109
+ "followersColor": "sys.color.text.subtle",
110
110
  "metricsRowGap": "sys.layout.inline.md",
111
111
  "metricChipTypo": "sys.typo.label.sm",
112
- "metricChipColor": "sys.color.onSurface",
112
+ "metricChipColor": "sys.color.text.default",
113
113
  "metricIconSize": "sys.icon.md",
114
- "metricIconStar": "StarFillIcon — sys.color.icon.yellow",
115
- "metricIconPulse": "PulseFillIcon — sys.color.success",
116
- "metricIconHeart": "HeartFillIcon — sys.color.icon.red",
114
+ "metricIconStar": "StarFillIcon — sys.color.icon.accent.yellow.default",
115
+ "metricIconPulse": "PulseFillIcon — sys.color.text.success",
116
+ "metricIconHeart": "HeartFillIcon — sys.color.icon.accent.red.default",
117
117
  "midSlotHeight": "calc(sys.typo.label.sm.size * sys.typo.label.sm.line * 2)",
118
118
  "midSlotHeightNote": "Shared fixed height for the metrics row and the description slot — exactly two `label.sm` lines (12 × 1.5 × 2 ≈ 36px). Cards that carry metrics and cards that carry a description paint the same outer height.",
119
119
  "descriptionTypo": "sys.typo.label.sm",
120
- "descriptionColor": "sys.color.onSurfaceVariant",
120
+ "descriptionColor": "sys.color.text.subtle",
121
121
  "descriptionLineClamp": 2,
122
122
  "descriptionOverflow": "Two-line clamp with trailing ellipsis; copy exceeding two lines truncates so the slot height stays fixed.",
123
123
  "followActionRendersAs": "Button variant='toggle' — Chip-toggle anatomy. Stretched to full card width via a wrapper rule. All state tokens delegate to the Toggle Button (Chip) family.",
@@ -8,5 +8,5 @@ A small, content-shaped control or label — chip-shaped affordance for two anch
8
8
 
9
9
  ## Sub-components
10
10
 
11
- - **[Filter](./filter.md)** — Selectable filter chip. Capsule (`radius.full`), `surfaceContainerHigh` raised tone with a hairline `outlineVariant` stroke at rest, swaps to an inverse fill when selected. Optional leading and trailing icons.
11
+ - **[Filter](./filter.md)** — Selectable filter chip. Capsule (`radius.full`), `surfaceContainerHigh` raised tone with a hairline `border.default` stroke at rest, swaps to an inverse fill when selected. Optional leading and trailing icons.
12
12
  - **[Tag](./tag.md)** — Informational tag chip. Square-cornered (`radius.sm`), `secondaryContainer` fill that sits one tonal step *below* the lifted Filter so the label reads as attached metadata rather than a tappable choice. Optional trailing icon only — typically the dismiss "×" for opt-out flows.
@@ -10,7 +10,7 @@ The selectable chip — a capsule-shaped toggle for refining a set. Unselected i
10
10
 
11
11
  ## Default
12
12
 
13
- At-rest — transparent fill with a hairline `outlineVariant` stroke so the chip sits on any surface without colliding with the surface ladder.
13
+ At-rest — transparent fill with a hairline `border.default` stroke so the chip sits on any surface without colliding with the surface ladder.
14
14
 
15
15
  ```preview
16
16
  chip/filter/unselected
@@ -22,9 +22,7 @@ import { Chip } from '@teamblind-chorus/ui';
22
22
  </Chip>
23
23
  ```
24
24
 
25
- ## Use cases
26
-
27
- ### Selected
25
+ ## Selected
28
26
 
29
27
  Active — inverse-toned fill. Toggle the `selected` flag on the same chip element.
30
28
 
@@ -41,7 +39,7 @@ import { Chip } from '@teamblind-chorus/ui';
41
39
  </Chip>
42
40
  ```
43
41
 
44
- ### With icon
42
+ ## Leading icon
45
43
 
46
44
  Facet glyph before the label — tag for category, magnifier for search, check on selection.
47
45
 
@@ -59,7 +57,7 @@ import { CheckedIcon } from '@teamblind-chorus/ui/icons';
59
57
  </Chip>
60
58
  ```
61
59
 
62
- ### With trailing icon
60
+ ## Trailing icon
63
61
 
64
62
  Directional/dismiss glyph after the label — chevron-down to expand, *×* to clear.
65
63
 
@@ -77,7 +75,7 @@ import { XIcon } from '@teamblind-chorus/ui/icons';
77
75
  </Chip>
78
76
  ```
79
77
 
80
- ### With trailing action
78
+ ## Trailing action
81
79
 
82
80
  Pair the chip rail with a trailing accent [Text Button](../button/text.md) (`size='small'`, `appearance='accent'`) for a destination outside the filter axis — managing the set, opening keyword settings. The button is *not* a filter toggle; the chip track scrolls horizontally with a trailing 48px `mask-image` fade painted only while overflowing, and the button stays pinned outside the scroll viewport at `sys.layout.inline.xl` gap.
83
81
 
@@ -128,7 +126,21 @@ import { ArrowDownIcon } from '@teamblind-chorus/ui/icons';
128
126
  </div>
129
127
  ```
130
128
 
131
- ### Group
129
+ ## Focused
130
+
131
+ Both selection states take the same standard ring; the case below shows unselected.
132
+
133
+ ```preview
134
+ chip/filter/focused
135
+ ---
136
+ import { Chip } from '@teamblind-chorus/ui';
137
+
138
+ <Chip variant="filter" state="focused">
139
+ All
140
+ </Chip>
141
+ ```
142
+
143
+ ## Group
132
144
 
133
145
  Adjacent filter chips share a 4px gap (`sys.layout.inline.sm`), left-to-right; selection is independent per chip — Filter does not enforce single-select.
134
146
 
@@ -153,20 +165,6 @@ import { Chip } from '@teamblind-chorus/ui';
153
165
  </div>
154
166
  ```
155
167
 
156
- ### Focus indicator
157
-
158
- Both selection states take the same standard ring; the case below shows unselected.
159
-
160
- ```preview
161
- chip/filter/focused
162
- ---
163
- import { Chip } from '@teamblind-chorus/ui';
164
-
165
- <Chip variant="filter" state="focused">
166
- All
167
- </Chip>
168
- ```
169
-
170
168
  ## Slots
171
169
 
172
170
  - **label** — accessible name. Required, single line.
@@ -197,8 +195,8 @@ Single visual variant; the selected/unselected toggle swaps the container/label
197
195
 
198
196
  | State | Background | Border (1px `sys.borderWidth.hairline`) | Label / icon color |
199
197
  |--------------|-------------------------------------|---------------------------------------------------------|-----------------------------------|
200
- | unselected | `transparent` | `sys.color.outlineVariant` | `sys.color.onSurface` |
201
- | selected | `sys.color.inverseSurface` | `transparent` | `sys.color.inverseOnSurface` |
198
+ | unselected | `transparent` | `sys.color.border.default` | `sys.color.text.default` |
199
+ | selected | `sys.color.background.inverse` | `transparent` | `sys.color.text.inverse` |
202
200
 
203
201
  ## States
204
202
 
@@ -63,16 +63,16 @@
63
63
  "selectionStates": {
64
64
  "unselected": {
65
65
  "background": "transparent",
66
- "label": "sys.color.onSurface",
66
+ "label": "sys.color.text.default",
67
67
  "border": {
68
68
  "width": "sys.borderWidth.hairline",
69
- "color": "sys.color.outlineVariant"
69
+ "color": "sys.color.border.default"
70
70
  },
71
71
  "note": "Transparent fill so the chip adopts whatever surface sits behind it (page, raised card, sheet) without pinning to a fixed neutral step."
72
72
  },
73
73
  "selected": {
74
- "background": "sys.color.inverseSurface",
75
- "label": "sys.color.inverseOnSurface",
74
+ "background": "sys.color.background.inverse",
75
+ "label": "sys.color.text.inverse",
76
76
  "border": null
77
77
  }
78
78
  },
@@ -102,35 +102,39 @@
102
102
  "layer": "::after overlay — position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
103
103
  "innerCounterRing": {
104
104
  "width": "sys.borderWidth.hairline",
105
- "color": "sys.color.focusInset"
105
+ "color": "sys.color.border.focused"
106
106
  },
107
107
  "outerRing": {
108
108
  "width": "sys.borderWidth.thin",
109
- "color": "sys.color.focus"
109
+ "color": "sys.color.border.focused"
110
110
  }
111
111
  },
112
112
  "note": "Keyboard-focus (:focus-visible) visual. Mirrors the `focusIndicator` block (the external-reader contract); kept here so spec-only renderers see focus in the states map. Composes over the lifecycle state the chip is in; never via plain mouse click."
113
113
  },
114
114
  "disabled": {
115
115
  "overlay": null,
116
- "containerOpacity": "sys.state.disabled",
116
+ "background": "sys.color.background.disabled",
117
+ "label": "sys.color.text.disabled",
118
+ "border": {
119
+ "width": "sys.borderWidth.hairline",
120
+ "color": "sys.color.border.bold"
121
+ },
117
122
  "suppressFocusRing": true,
118
- "cursor": "not-allowed"
123
+ "cursor": "not-allowed",
124
+ "note": "Explicit disabled (no opacity): neutral disabled fill + bold border so the shape reads on any surface, plus disabled label. Overrides the rest/selected appearance."
119
125
  }
120
126
  },
121
127
  "focusIndicator": {
122
128
  "description": "Keyboard-focus visual — an accessibility indicator, not a lifecycle state. Composes over whichever lifecycle state the chip is in. The `states.focused` block above is kept for JSX runtime consumers; this block is the parallel external-reader contract.",
123
129
  "composition": "outward",
124
- "compositionReason": "Action affordance with breathing room around it; the 3px outward extent is reserved by the surrounding layout.",
130
+ "compositionReason": "Action affordance with breathing room around it; the 1px outward ring is reserved by the surrounding layout.",
125
131
  "overlay": {
126
132
  "color": "label",
127
133
  "opacity": "sys.state.focus"
128
134
  },
129
135
  "ring": {
130
- "outerWidth": "sys.borderWidth.thin",
131
- "outerColor": "sys.color.focus",
132
- "insetWidth": "sys.borderWidth.hairline",
133
- "insetColor": "sys.color.focusInset"
136
+ "width": "sys.borderWidth.hairline",
137
+ "color": "sys.color.border.focused"
134
138
  },
135
139
  "trigger": ":focus-visible (keyboard / programmatic focus, never plain mouse click)"
136
140
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  > 🇰🇷 한국어: [`i18n/ko/schema/components/chip/tag.md`](../../../i18n/ko/schema/components/chip/tag.md)
4
4
 
5
- The informational chip — square-cornered label naming attached metadata (categories, statuses, content labels). Shorter than Filter (24 vs 32 min-height) with `sys.radius.sm` corners. Two appearances: `default` paints a translucent `sys.color.scrimSubtle` overlay (~8% inverse-tone, adopts whatever surface sits behind it); `accent` paints a tonal pale-primary container with primary label.
5
+ The informational chip — square-cornered label naming attached metadata (categories, statuses, content labels). Shorter than Filter (24 vs 32 min-height) with `sys.radius.sm` corners. Two appearances: `default` paints a translucent `sys.color.background.neutral` overlay (~8% inverse-tone, adopts whatever surface sits behind it); `accent` paints a tonal pale-primary container with primary label.
6
6
 
7
7
  **Reach for this when** you're naming attached metadata on rows, cards, or profiles. **Skip when** the marker signals unread / new activity on a host rather than describing it — use [Badge](../badge/badge.md) instead.
8
8
 
@@ -22,11 +22,9 @@ import { Chip } from '@teamblind-chorus/ui';
22
22
  </Chip>
23
23
  ```
24
24
 
25
- ## Use cases
25
+ ## Accent
26
26
 
27
- ### Accent
28
-
29
- Tonal pale-primary fill — `sys.color.primaryContainer` background, `sys.color.primary` label. Use when the tag should pop against the surface (Popular Tags in compose, highlighted hashtags); the default overlay is too quiet there.
27
+ Tonal pale-primary fill — `sys.color.background.selected` background, `sys.color.background.primary` label. Use when the tag should pop against the surface (Popular Tags in compose, highlighted hashtags); the default overlay is too quiet there.
30
28
 
31
29
  ```preview
32
30
  chip/tag/accent
@@ -38,7 +36,7 @@ import { Chip } from '@teamblind-chorus/ui';
38
36
  </Chip>
39
37
  ```
40
38
 
41
- ### Dismissable
39
+ ## Dismissable
42
40
 
43
41
  Opt-out — same chip with a trailing *×* to remove the tag. Trailing icon inherits label color via `currentColor`.
44
42
 
@@ -56,7 +54,22 @@ import { XIcon } from '@teamblind-chorus/ui/icons';
56
54
  </Chip>
57
55
  ```
58
56
 
59
- ### Group
57
+ ## Focused
58
+
59
+ Only the dismissable tag is focusable; the case below shows that form. See [Focus ring composition](../../DESIGN.md#focus-ring-composition).
60
+
61
+ ```preview
62
+ chip/tag/focused
63
+ ---
64
+ import { Chip } from '@teamblind-chorus/ui';
65
+ import { XIcon } from '@teamblind-chorus/ui/icons';
66
+
67
+ <Chip variant="tag" state="focused" trailingIcon={<XIcon />}>
68
+ Newsletter
69
+ </Chip>
70
+ ```
71
+
72
+ ## Group
60
73
 
61
74
  Adjacent tag chips share a 4px gap on both axes — `sys.layout.inline.sm` between siblings, `sys.layout.stack.2xs` between rows on wrap. Mixing with Filter is allowed — Tag's square + sunken tone vs Filter's pill + raised tone keeps roles legible. Tags are passive metadata, so collections exceeding the container's width **wrap** rather than scroll or truncate (set `display: flex; flex-wrap: wrap` on the container; do not use `overflow-x: auto` — horizontal scrolling belongs to tappable affordances).
62
75
 
@@ -76,21 +89,6 @@ import { Chip } from '@teamblind-chorus/ui';
76
89
  </div>
77
90
  ```
78
91
 
79
- ### Focus indicator
80
-
81
- Only the dismissable tag is focusable; the case below shows that form. See [Focus ring composition](../../DESIGN.md#focus-ring-composition).
82
-
83
- ```preview
84
- chip/tag/focused
85
- ---
86
- import { Chip } from '@teamblind-chorus/ui';
87
- import { XIcon } from '@teamblind-chorus/ui/icons';
88
-
89
- <Chip variant="tag" state="focused" trailingIcon={<XIcon />}>
90
- Newsletter
91
- </Chip>
92
- ```
93
-
94
92
  ## Slots
95
93
 
96
94
  - **label** — accessible name. Required, single line.
@@ -120,8 +118,8 @@ Two appearances; Tag never toggles.
120
118
 
121
119
  | Appearance | Background | Label / icon color |
122
120
  |------------|---------------------------------------------------------------------------------------------|------------------------------|
123
- | `default` | `sys.color.scrimSubtle` (translucent inverse-tone overlay — black 8% light / white 8% dark) | `sys.color.onSurface` |
124
- | `accent` | `sys.color.primaryContainer` (theme-aware) | `sys.color.primary` |
121
+ | `default` | `sys.color.background.neutral` (translucent inverse-tone overlay — black 8% light / white 8% dark) | `sys.color.text.default` |
122
+ | `accent` | `sys.color.background.selected` (theme-aware) | `sys.color.background.primary` |
125
123
 
126
124
  ## States
127
125
 
@@ -3,7 +3,7 @@
3
3
  "name": "Chip",
4
4
  "family": "chip",
5
5
  "subcomponent": "tag",
6
- "description": "Informational chip. Square-cornered metadata label. Passive (or dismissable via trailing ×). No leading icon. Two appearances: `default` paints the translucent `sys.color.scrimSubtle` scrim (~8% inverse-tone overlay — black in light, white in dark) so the tag adopts whatever surface sits behind it; `accent` paints a tonal pale-primary container (`sys.color.primaryContainer`) with primary label for tags that need to pop against the surface.",
6
+ "description": "Informational chip. Square-cornered metadata label. Passive (or dismissable via trailing ×). No leading icon. Two appearances: `default` paints the translucent `sys.color.background.neutral` scrim (~8% inverse-tone overlay — black in light, white in dark) so the tag adopts whatever surface sits behind it; `accent` paints a tonal pale-primary container (`sys.color.background.selected`) with primary label for tags that need to pop against the surface.",
7
7
  "element": "span",
8
8
  "props": {
9
9
  "variant": {
@@ -44,15 +44,15 @@
44
44
  },
45
45
  "appearances": {
46
46
  "default": {
47
- "background": "sys.color.scrimSubtle",
48
- "label": "sys.color.onSurface",
47
+ "background": "sys.color.background.neutral",
48
+ "label": "sys.color.text.default",
49
49
  "border": null,
50
50
  "default": true,
51
- "note": "Background is the translucent inverse-tone scrim (`sys.color.scrimSubtle` — black 8% in light mode, white 8% in dark) so the tag harmonises with whatever surface sits behind it — body, raised card, BottomSheet — instead of pinning to a fixed neutral step. Same Banner-style fill used by Progress track, StatusTag neutral, and Skeleton; sys-color is theme-aware so a single token resolves correctly in both modes."
51
+ "note": "Background is the translucent inverse-tone scrim (`sys.color.background.neutral` — black 8% in light mode, white 8% in dark) so the tag harmonises with whatever surface sits behind it — body, raised card, BottomSheet — instead of pinning to a fixed neutral step. Same Banner-style fill used by Progress track, StatusTag neutral, and Skeleton; sys-color is theme-aware so a single token resolves correctly in both modes."
52
52
  },
53
53
  "accent": {
54
- "background": "sys.color.primaryContainer",
55
- "label": "sys.color.primary",
54
+ "background": "sys.color.background.selected",
55
+ "label": "sys.color.text.link",
56
56
  "border": null,
57
57
  "note": "Tonal accent: pale primary container background with primary label. Sys-color tokens are theme-aware, so no separate dark binding is needed — the resolved tokens pick the right values per theme. Use for tags that should pop against the surface (e.g. Popular Tags in compose, highlighted hashtags) where the default overlay is too quiet."
58
58
  }
@@ -83,35 +83,39 @@
83
83
  "layer": "::after overlay — position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
84
84
  "innerCounterRing": {
85
85
  "width": "sys.borderWidth.hairline",
86
- "color": "sys.color.focusInset"
86
+ "color": "sys.color.border.focused"
87
87
  },
88
88
  "outerRing": {
89
89
  "width": "sys.borderWidth.thin",
90
- "color": "sys.color.focus"
90
+ "color": "sys.color.border.focused"
91
91
  }
92
92
  },
93
93
  "note": "Keyboard-focus (:focus-visible) visual. Mirrors the `focusIndicator` block (the external-reader contract); kept here so spec-only renderers see focus in the states map. Composes over the lifecycle state the chip is in; never via plain mouse click."
94
94
  },
95
95
  "disabled": {
96
96
  "overlay": null,
97
- "containerOpacity": "sys.state.disabled",
97
+ "background": "sys.color.background.disabled",
98
+ "label": "sys.color.text.disabled",
99
+ "border": {
100
+ "width": "sys.borderWidth.hairline",
101
+ "color": "sys.color.border.bold"
102
+ },
98
103
  "suppressFocusRing": true,
99
- "cursor": "not-allowed"
104
+ "cursor": "not-allowed",
105
+ "note": "Explicit disabled (no opacity): neutral disabled fill + bold border so the shape reads on any surface, plus disabled label. Overrides the rest/selected appearance."
100
106
  }
101
107
  },
102
108
  "focusIndicator": {
103
109
  "description": "Keyboard-focus visual — an accessibility indicator, not a lifecycle state. Composes over whichever lifecycle state the chip is in. Applies only when the chip is interactive (a dismiss trailingIcon is present). The `states.focused` block above is kept for JSX runtime consumers; this block is the parallel external-reader contract.",
104
110
  "composition": "outward",
105
- "compositionReason": "Action affordance with breathing room around it; the 3px outward extent is reserved by the surrounding layout.",
111
+ "compositionReason": "Action affordance with breathing room around it; the 1px outward ring is reserved by the surrounding layout.",
106
112
  "overlay": {
107
113
  "color": "label",
108
114
  "opacity": "sys.state.focus"
109
115
  },
110
116
  "ring": {
111
- "outerWidth": "sys.borderWidth.thin",
112
- "outerColor": "sys.color.focus",
113
- "insetWidth": "sys.borderWidth.hairline",
114
- "insetColor": "sys.color.focusInset"
117
+ "width": "sys.borderWidth.hairline",
118
+ "color": "sys.color.border.focused"
115
119
  },
116
120
  "trigger": ":focus-visible (keyboard / programmatic focus, never plain mouse click)"
117
121
  },
@@ -33,9 +33,7 @@ const [open, setOpen] = useState(false);
33
33
  </>
34
34
  ```
35
35
 
36
- ## Use cases
37
-
38
- ### With image
36
+ ## Image
39
37
 
40
38
  Pass an `image` to add a centred illustration between title and actions. With the image present, the whole stack centre-aligns. `imageFirst` (default `true`) controls whether the image sits under the title or the body.
41
39
 
@@ -90,18 +90,18 @@
90
90
  "sizing": {
91
91
  "scrimTint": "ref.palette.black.600",
92
92
  "scrimPaddingInline": "ref.space.500",
93
- "containerFill": "sys.color.surfaceContainerHigh",
93
+ "containerFill": "sys.color.surface.default",
94
94
  "containerRadius": "sys.radius.xl",
95
95
  "elevation": "sys.elevation.overlay",
96
96
  "containerPadding": "sys.layout.container.lg",
97
97
  "maxWidth": "480px",
98
98
  "titleTypo": "sys.typo.heading.sm",
99
- "titleColor": "sys.color.onSurface",
99
+ "titleColor": "sys.color.text.default",
100
100
  "imageWidth": "100%",
101
101
  "imageHeight": "auto",
102
102
  "imageRadius": "sys.radius.lg",
103
103
  "bodyTypo": "sys.typo.body.sm",
104
- "bodyColor": "sys.color.onSurfaceVariant",
104
+ "bodyColor": "sys.color.text.subtle",
105
105
  "interSlotGap": "sys.layout.stack.md",
106
106
  "actionsStackGap": "sys.layout.stack.xs"
107
107
  },
@@ -31,9 +31,7 @@ import { DirectoryList } from '@teamblind-chorus/ui';
31
31
  />
32
32
  ```
33
33
 
34
- ## Use cases
35
-
36
- ### With header action
34
+ ## Header action
37
35
 
38
36
  Extends the header with a trailing `accent` Text Button when the screen has a broader index page to route to.
39
37
 
@@ -55,12 +55,12 @@
55
55
  }
56
56
  },
57
57
  "sizing": {
58
- "containerFill": "sys.color.surface",
58
+ "containerFill": "sys.color.surface.default",
59
59
  "containerPaddingBlock": "sys.layout.container.lg",
60
60
  "containerPaddingInline": "sys.layout.container.md",
61
61
  "headerToListGap": "sys.layout.stack.md",
62
62
  "labelTypo": "sys.typo.heading.md",
63
- "labelColor": "sys.color.onSurface",
63
+ "labelColor": "sys.color.text.default",
64
64
  "headerActionRendersAs": "Button variant='text' size='xsmall' appearance='accent' — link-affordance accent rule.",
65
65
  "rowRung": "list/entry size=\"large\" — 48 avatar, inline.lg gap, label.md primary, label.sm secondary + description.",
66
66
  "rowInlinePaddingNote": "Each row keeps the list/entry native sys.layout.container.md inline padding (the tap target reaches the surface edge) and adds margin-inline: calc(-1 * sys.layout.container.md) so the visible avatar sits flush at the section's content rail — aligned with the header label at 16 from the surface.",
@@ -2,7 +2,7 @@
2
2
  "$schema": "../../family.schema.json",
3
3
  "family": "divider",
4
4
  "name": "Divider",
5
- "description": "Region separator — a heavy tonal band that splits adjacent regions whose vertical rhythm alone doesn't read as a boundary. Painted with `sys.color.scrimSubtle` (~8% inverse-tone overlay — black scrim in light mode, white scrim in dark) so the band stays visible on every host surface tier (`surface`, `surfaceContainer`, `surfaceContainerHigh`, hero, …) without colliding with a fixed neutral step. Same scrim used by Banner default, Chip / Tag default, Progress track, StatusTag neutral, and Skeleton — Divider is the section-level member of that family. Reserved for *region*-level separation between groups that don't share an enclosing container (a feed segment ending and a followed-channels list beginning, a recents block ending above a single anchored CTA). Not for row-level separators inside a List (the list's own `divider={true}` paints those as a hairline `outlineVariant` rule). Single-spec family.",
5
+ "description": "Region separator — a heavy tonal band that splits adjacent regions whose vertical rhythm alone doesn't read as a boundary. Painted with `sys.color.border.default` (~8% inverse-tone overlay — black scrim in light mode, white scrim in dark) so the band stays visible on every host surface tier (`surface`, `surfaceContainer`, `surfaceContainerHigh`, hero, …) without colliding with a fixed neutral step. Same scrim used by Banner default, Chip / Tag default, Progress track, StatusTag neutral, and Skeleton — Divider is the section-level member of that family. Reserved for *region*-level separation between groups that don't share an enclosing container (a feed segment ending and a followed-channels list beginning, a recents block ending above a single anchored CTA). Not for row-level separators inside a List (the list's own `divider={true}` paints those as a hairline `border.default` rule). Single-spec family.",
6
6
  "useCases": [
7
7
  "between page-level content groups",
8
8
  "between a feed segment and the section below",
@@ -2,19 +2,19 @@
2
2
 
3
3
  > 🇰🇷 한국어: [`i18n/ko/schema/components/divider/divider.md`](../../../i18n/ko/schema/components/divider/divider.md)
4
4
 
5
- A section-break band — a single full-bleed block painted with `sys.color.scrimSubtle` (~8% inverse-tone overlay — black in light mode, white in dark) at a fixed block thickness of `sys.layout.stack.xs` (8). Reach for it when two adjacent regions don't share an enclosing container and vertical rhythm alone doesn't read as a boundary — a directory of suggested channels ending and a fresh recommendation list beginning, a feed segment ending and a followed-channels list resuming, a promo strip ending and content picking up below.
5
+ A section-break band — a single full-bleed block painted with `sys.color.border.default` (~8% inverse-tone overlay — black in light mode, white in dark) at a fixed block thickness of `sys.layout.stack.xs` (8). Reach for it when two adjacent regions don't share an enclosing container and vertical rhythm alone doesn't read as a boundary — a directory of suggested channels ending and a fresh recommendation list beginning, a feed segment ending and a followed-channels list resuming, a promo strip ending and content picking up below.
6
6
 
7
- **Reach for this when** the boundary between two regions is ambiguous because they share the same surface and vertical rhythm — the visitor's eye should *land* on the break, not infer it. **Skip when** the regions already sit on different surfaces (one card, one canvas — the surface change is the break), when one region carries a heading that itself reads as the start of a new block, or when the separation is between *rows of the same list* (List's own `divider={true}` paints those as a hairline `outlineVariant` rule).
7
+ **Reach for this when** the boundary between two regions is ambiguous because they share the same surface and vertical rhythm — the visitor's eye should *land* on the break, not infer it. **Skip when** the regions already sit on different surfaces (one card, one canvas — the surface change is the break), when one region carries a heading that itself reads as the start of a new block, or when the separation is between *rows of the same list* (List's own `divider={true}` paints those as a hairline `border.default` rule).
8
8
 
9
- **Surface-agnostic by design.** The fill is `sys.color.scrimSubtle` — a ~8% inverse-tone overlay (black in light mode, white in dark) — so the band reads as a tint *darker than the host surface* without pinning to a fixed neutral step. The same band visibly separates regions on `surface`, `surfaceContainerHigh`, a hero panel, or a coloured card without retoning per-host. Same scrim tier as Banner default, Chip / Tag default, Progress track, StatusTag neutral, and Skeleton.
9
+ **Surface-agnostic by design.** The fill is `sys.color.border.default` — a ~8% inverse-tone overlay (black in light mode, white in dark) — so the band reads as a tint *darker than the host surface* without pinning to a fixed neutral step. The same band visibly separates regions on `surface`, `surfaceContainerHigh`, a hero panel, or a coloured card without retoning per-host. Same scrim tier as Banner default, Chip / Tag default, Progress track, StatusTag neutral, and Skeleton.
10
10
 
11
- **Layout inset.** `full-bleed` — Divider stretches edge-to-edge inside the page-shell content box. It ships **no** inline padding, **no** outer margin, **no** corner radius, **no** stroke; it just paints `scrimSubtle` across a `sys.layout.stack.xs` (8) block. Drop it as a direct child of the page-shell `<main>` (or any full-width host column) between two regions — do not wrap in a `padding-inline` div, `className="px-*"`, or `style={{ padding }}`; the band reading edge-to-edge IS what makes it a region boundary.
11
+ **Layout inset.** `full-bleed` — Divider stretches edge-to-edge inside the page-shell content box. It ships **no** inline padding, **no** outer margin, **no** corner radius, **no** stroke; it just paints `border.default` across a `sys.layout.stack.xs` (8) block. Drop it as a direct child of the page-shell `<main>` (or any full-width host column) between two regions — do not wrap in a `padding-inline` div, `className="px-*"`, or `style={{ padding }}`; the band reading edge-to-edge IS what makes it a region boundary.
12
12
 
13
- **Safe zone — none.** The parent column pays no `gap`, `padding-block`, or `margin-block` around Divider. The 8 of `scrimSubtle` is the breathing. If two regions feel cramped after dropping Divider between them, the fix is to add internal padding to the regions themselves (`layout.container.*`), never to wrap Divider in a spacer or paint outer margin on it.
13
+ **Safe zone — none.** The parent column pays no `gap`, `padding-block`, or `margin-block` around Divider. The 8 of `border.default` is the breathing. If two regions feel cramped after dropping Divider between them, the fix is to add internal padding to the regions themselves (`layout.container.*`), never to wrap Divider in a spacer or paint outer margin on it.
14
14
 
15
15
  ## Default
16
16
 
17
- The single canonical band. 8 high, full inline width, `scrimSubtle` fill.
17
+ The single canonical band. 8 high, full inline width, `border.default` fill.
18
18
 
19
19
  ```preview
20
20
  divider/default
@@ -24,9 +24,7 @@ import { Divider } from '@teamblind-chorus/ui';
24
24
  <Divider />
25
25
  ```
26
26
 
27
- ## Use cases
28
-
29
- ### Between adjacent lists
27
+ ## Between adjacent lists
30
28
 
31
29
  The canonical placement — a region break between two full-bleed lists stacked on the same page. Above: a directory of new channels (DirectoryList, an inert directory). Below: a recommendation set keyed to the visitor (SuggestionList, the pager-flavoured sibling). Both lists own their internal divider hairlines for rows, but the *boundary between the two lists* is a region break — that is the role Divider plays.
32
30
 
@@ -56,13 +54,13 @@ import { Divider, DirectoryList, SuggestionList } from '@teamblind-chorus/ui';
56
54
 
57
55
  ## Slots
58
56
 
59
- - **container** — the tonal band. `sys.color.scrimSubtle` fill, `sys.layout.stack.xs` (8) block thickness, full inline width, no padding, no border, no corner radius. The native `<hr>` element with all browser defaults reset. `aria-hidden="true"` by default — the band is decorative.
57
+ - **container** — the tonal band. `sys.color.border.default` fill, `sys.layout.stack.xs` (8) block thickness, full inline width, no padding, no border, no corner radius. The native `<hr>` element with all browser defaults reset. `aria-hidden="true"` by default — the band is decorative.
60
58
 
61
59
  ## Anatomy
62
60
 
63
61
  | Slot | Token bindings |
64
62
  |------------|----------------|
65
- | container | `sys.color.scrimSubtle` fill, `sys.layout.stack.xs` (8) block height, 100% inline width, `border: none`, `margin: 0`, `border-radius: 0` |
63
+ | container | `sys.color.border.default` fill, `sys.layout.stack.xs` (8) block height, 100% inline width, `border: none`, `margin: 0`, `border-radius: 0` |
66
64
 
67
65
  ## Appearance
68
66
 
@@ -70,11 +68,11 @@ Single appearance — Divider has no emphasis axis, no orientation axis, and no
70
68
 
71
69
  | Appearance | Fill | When to use |
72
70
  |------------|----------------------------|-----------------------------------------------------------------------------|
73
- | `default` | `sys.color.scrimSubtle` | The only mode. Same scrim used by Banner default / Chip-Tag default / Progress track / StatusTag neutral / Skeleton — Divider is the section-level member of that family. |
71
+ | `default` | `sys.color.border.default` | The only mode. Same scrim used by Banner default / Chip-Tag default / Progress track / StatusTag neutral / Skeleton — Divider is the section-level member of that family. |
74
72
 
75
73
  ## Behavior
76
74
 
77
75
  - **aria-hidden by default.** The band is decorative chrome; screen-reader users navigate by headings and landmarks, not visual breaks. Override `aria-hidden={false}` only when the divider genuinely marks a semantic section change (rare — prefer a heading).
78
- - **Fixed thickness.** Block thickness is `sys.layout.stack.xs` (8) and is not a prop. Heavier bands compete with content; thinner bands collapse to a hairline (use the host's own `outlineVariant` border for row-level breaks, not Divider).
76
+ - **Fixed thickness.** Block thickness is `sys.layout.stack.xs` (8) and is not a prop. Heavier bands compete with content; thinner bands collapse to a hairline (use the host's own `border.default` border for row-level breaks, not Divider).
79
77
  - **Full-bleed by contract.** The band must touch the page edge to read as a region boundary. Wrapping Divider in a padding-inline container breaks the affordance — see the AGENTS.md "one gutter, paid once" rule.
80
- - **Not a row separator.** Inside a List, rows already separate via the list's own `divider={true}` hairline `outlineVariant` rule. Reach for Divider only at the *region* level, between groups that don't share an enclosing container.
78
+ - **Not a row separator.** Inside a List, rows already separate via the list's own `divider={true}` hairline `border.default` rule. Reach for Divider only at the *region* level, between groups that don't share an enclosing container.