@cyberskill/design 1.2.0 → 1.3.9

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 (232) hide show
  1. package/DESIGN.md +11 -9
  2. package/README.md +28 -24
  3. package/SKILL.md +18 -9
  4. package/THIRD-PARTY-NOTICES.md +35 -0
  5. package/VERSION +1 -1
  6. package/_ds_bundle.js +701 -1342
  7. package/_esm/cs.mjs +2 -2
  8. package/_esm/react.mjs +6 -1
  9. package/_vendor/NOTICE.md +16 -0
  10. package/_vendor/babel/README.md +7 -0
  11. package/_vendor/babel/babel.min.js +4 -0
  12. package/_vendor/react/README.md +3 -0
  13. package/_vendor/react/react-dom.production.min.js +1 -0
  14. package/_vendor/react/react.production.min.js +1 -0
  15. package/assets/aurora-hoa.webp +0 -0
  16. package/assets/aurora-kim.webp +0 -0
  17. package/assets/aurora-moc.webp +0 -0
  18. package/assets/aurora-tho.webp +0 -0
  19. package/assets/aurora-thuy.webp +0 -0
  20. package/base/ai.css +8 -3
  21. package/base/collections.css +10 -4
  22. package/base/components.css +5 -2
  23. package/base/controls.css +58 -21
  24. package/base/data.css +1 -1
  25. package/base/feedback.css +9 -2
  26. package/base/forms.css +1 -1
  27. package/base/glass.css +1 -1
  28. package/base/interaction.css +6 -2
  29. package/base/navigation.css +1 -1
  30. package/base/reset.css +7 -1
  31. package/base/responsive.css +13 -12
  32. package/base/shell.css +8 -2
  33. package/components/_i18n/i18n.js +28 -3
  34. package/components/_i18n/strings.js +42 -24
  35. package/components/ai/ChatMessage.d.ts +2 -0
  36. package/components/ai/ChatMessage.jsx +8 -4
  37. package/components/ai/ConfidenceMeter.d.ts +2 -0
  38. package/components/ai/HumanReviewGate.d.ts +2 -0
  39. package/components/ai/PromptInput.d.ts +2 -0
  40. package/components/ai/TypingIndicator.d.ts +2 -0
  41. package/components/ai/ai-conversation.card.html +3 -3
  42. package/components/ai/ai-lumi.card.html +3 -3
  43. package/components/ai/ai.card.html +3 -3
  44. package/components/brand/brand.card.html +3 -3
  45. package/components/button/buttons.card.html +3 -3
  46. package/components/data/Image.jsx +18 -2
  47. package/components/data/Sortable.d.ts +5 -1
  48. package/components/data/Sortable.jsx +42 -9
  49. package/components/data/Sortable.prompt.md +4 -2
  50. package/components/data/Terminal.jsx +3 -2
  51. package/components/data/Tooltip.d.ts +2 -0
  52. package/components/data/Tooltip.jsx +6 -3
  53. package/components/data/Tree.d.ts +2 -1
  54. package/components/data/Tree.jsx +137 -16
  55. package/components/data/Tree.prompt.md +1 -1
  56. package/components/data/collections.card.html +3 -3
  57. package/components/data/data.card.html +3 -3
  58. package/components/datatable/DataTable.d.ts +24 -1
  59. package/components/datatable/DataTable.jsx +78 -5
  60. package/components/datatable/DataTable.prompt.md +2 -1
  61. package/components/datatable/datatable.card.html +20 -16
  62. package/components/dialog/dialog.card.html +3 -3
  63. package/components/feedback/Alert.d.ts +2 -0
  64. package/components/feedback/Alert.jsx +8 -2
  65. package/components/feedback/EmptyState.d.ts +2 -0
  66. package/components/feedback/EmptyState.jsx +6 -3
  67. package/components/feedback/ProgressBar.d.ts +2 -0
  68. package/components/feedback/ProgressBar.jsx +6 -3
  69. package/components/feedback/Toast.jsx +15 -1
  70. package/components/feedback/Toast.prompt.md +2 -1
  71. package/components/feedback/feedback-2.card.html +3 -3
  72. package/components/feedback/feedback.card.html +3 -3
  73. package/components/forms/Cascader.jsx +7 -2
  74. package/components/forms/FileUpload.d.ts +2 -0
  75. package/components/forms/Form.d.ts +3 -1
  76. package/components/forms/Form.jsx +9 -1
  77. package/components/forms/Form.prompt.md +1 -1
  78. package/components/forms/Mentions.d.ts +1 -1
  79. package/components/forms/Mentions.jsx +59 -7
  80. package/components/forms/Mentions.prompt.md +3 -1
  81. package/components/forms/Rating.d.ts +3 -2
  82. package/components/forms/Rating.jsx +34 -3
  83. package/components/forms/Rating.prompt.md +1 -1
  84. package/components/forms/Select.d.ts +2 -0
  85. package/components/forms/Select.jsx +6 -2
  86. package/components/forms/Slider.d.ts +2 -0
  87. package/components/forms/Slider.jsx +5 -2
  88. package/components/forms/Switch.d.ts +2 -0
  89. package/components/forms/Switch.jsx +7 -9
  90. package/components/forms/Toggle.d.ts +2 -0
  91. package/components/forms/Toggle.jsx +14 -2
  92. package/components/forms/forms-2.card.html +3 -3
  93. package/components/forms/forms.card.html +3 -3
  94. package/components/icon/Icon.d.ts +1 -1
  95. package/components/icon/Icon.prompt.md +1 -1
  96. package/components/icon/icon.card.html +3 -3
  97. package/components/logo/logo.card.html +3 -3
  98. package/components/navigation/CommandPalette.d.ts +2 -0
  99. package/components/navigation/Menu.d.ts +2 -0
  100. package/components/navigation/Menu.jsx +60 -6
  101. package/components/navigation/Steps.d.ts +2 -0
  102. package/components/navigation/Steps.jsx +6 -3
  103. package/components/navigation/Tabs.d.ts +2 -0
  104. package/components/navigation/Tabs.jsx +6 -3
  105. package/components/navigation/Toolbar.d.ts +3 -2
  106. package/components/navigation/Toolbar.jsx +117 -11
  107. package/components/navigation/Toolbar.prompt.md +1 -1
  108. package/components/navigation/navigation.card.html +3 -3
  109. package/components/navigation/shell.card.html +3 -3
  110. package/components/overlays/ContextMenu.d.ts +2 -0
  111. package/components/overlays/ContextMenu.jsx +6 -3
  112. package/components/overlays/Drawer.d.ts +2 -0
  113. package/components/overlays/alertdialog.card.html +3 -3
  114. package/components/overlays/overlays.card.html +3 -3
  115. package/components/textfield/textfield.card.html +3 -3
  116. package/dist/styles.min.css +312 -64
  117. package/docs/benchmark-rubric.md +2 -2
  118. package/docs/ci-cd.md +18 -13
  119. package/docs/consumer-grant.md +4 -1
  120. package/docs/consuming.md +16 -12
  121. package/docs/contrast-report.md +81 -1
  122. package/docs/conventions.md +18 -5
  123. package/docs/decisions.md +41 -3
  124. package/docs/deploy.md +19 -6
  125. package/docs/design-styles.md +2 -2
  126. package/docs/doctrine.md +51 -0
  127. package/docs/figma.md +2 -0
  128. package/docs/live-hub.md +3 -1
  129. package/docs/products.md +1 -1
  130. package/docs/quality-gates.md +24 -12
  131. package/docs/release-notes.md +1 -1
  132. package/docs/release-runbook.md +78 -0
  133. package/docs/storybook.md +3 -3
  134. package/docs/sync.md +8 -8
  135. package/docs/template-schema-v2.md +1 -1
  136. package/docs/vi/benchmark-rubric.md +2 -2
  137. package/docs/vi/ci-cd.md +17 -14
  138. package/docs/vi/consumer-grant.md +4 -1
  139. package/docs/vi/consuming.md +16 -12
  140. package/docs/vi/contrast-report.md +81 -1
  141. package/docs/vi/conventions.md +19 -6
  142. package/docs/vi/decisions.md +40 -3
  143. package/docs/vi/deploy.md +19 -6
  144. package/docs/vi/design-styles.md +1 -1
  145. package/docs/vi/doctrine.md +51 -0
  146. package/docs/vi/figma.md +2 -0
  147. package/docs/vi/live-hub.md +3 -1
  148. package/docs/vi/products.md +1 -1
  149. package/docs/vi/quality-gates.md +23 -12
  150. package/docs/vi/release-notes.md +1 -1
  151. package/docs/vi/release-runbook.md +78 -0
  152. package/docs/vi/storybook.md +3 -3
  153. package/docs/vi/sync.md +7 -7
  154. package/docs/vi/template-schema-v2.md +1 -1
  155. package/docs/viewer.html +16 -5
  156. package/fonts/OFL.txt +98 -0
  157. package/guidelines/atomic-view.html +2 -2
  158. package/guidelines/brand-imagery.html +1 -1
  159. package/guidelines/elements-variants.html +5 -5
  160. package/guidelines/spacing-breakpoints.html +2 -1
  161. package/guidelines/surfaces-glass.html +1 -1
  162. package/llms.txt +18 -11
  163. package/package.json +28 -8
  164. package/templates/app-shell/AppShell.dc.html +3 -3
  165. package/templates/app-shell/content-schema.json +7 -0
  166. package/templates/article/Article.dc.html +3 -3
  167. package/templates/article/content-schema.json +7 -0
  168. package/templates/auth/Auth.dc.html +26 -10
  169. package/templates/auth/content-schema.json +25 -0
  170. package/templates/dashboard/Dashboard.dc.html +4 -4
  171. package/templates/dashboard/content-schema.json +7 -0
  172. package/templates/delivery-change-note/DeliveryChangeNote.dc.html +2 -2
  173. package/templates/delivery-runbook/DeliveryRunbook.dc.html +2 -2
  174. package/templates/email-safe/email-announcement.html +2 -2
  175. package/templates/email-safe/email-dunning.html +2 -2
  176. package/templates/email-safe/email-investor.html +2 -2
  177. package/templates/email-safe/email-launch.html +2 -2
  178. package/templates/email-safe/email-newsletter.html +2 -2
  179. package/templates/email-safe/email-status.html +2 -2
  180. package/templates/email-safe/email-transactional.html +2 -2
  181. package/templates/finance-dunning-email/FinanceDunningEmail.dc.html +2 -2
  182. package/templates/finance-expense-report/FinanceExpenseReport.dc.html +2 -2
  183. package/templates/finance-invoice/FinanceInvoice.dc.html +2 -2
  184. package/templates/finance-quote/FinanceQuote.dc.html +4 -4
  185. package/templates/hr-interview-kit/HrInterviewKit.dc.html +1 -1
  186. package/templates/marketing-case-study/MarketingCaseStudy.dc.html +1 -1
  187. package/templates/marketing-page/MarketingPage.dc.html +3 -3
  188. package/templates/marketing-page/content-schema.json +1 -0
  189. package/templates/settings/Settings.dc.html +3 -3
  190. package/templates/settings/content-schema.json +7 -0
  191. package/tokens/element-seeds.json +2 -2
  192. package/tokens/elements.css +193 -19
  193. package/tokens/native/CSTokens.kt +3 -2
  194. package/tokens/native/CSTokens.swift +3 -2
  195. package/tokens/native/cs_tokens.dart +3 -2
  196. package/tokens/provenance.json +8 -8
  197. package/tokens/spacing.css +2 -1
  198. package/tokens/tokens.dtcg.json +19 -14
  199. package/tokens/tokens.js +16 -15
  200. package/tokens/tokens.json +15 -14
  201. package/ui_kits/deck/index.html +1 -1
  202. package/ui_kits/status-hub/StatusHub.jsx +1 -1
  203. package/ui_kits/status-hub/login.html +52 -10
  204. package/ui_kits/status-hub/project.html +1 -1
  205. package/ui_kits/status-hub/settings.html +1 -1
  206. package/ui_kits/website/Website.jsx +1 -1
  207. package/ui_kits/website/careers.html +2 -2
  208. package/ui_kits/website/chat.html +1 -1
  209. package/ui_kits/website/site.css +1 -1
  210. package/ui_kits/website/work.html +2 -2
  211. package/assets/aurora-hoa.png +0 -0
  212. package/assets/aurora-kim.png +0 -0
  213. package/assets/aurora-moc.png +0 -0
  214. package/assets/aurora-thuy.png +0 -0
  215. package/docs/decisions/container-query-migration.md +0 -18
  216. package/docs/decisions/overlay-manager-design.md +0 -101
  217. package/docs/plans/cyberskill-design-system-audit-and-12-month-evolution-plan.md +0 -1490
  218. package/docs/status/assets/favicon.svg +0 -5
  219. package/docs/status/assets/status-legacy.css +0 -399
  220. package/docs/status/assets/status-legacy.js +0 -505
  221. package/docs/status/assets/status.css +0 -644
  222. package/docs/status/assets/status.js +0 -1308
  223. package/docs/status/data/status-feed.json +0 -1
  224. package/docs/status/data/task/TASK-REL-001.js +0 -1
  225. package/docs/status/data/task/TASK-REL-002.js +0 -1
  226. package/docs/status/index.html +0 -46
  227. package/docs/status/roadmap.html +0 -4
  228. package/docs/status/status-legacy.html +0 -122
  229. package/docs/tasks/BACKLOG.md +0 -26
  230. package/docs/tasks/_state/commit-links.yaml +0 -14
  231. package/docs/tasks/release/TASK-REL-001-launch-1-1-0/spec.md +0 -55
  232. package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +0 -54
@@ -139,6 +139,8 @@
139
139
  color: var(--cs-color-text-primary, #45210e);
140
140
  left: 50%;
141
141
  max-inline-size: min(42rem, calc(100vw - 2rem));
142
+ max-block-size: min(80vh, calc(100vh - 4rem));
143
+ overflow: auto;
142
144
  padding: var(--cs-space-6, 24px);
143
145
  position: absolute;
144
146
  top: 12vh;
@@ -163,6 +165,7 @@
163
165
 
164
166
  /* ---- DataTable ---- */
165
167
  .cs-table-wrap { overflow: auto; }
168
+ .cs-table-wrap--status { padding: var(--cs-space-4, 16px) 0; }
166
169
  .cs-table { border-collapse: collapse; color: var(--cs-color-text-primary, #45210e); inline-size: 100%; }
167
170
  .cs-table th, .cs-table td {
168
171
  border-block-end: 1px solid rgba(69, 33, 14, 0.18);
@@ -179,7 +182,7 @@
179
182
  .cs-ai-disclosure { display: inline-block; position: relative; }
180
183
  .cs-ai-disclosure__badge {
181
184
  background: var(--cs-color-semantic-info, #1d4ed8); border: 0; border-radius: 999px;
182
- color: #ffffff; font: inherit; font-size: 0.875rem; font-weight: 700;
185
+ color: var(--cs-color-semantic-info-fg, #ffffff); font: inherit; font-size: 0.875rem; font-weight: 700;
183
186
  padding: 0.25rem 0.625rem; cursor: pointer;
184
187
  }
185
188
  .cs-ai-disclosure__panel {
@@ -187,7 +190,7 @@
187
190
  border: 1px solid rgba(69, 33, 14, 0.18); border-radius: var(--cs-radius-md, 8px);
188
191
  box-shadow: var(--cs-shadow-md, 0 12px 30px rgba(31, 19, 11, 0.18));
189
192
  display: grid; gap: 0.375rem; inset-block-start: calc(100% + 0.375rem); inset-inline-start: 0;
190
- min-inline-size: 18rem; padding: 0.75rem; position: absolute; z-index: 20;
193
+ min-inline-size: 18rem; padding: 0.75rem; position: absolute; z-index: var(--cs-depth-dropdown, 60);
191
194
  }
192
195
  .cs-ai-disclosure__sources { color: var(--cs-color-text-muted, #6e5a4c); font-size: 0.8125rem; }
193
196
 
package/base/controls.css CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  /* SearchField */
4
4
  .cs-search { display: flex; align-items: center; gap: 8px; border: 1px solid var(--cs-component-textfield-border-default); border-radius: var(--cs-radius-full); padding: 0 14px; min-height: 44px; background: var(--cs-color-surface-panel); }
5
- .cs-search:focus-within { border-color: var(--cs-color-brand-ochre); box-shadow: 0 0 0 3px color-mix(in oklab, var(--cs-color-brand-ochre) 30%, transparent); }
5
+ .cs-search:focus-within {
6
+ border-color: var(--cs-color-text-primary);
7
+ outline: 2px solid var(--cs-color-text-primary);
8
+ outline-offset: 2px;
9
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre);
10
+ }
6
11
  .cs-search svg { color: var(--cs-color-text-muted); flex: none; }
7
12
  .cs-search input { flex: 1; min-inline-size: 0; border: 0; background: transparent; outline: 0; font: inherit; font-family: var(--cs-font-family-ui); color: var(--cs-color-text-primary); }
8
13
  .cs-search input::placeholder { color: var(--cs-color-text-muted); }
@@ -11,7 +16,12 @@
11
16
 
12
17
  /* NumberField / stepper */
13
18
  .cs-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--cs-component-textfield-border-default); border-radius: var(--cs-radius-md); overflow: hidden; background: var(--cs-color-surface-panel); }
14
- .cs-stepper:focus-within { border-color: var(--cs-color-brand-ochre); }
19
+ .cs-stepper:focus-within {
20
+ border-color: var(--cs-color-text-primary);
21
+ outline: 2px solid var(--cs-color-text-primary);
22
+ outline-offset: 2px;
23
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre);
24
+ }
15
25
  .cs-stepper button { border: 0; background: var(--cs-color-surface-raised); color: var(--cs-color-text-primary); inline-size: 40px; cursor: pointer; font-size: var(--cs-font-size-md); font-weight: 700; display: grid; place-items: center; }
16
26
  .cs-stepper button:hover:not(:disabled) { color: var(--cs-color-text-accent); }
17
27
  .cs-stepper button:disabled { opacity: 0.45; cursor: not-allowed; }
@@ -110,7 +120,7 @@
110
120
  .cs-datepicker__field { display: inline-flex; align-items: center; gap: 8px; min-inline-size: 220px; min-block-size: 44px; font: 500 14px var(--cs-font-family-ui); color: var(--cs-color-text-primary); background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); padding: 8px 12px; cursor: pointer; }
111
121
  .cs-datepicker__field:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 1px; }
112
122
  .cs-datepicker__field .ph { color: var(--cs-color-text-muted); }
113
- .cs-datepicker__pop { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-block-start: calc(100% + 6px); inset-inline-start: 0; }
123
+ .cs-datepicker__pop { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-block-start: calc(100% + 6px); inset-inline-start: 0; }
114
124
  .cs-timepicker { display: inline-flex; align-items: center; gap: 8px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); padding: 0 10px; min-block-size: 44px; color: var(--cs-color-text-muted); }
115
125
  .cs-timepicker:focus-within { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 1px; }
116
126
  .cs-timepicker select { border: 0; background: transparent; color: var(--cs-color-text-primary); font: 600 14px var(--cs-font-family-mono); padding: 8px 2px; cursor: pointer; }
@@ -118,13 +128,13 @@
118
128
 
119
129
  /* ---- v3 Batch 4 (Jul 2026): HoverCard · Popconfirm · ContextMenu · FAB · Result · InlineEdit ---- */
120
130
  .cs-hovercard { position: relative; display: inline-block; }
121
- .cs-hovercard__panel { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; display: block; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px 16px; font-size: var(--cs-font-size-sm); line-height: 1.5; color: var(--cs-color-text-primary); }
131
+ .cs-hovercard__panel { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; display: block; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px 16px; font-size: var(--cs-font-size-sm); line-height: 1.5; color: var(--cs-color-text-primary); }
122
132
  .cs-popconfirm { position: relative; display: inline-block; }
123
- .cs-popconfirm__panel { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; display: block; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 12px 14px; }
133
+ .cs-popconfirm__panel { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; display: block; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 12px 14px; }
124
134
  .cs-popconfirm__title { display: block; font: 600 13.5px/1.45 var(--cs-font-family-ui); color: var(--cs-color-text-primary); margin-bottom: 10px; }
125
135
  .cs-popconfirm__actions { display: flex; gap: 8px; justify-content: flex-end; }
126
136
  .cs-ctxmenu-zone { position: relative; }
127
- .cs-fab { position: fixed; inset-inline-end: 24px; inset-block-end: 24px; z-index: var(--cs-depth-overlay, 60); display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
137
+ .cs-fab { position: fixed; inset-inline-end: 24px; inset-block-end: 24px; z-index: var(--cs-depth-overlay, 80); display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
128
138
  .cs-fab--static { position: static; align-items: flex-start; }
129
139
  .cs-fab__main { inline-size: 56px; block-size: 56px; border-radius: 999px; border: 0; background: var(--cs-accent); color: var(--cs-accent-on); display: grid; place-items: center; cursor: pointer; box-shadow: var(--cs-shadow-lg); }
130
140
  .cs-fab__main:hover { filter: brightness(1.05); }
@@ -167,7 +177,7 @@
167
177
  .cs-image__fallback { display: grid; place-items: center; min-block-size: 80px; block-size: 100%; color: var(--cs-color-text-muted); }
168
178
  .cs-image__zoom { position: fixed; inset: 0; z-index: var(--cs-depth-modal, 100); background: rgba(26, 17, 8, .82); display: grid; place-items: center; cursor: zoom-out; }
169
179
  .cs-image__zoom img { max-inline-size: 88vw; max-block-size: 86vh; border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-xl); }
170
- .cs-image__zoom button { position: absolute; inset-block-start: 18px; inset-inline-end: 18px; inline-size: 40px; block-size: 40px; border-radius: 999px; border: 0; background: rgba(255, 255, 255, .12); color: #fff; font-size: var(--cs-font-size-base); cursor: pointer; }
180
+ .cs-image__zoom button { position: absolute; inset-block-start: 18px; inset-inline-end: 18px; inline-size: 40px; block-size: 40px; border-radius: 999px; border: 0; background: rgba(255, 255, 255, .12); color: #fff; /* on-dark-chrome ink */ font-size: var(--cs-font-size-base); cursor: pointer; }
171
181
  .cs-toolbar { display: inline-flex; align-items: center; gap: 4px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); padding: 4px; }
172
182
  .cs-toolbar__btn { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; color: var(--cs-color-text-primary); font: 600 13px var(--cs-font-family-ui); padding: 7px 10px; border-radius: var(--cs-radius-sm); cursor: pointer; min-block-size: 32px; }
173
183
  .cs-toolbar__btn:hover { background: var(--cs-color-surface-raised); }
@@ -186,7 +196,7 @@
186
196
  .cs-navmenu__wrap { position: relative; }
187
197
  .cs-navmenu__top { display: inline-flex; align-items: center; gap: 5px; border: 0; background: none; text-decoration: none; font: 600 14px var(--cs-font-family-ui); color: var(--cs-color-text-primary); padding: 9px 12px; border-radius: var(--cs-radius-sm); cursor: pointer; }
188
198
  .cs-navmenu__top:hover, .cs-navmenu__top.is-open { background: var(--cs-color-surface-raised); }
189
- .cs-navmenu__panel { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-inline-start: 0; inset-block-start: calc(100% + 8px); display: grid; grid-template-columns: repeat(2, 220px); gap: 6px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-md); padding: 10px; }
199
+ .cs-navmenu__panel { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-inline-start: 0; inset-block-start: calc(100% + 8px); display: grid; grid-template-columns: repeat(2, 220px); gap: 6px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-md); padding: 10px; }
190
200
  .cs-navmenu__card { display: grid; gap: 3px; padding: 10px 12px; border-radius: var(--cs-radius-md); text-decoration: none; color: var(--cs-color-text-primary); }
191
201
  .cs-navmenu__card:hover { background: var(--cs-accent-tint); }
192
202
  .cs-navmenu__card b { font-size: var(--cs-font-size-sm); }
@@ -214,6 +224,12 @@
214
224
 
215
225
  /* ---- v3 Batch 6a (Jul 2026): Form · Tree · BackTop · Watermark ---- */
216
226
  .cs-form { display: grid; gap: 16px; }
227
+ /* FIND-015 — visible pending + interaction lock while asyncRules / submit run. */
228
+ .cs-form.is-pending { opacity: 0.72; }
229
+ .cs-form.is-pending :is(button, input, select, textarea, [role="button"]) {
230
+ pointer-events: none;
231
+ cursor: wait;
232
+ }
217
233
  .cs-form__summary { border: 1px solid var(--cs-color-semantic-danger); border-radius: var(--cs-radius-md); background: color-mix(in oklab, var(--cs-color-semantic-danger) 8%, var(--cs-color-surface-panel)); color: var(--cs-color-text-primary); padding: 12px 14px; font-size: var(--cs-font-size-sm); }
218
234
  .cs-form__summary b { color: var(--cs-color-semantic-danger); }
219
235
  .cs-form__summary ul { margin: 6px 0 0; padding-inline-start: 18px; }
@@ -232,7 +248,7 @@
232
248
  [data-theme="dark"] .cs-tree__row.is-selected .cs-tree__label { color: var(--cs-accent-bright); }
233
249
  .cs-tree__twist { inline-size: 20px; block-size: 28px; border: 0; background: none; color: var(--cs-color-text-muted); cursor: pointer; padding: 0; display: inline-grid; place-items: center; }
234
250
  .cs-tree__label { border: 0; background: none; color: var(--cs-color-text-primary); font: inherit; padding: 4px 6px; cursor: pointer; border-radius: var(--cs-radius-sm); }
235
- .cs-backtop { position: fixed; inset-inline-end: 24px; inset-block-end: 84px; z-index: var(--cs-depth-overlay, 60); inline-size: 44px; block-size: 44px; border-radius: 999px; border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); display: grid; place-items: center; cursor: pointer; box-shadow: var(--cs-shadow-md); }
251
+ .cs-backtop { position: fixed; inset-inline-end: 24px; inset-block-end: 84px; z-index: var(--cs-depth-overlay, 80); inline-size: 44px; block-size: 44px; border-radius: 999px; border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); display: grid; place-items: center; cursor: pointer; box-shadow: var(--cs-shadow-md); }
236
252
  .cs-backtop:hover { border-color: var(--cs-accent); }
237
253
 
238
254
  /* ---- v3 Batch 6b (Jul 2026): TreeSelect · Cascader · Transfer · Mentions ---- */
@@ -240,7 +256,7 @@
240
256
  .cs-treeselect__field { display: inline-flex; align-items: center; justify-content: space-between; gap: 10px; inline-size: 100%; min-block-size: 44px; font: 500 14px var(--cs-font-family-ui); color: var(--cs-color-text-primary); background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); padding: 8px 12px; cursor: pointer; box-sizing: border-box; }
241
257
  .cs-treeselect__field:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 1px; }
242
258
  .cs-treeselect__field .ph { color: var(--cs-color-text-muted); }
243
- .cs-treeselect__pop, .cs-cascader__pop { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-block-start: calc(100% + 6px); inset-inline-start: 0; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 8px; min-inline-size: 100%; }
259
+ .cs-treeselect__pop, .cs-cascader__pop { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-block-start: calc(100% + 6px); inset-inline-start: 0; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 8px; min-inline-size: 100%; }
244
260
  .cs-cascader__pop { display: flex; padding: 0; overflow: hidden; }
245
261
  .cs-cascader__col { list-style: none; margin: 0; padding: 6px; min-inline-size: 150px; max-block-size: 240px; overflow: auto; }
246
262
  .cs-cascader__col + .cs-cascader__col { border-inline-start: 1px solid var(--cs-color-border-default); }
@@ -255,29 +271,30 @@
255
271
  .cs-transfer__list label { display: flex; align-items: center; gap: 8px; font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); cursor: pointer; }
256
272
  .cs-transfer__ops { display: grid; gap: 6px; align-content: center; }
257
273
  .cs-mentions { position: relative; display: block; max-inline-size: 420px; }
258
- .cs-mentions__pop { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-inline-start: 10px; inset-block-start: calc(100% - 6px); display: grid; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 4px; }
274
+ .cs-mentions__pop { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-inline-start: 10px; inset-block-start: calc(100% - 6px); display: grid; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 4px; }
259
275
  .cs-mentions__pop button { border: 0; background: none; text-align: start; font: 600 13px var(--cs-font-family-mono); color: var(--cs-color-text-primary); padding: 7px 10px; border-radius: var(--cs-radius-sm); cursor: pointer; }
260
- .cs-mentions__pop button:hover { background: var(--cs-accent-tint); color: var(--cs-accent-strong); }
276
+ .cs-mentions__pop button:hover, .cs-mentions__pop button.hl, .cs-mentions__pop button[aria-selected="true"] { background: var(--cs-accent-tint); color: var(--cs-accent-strong); }
277
+ [data-theme="dark"] .cs-mentions__pop button:hover, [data-theme="dark"] .cs-mentions__pop button.hl, [data-theme="dark"] .cs-mentions__pop button[aria-selected="true"] { background: color-mix(in oklab, var(--cs-accent) 22%, var(--cs-color-surface-panel)); color: var(--cs-accent-bright); }
261
278
 
262
279
  /* ---- v3 Batch 6c (Jul 2026): ColorPicker · Tour · QRCode ---- */
263
280
  .cs-colorpicker { position: relative; display: inline-block; }
264
281
  .cs-colorpicker__field { display: inline-flex; align-items: center; gap: 9px; min-block-size: 44px; font: 600 13px var(--cs-font-family-mono); color: var(--cs-color-text-primary); background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); padding: 8px 12px; cursor: pointer; }
265
282
  .cs-colorpicker__field i { inline-size: 20px; block-size: 20px; border-radius: 6px; border: 1px solid var(--cs-color-border-default); }
266
283
  .cs-colorpicker__field:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 1px; }
267
- .cs-colorpicker__pop { position: absolute; z-index: var(--cs-depth-dropdown, 50); inset-block-start: calc(100% + 6px); inset-inline-start: 0; display: grid; gap: 10px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 12px; }
284
+ .cs-colorpicker__pop { position: absolute; z-index: var(--cs-depth-dropdown, 60); inset-block-start: calc(100% + 6px); inset-inline-start: 0; display: grid; gap: 10px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 12px; }
268
285
  .cs-colorpicker__grid { display: grid; grid-template-columns: repeat(5, 26px); gap: 8px; }
269
286
  .cs-colorpicker__grid button { inline-size: 26px; block-size: 26px; border-radius: 7px; border: 1px solid var(--cs-color-border-default); cursor: pointer; }
270
287
  .cs-colorpicker__grid button.on { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 1px; }
271
288
  .cs-colorpicker__hex input { inline-size: 110px; font: 600 13px var(--cs-font-family-mono); color: var(--cs-color-text-primary); background: var(--cs-color-surface-raised); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-sm); padding: 6px 8px; }
272
289
  .cs-tour__scrim { position: fixed; inset: 0; z-index: var(--cs-depth-modal, 100); background: rgba(26, 17, 8, .45); }
273
- .cs-tour__hole { position: fixed; z-index: calc(var(--cs-depth-modal, 90) + 1); border-radius: var(--cs-radius-md); box-shadow: 0 0 0 4000px rgba(26, 17, 8, .45); outline: var(--cs-focus-ring, 3px) solid var(--cs-color-brand-ochre); pointer-events: none; background: transparent; }
274
- .cs-tour__pop { position: fixed; z-index: calc(var(--cs-depth-modal, 90) + 2); inline-size: 280px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-xl); padding: 14px 16px; }
290
+ .cs-tour__hole { position: fixed; z-index: calc(var(--cs-depth-modal, 100) + 1); border-radius: var(--cs-radius-md); box-shadow: 0 0 0 4000px rgba(26, 17, 8, .45); outline: var(--cs-focus-ring, 3px) solid var(--cs-color-brand-ochre); pointer-events: none; background: transparent; }
291
+ .cs-tour__pop { position: fixed; z-index: calc(var(--cs-depth-modal, 100) + 2); inline-size: 280px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-xl); padding: 14px 16px; }
275
292
  .cs-tour__pop b { font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); }
276
293
  .cs-tour__pop p { margin: 6px 0 12px; font-size: var(--cs-font-size-sm); line-height: 1.5; color: var(--cs-color-text-muted); }
277
294
  .cs-tour__bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
278
295
  .cs-tour__count { font: 600 11px var(--cs-font-family-mono); color: var(--cs-color-text-muted); }
279
296
  .cs-tour__btns { display: flex; gap: 6px; }
280
- .cs-qrcode { display: inline-block; padding: 10px; background: #fff; border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); line-height: 0; }
297
+ .cs-qrcode { display: inline-block; padding: 10px; background: var(--cs-color-surface-panel, #fff); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); line-height: 0; }
281
298
 
282
299
  /* ---- v3 Batch 7a (Jul 2026): Masonry · Splitter · HotKeys · Dock ---- */
283
300
  .cs-masonry__item { break-inside: avoid; }
@@ -310,6 +327,10 @@
310
327
  .cs-sortable__item.is-dragging { opacity: .5; }
311
328
  .cs-sortable__item.is-over { border-color: var(--cs-accent); box-shadow: inset 0 0 0 1px var(--cs-accent); }
312
329
  .cs-sortable__grip { color: var(--cs-color-text-muted); }
330
+ .cs-sortable__label { flex: 1; min-inline-size: 0; }
331
+ .cs-sortable__ops { display: inline-flex; gap: 4px; margin-inline-start: auto; }
332
+ .cs-sortable__ops .cs-button { cursor: pointer; }
333
+ .cs-sortable__ops .cs-button:disabled { opacity: .4; cursor: not-allowed; }
313
334
 
314
335
  /* ---- v3 Batch 7c (Jul 2026): Chart · Editor · Terminal ---- */
315
336
  .cs-chart { margin: 0; display: grid; gap: 8px; max-inline-size: 420px; }
@@ -319,15 +340,30 @@
319
340
  .cs-editor__bar { display: flex; gap: 2px; padding: 6px; border-block-end: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-raised); border-radius: var(--cs-radius-md) var(--cs-radius-md) 0 0; }
320
341
  .cs-editor__area { padding: 12px 14px; font: 400 14px/1.6 var(--cs-font-family-ui); color: var(--cs-color-text-primary); outline: none; }
321
342
  .cs-editor__area:focus-visible { box-shadow: inset 0 0 0 2px var(--cs-color-accent-ochre); border-radius: 0 0 var(--cs-radius-md) var(--cs-radius-md); }
322
- .cs-terminal { max-inline-size: 480px; border-radius: var(--cs-radius-lg); overflow: hidden; border: 1px solid #3a2a1c; box-shadow: var(--cs-shadow-md); }
323
- .cs-terminal__bar { display: flex; align-items: center; gap: 6px; background: #2a1a0d; color: #c9b7a3; font: 600 11px var(--cs-font-family-mono); padding: 8px 12px; }
324
- .cs-terminal__bar i { inline-size: 10px; block-size: 10px; border-radius: 999px; background: #5b4331; }
343
+ /* Terminal — always-dark chrome (FIND-010: hex only in local custom props) */
344
+ .cs-terminal {
345
+ --cs-term-border: #3a2a1c;
346
+ --cs-term-bar: #2a1a0d;
347
+ --cs-term-dot: #5b4331;
348
+ --cs-term-bg: #1a1108;
349
+ --cs-term-fg: #f5ead9;
350
+ --cs-term-muted: #c9b7a3;
351
+ max-inline-size: 480px; border-radius: var(--cs-radius-lg); overflow: hidden; border: 1px solid var(--cs-term-border); box-shadow: var(--cs-shadow-md);
352
+ }
353
+ .cs-terminal__bar { display: flex; align-items: center; gap: 6px; background: var(--cs-term-bar); color: var(--cs-term-muted); font: 600 11px var(--cs-font-family-mono); padding: 8px 12px; }
354
+ .cs-terminal__bar i { inline-size: 10px; block-size: 10px; border-radius: 999px; background: var(--cs-term-dot); }
325
355
  .cs-terminal__bar span { margin-inline-start: 8px; }
326
- .cs-terminal__body { background: #1a1108; color: #f5ead9; font: 500 13px/1.7 var(--cs-font-family-mono); padding: 12px 14px; min-block-size: 130px; }
356
+ .cs-terminal__body { background: var(--cs-term-bg); color: var(--cs-term-fg); font: 500 13px/1.7 var(--cs-font-family-mono); padding: 12px 14px; min-block-size: 130px; }
327
357
  .cs-terminal__line { display: flex; gap: 8px; align-items: center; }
328
358
  .cs-terminal__line .p { color: var(--cs-color-brand-ochre); }
329
359
  .cs-terminal__line input { flex: 1; border: 0; background: transparent; color: inherit; font: inherit; outline: none; }
330
- .cs-terminal__out { color: #c9b7a3; white-space: pre-wrap; }
360
+ /* Wrapper ring — input clears outline for chrome; focus-within restores ≥3:1 indicator (FIND-038). */
361
+ .cs-terminal:focus-within {
362
+ outline: 2px solid var(--cs-color-accent-ochre);
363
+ outline-offset: 2px;
364
+ box-shadow: 0 0 0 5px var(--cs-color-brand-umber);
365
+ }
366
+ .cs-terminal__out { color: var(--cs-term-muted); white-space: pre-wrap; }
331
367
 
332
368
  /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
333
369
  @media (prefers-color-scheme: dark) {
@@ -339,4 +375,5 @@
339
375
  [data-theme="system"] .cs-tree__row.is-selected .cs-tree__label { color: var(--cs-accent-bright); }
340
376
  [data-theme="system"] .cs-cascader__opt.on { background: color-mix(in oklab, var(--cs-accent) 22%, var(--cs-color-surface-panel)); color: var(--cs-accent-bright); }
341
377
  [data-theme="system"] .cs-datagrid tr.is-selected td { background: color-mix(in oklab, var(--cs-accent) 18%, var(--cs-color-surface-panel)); }
378
+ [data-theme="system"] .cs-mentions__pop button:hover, [data-theme="system"] .cs-mentions__pop button.hl, [data-theme="system"] .cs-mentions__pop button[aria-selected="true"] { background: color-mix(in oklab, var(--cs-accent) 22%, var(--cs-color-surface-panel)); color: var(--cs-accent-bright); }
342
379
  }
package/base/data.css CHANGED
@@ -37,7 +37,7 @@
37
37
 
38
38
  /* Tooltip */
39
39
  .cs-tooltip { position: relative; display: inline-flex; }
40
- .cs-tooltip__bubble { position: absolute; inset-block-end: calc(100% + 8px); inset-inline-start: 50%; transform: translateX(-50%) translateY(4px); background: var(--cs-color-brand-umber); color: #fff; font-size: var(--cs-font-size-xs); font-weight: 600; line-height: 1.35; padding: 6px 10px; border-radius: var(--cs-radius-sm); white-space: nowrap; max-inline-size: 240px; opacity: 0; pointer-events: none; transition: opacity var(--cs-duration-fast) var(--cs-ease-standard), transform var(--cs-duration-fast) var(--cs-ease-standard); box-shadow: var(--cs-shadow-md); z-index: var(--cs-depth-toast); }
40
+ .cs-tooltip__bubble { position: absolute; inset-block-end: calc(100% + 8px); inset-inline-start: 50%; transform: translateX(-50%) translateY(4px); background: var(--cs-color-brand-umber); color: #fff; /* on-brand-umber ink */ font-size: var(--cs-font-size-xs); font-weight: 600; line-height: 1.35; padding: 6px 10px; border-radius: var(--cs-radius-sm); white-space: nowrap; max-inline-size: 240px; opacity: 0; pointer-events: none; transition: opacity var(--cs-duration-fast) var(--cs-ease-standard), transform var(--cs-duration-fast) var(--cs-ease-standard); box-shadow: var(--cs-shadow-md); z-index: var(--cs-depth-dropdown, 60); }
41
41
  .cs-tooltip__bubble::after { content: ""; position: absolute; inset-block-start: 100%; inset-inline-start: 50%; transform: translateX(-50%); border: 5px solid transparent; border-block-start-color: var(--cs-color-brand-umber); }
42
42
  .cs-tooltip:hover .cs-tooltip__bubble, .cs-tooltip:focus-within .cs-tooltip__bubble { opacity: 1; transform: translateX(-50%) translateY(0); }
43
43
 
package/base/feedback.css CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  /* Badge — compact status label */
4
4
  .cs-badge { display: inline-flex; align-items: center; gap: 5px; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-xs); font-weight: 700; line-height: 1; padding: 4px 9px; border-radius: var(--cs-radius-full); text-transform: uppercase; letter-spacing: 0.04em; background: var(--cs-color-surface-raised); color: var(--cs-color-text-accent); border: 1px solid var(--cs-color-border-default); }
5
- .cs-badge--solid { border-color: transparent; color: #fff; background: var(--cs-color-brand-umber); }
5
+ .cs-badge--solid { border-color: transparent; color: #fff; /* on-brand-umber ink (allowlisted; text-inverse flips in dark) */ background: var(--cs-color-brand-umber); }
6
6
  .cs-badge--ochre { background: var(--cs-color-brand-ochre); color: var(--cs-color-brand-umber); border-color: transparent; }
7
7
  .cs-badge--success { background: var(--cs-color-semantic-success); color: var(--cs-color-text-inverse); border-color: transparent; }
8
8
  .cs-badge--danger { background: var(--cs-color-semantic-danger); color: var(--cs-color-text-inverse); border-color: transparent; }
@@ -16,10 +16,13 @@
16
16
  .cs-tag__close:hover { background: color-mix(in oklab, var(--cs-color-brand-umber) 12%, transparent); }
17
17
 
18
18
  /* Alert / Banner */
19
- .cs-alert { display: grid; grid-template-columns: auto 1fr; gap: 12px; padding: 14px 16px; border-radius: var(--cs-radius-md); border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); }
19
+ .cs-alert { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; padding: 14px 16px; border-radius: var(--cs-radius-md); border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); align-items: start; }
20
20
  .cs-alert__icon { color: var(--cs-color-text-accent); display: grid; place-items: start; padding-block-start: 1px; }
21
21
  .cs-alert__title { font-weight: 700; margin: 0 0 2px; }
22
22
  .cs-alert__body { margin: 0; color: var(--cs-color-text-muted); font-size: var(--cs-font-size-sm); }
23
+ .cs-alert__dismiss { appearance: none; border: 0; background: transparent; color: var(--cs-color-text-muted); cursor: pointer; font-size: var(--cs-font-size-md, 1.125rem); line-height: 1; padding: 0 2px; border-radius: var(--cs-radius-sm); }
24
+ .cs-alert__dismiss:hover { color: var(--cs-color-text-primary); }
25
+ .cs-alert__dismiss:focus-visible { outline: 2px solid var(--cs-color-focus-ring, var(--cs-accent-bright)); outline-offset: 2px; }
23
26
  .cs-alert--info { border-inline-start: 4px solid var(--cs-color-semantic-info); }
24
27
  .cs-alert--info .cs-alert__icon { color: var(--cs-color-semantic-info); }
25
28
  .cs-alert--success { border-inline-start: 4px solid var(--cs-color-semantic-success); }
@@ -33,7 +36,11 @@
33
36
  .cs-toast-stack { position: fixed; inset-block-end: 20px; inset-inline-end: 20px; z-index: var(--cs-depth-toast); display: grid; gap: 10px; max-inline-size: min(380px, calc(100vw - 40px)); }
34
37
  .cs-toast { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: start; padding: 12px 14px; border-radius: var(--cs-radius-md); background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); box-shadow: var(--cs-shadow-md); color: var(--cs-color-text-primary); animation: cs-toast-in var(--cs-duration-base) var(--cs-ease-entrance); }
35
38
  .cs-toast__icon { color: var(--cs-color-text-accent); }
39
+ .cs-toast--default { border-inline-start: 4px solid var(--cs-color-semantic-info); }
40
+ .cs-toast--default .cs-toast__icon { color: var(--cs-color-semantic-info); }
41
+ .cs-toast--success { border-inline-start: 4px solid var(--cs-color-semantic-success); }
36
42
  .cs-toast--success .cs-toast__icon { color: var(--cs-color-semantic-success); }
43
+ .cs-toast--danger { border-inline-start: 4px solid var(--cs-color-semantic-danger); }
37
44
  .cs-toast--danger .cs-toast__icon { color: var(--cs-color-semantic-danger); }
38
45
  .cs-toast__title { font-weight: 700; font-size: var(--cs-font-size-sm); }
39
46
  .cs-toast__body { font-size: var(--cs-font-size-sm); color: var(--cs-color-text-muted); margin-block-start: 2px; }
package/base/forms.css CHANGED
@@ -29,7 +29,7 @@
29
29
  .cs-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-family: var(--cs-font-family-ui); color: var(--cs-color-text-primary); }
30
30
  .cs-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
31
31
  .cs-switch__track { inline-size: 44px; block-size: 26px; border-radius: 999px; background: var(--cs-color-border-default); position: relative; transition: background var(--cs-duration-fast) var(--cs-ease-standard); flex: none; }
32
- .cs-switch__track::after { content: ""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px; inline-size: 20px; block-size: 20px; border-radius: 50%; background: #fff; box-shadow: var(--cs-shadow-xs); transition: transform var(--cs-duration-fast) var(--cs-ease-standard); }
32
+ .cs-switch__track::after { content: ""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px; inline-size: 20px; block-size: 20px; border-radius: 50%; background: var(--cs-color-surface-panel, #fff); box-shadow: var(--cs-shadow-xs); transition: transform var(--cs-duration-fast) var(--cs-ease-standard); }
33
33
  .cs-switch input:checked + .cs-switch__track { background: var(--cs-color-brand-umber); }
34
34
  [data-theme="dark"] .cs-switch input:checked + .cs-switch__track { background: var(--cs-color-brand-ochre); }
35
35
  .cs-switch input:checked + .cs-switch__track::after { transform: translateX(18px); }
package/base/glass.css CHANGED
@@ -114,7 +114,7 @@
114
114
  radial-gradient(90% 120% at 12% -10%, color-mix(in oklab, var(--cs-color-brand-ochre) 46%, transparent), transparent 55%),
115
115
  radial-gradient(70% 90% at 88% 8%, color-mix(in oklab, #ffcf5c 32%, transparent), transparent 60%),
116
116
  radial-gradient(120% 120% at 50% 120%, color-mix(in oklab, #1a1108 60%, transparent), transparent 60%);
117
- color: #fff;
117
+ color: #fff; /* on-aurora wash */
118
118
  }
119
119
  .cs-aurora--photo { background-size: cover; background-position: center; }
120
120
 
@@ -22,15 +22,19 @@
22
22
  box-shadow: var(--cs-shadow-xs);
23
23
  }
24
24
 
25
- /* ---- 2. Soft ochre focus glow — layered on the immutable 3px ring ---- */
25
+ /* ---- 2. Focus halo — ochre brand ring outside the high-contrast contour (FIND-032) ---- */
26
26
  .cs-button:focus-visible,
27
27
  .cs-field__control:focus-visible,
28
28
  .cs-select select.cs-field__control:focus-visible,
29
29
  .cs-native-select select.cs-field__control:focus-visible,
30
30
  .cs-search:focus-within,
31
+ .cs-stepper:focus-within,
32
+ .cs-prompt:focus-within,
33
+ .cs-cmdk__search:focus-within,
34
+ .cs-terminal:focus-within,
31
35
  .cs-ai-disclosure__badge:focus-visible,
32
36
  .cs-switch input:focus-visible + .cs-switch__track {
33
- box-shadow: 0 0 0 5px color-mix(in oklab, var(--cs-color-accent-ochre) 26%, transparent);
37
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre);
34
38
  }
35
39
 
36
40
  /* ---- 3. Entrance motion utilities (opt-in) + a gentle Dialog entrance ---- */
@@ -28,7 +28,7 @@
28
28
 
29
29
  /* Menu / Dropdown */
30
30
  .cs-menu { position: relative; display: inline-block; }
31
- .cs-menu__list { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; min-inline-size: 200px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 6px; z-index: var(--cs-depth-toast); display: grid; gap: 2px; }
31
+ .cs-menu__list { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; min-inline-size: 200px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 6px; z-index: var(--cs-depth-dropdown, 60); display: grid; gap: 2px; }
32
32
  .cs-menu__list--end { inset-inline-start: auto; inset-inline-end: 0; }
33
33
  .cs-menu__item { display: flex; align-items: center; gap: 10px; inline-size: 100%; text-align: start; border: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); padding: 8px 10px; border-radius: var(--cs-radius-sm); cursor: pointer; }
34
34
  .cs-menu__item:hover { background: var(--cs-color-surface-raised); }
package/base/reset.css CHANGED
@@ -14,4 +14,10 @@ body {
14
14
  :where(h1, h2, h3, h4, h5, h6) { line-height: var(--cs-font-lineHeight-heading, 1.35); text-wrap: balance; }
15
15
  :where(p) { text-wrap: pretty; }
16
16
  :where(code, pre, kbd, samp) { font-family: var(--cs-font-family-mono, ui-monospace, monospace); }
17
- :where(:focus-visible) { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre, #f4ba17); outline-offset: 2px; }
17
+ /* Composite focus indicator (FIND-032): high-contrast text-primary contour (≥3:1
18
+ * on light + dark surfaces) + ochre outer brand halo. Ochre alone is ~1.7:1 on cream. */
19
+ :where(:focus-visible) {
20
+ outline: 2px solid var(--cs-color-text-primary, #45210e);
21
+ outline-offset: 2px;
22
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre, #f4ba17);
23
+ }
@@ -1,4 +1,5 @@
1
1
  /* CyberSkill — global responsive layer (loaded LAST so it can adapt any surface).
2
+ * FIND-007: width stops ⊆ token breakpoints (incl. justified `phone` 360).
2
3
  * The system is desktop-first but every artifact must read on tablet and phone.
3
4
  * Strategy: (1) media never overflows; (2) the print-doc archetype (cs-desk /
4
5
  * cs-sheet) relaxes its generous desktop padding on small screens; (3) shared class
@@ -25,26 +26,26 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
25
26
 
26
27
  /* 2 — Print-doc archetype: shrink desk + sheet chrome as the screen narrows.
27
28
  * cs-desk is the grey backing; cs-sheet is the white page. */
28
- @media screen and (max-width: 900px) {
29
+ @media screen and (max-width: 768px) {
29
30
  .cs-desk { padding: 24px 10px !important; }
30
31
  .cs-sheet { padding: 40px 40px !important; }
31
32
  }
32
- @media screen and (max-width: 620px) {
33
+ @media screen and (max-width: 640px) {
33
34
  .cs-desk { padding: 12px 6px !important; }
34
35
  .cs-sheet { padding: 26px 20px !important; border-radius: 8px !important; }
35
36
  }
36
- @media screen and (max-width: 460px) {
37
+ @media screen and (max-width: 360px) {
37
38
  .cs-sheet { padding: 20px 15px !important; }
38
39
  }
39
40
 
40
41
  /* 3 — Wide tables inside sheets/panels scroll horizontally instead of clipping */
41
- @media screen and (max-width: 760px) {
42
+ @media screen and (max-width: 768px) {
42
43
  .cs-sheet table, .cs-table-scroll { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
43
44
  }
44
45
 
45
46
  /* 4 — App shell: the sidebar + main is a fixed two-column inline grid on desktop.
46
47
  * Collapse it to a stacked layout; the sidebar becomes a horizontal nav strip. */
47
- @media screen and (max-width: 760px) {
48
+ @media screen and (max-width: 768px) {
48
49
  .cs-sidebar { position: static !important; width: auto !important; height: auto !important;
49
50
  display: flex !important; flex-wrap: wrap !important; gap: 4px 10px !important;
50
51
  align-items: center !important; border-inline-end: 0 !important;
@@ -59,12 +60,12 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
59
60
  * even on a laptop (≈1280), which otherwise overflowed the document. The legible
60
61
  * min-width floor for the inner track only applies once the window itself is narrow. */
61
62
  .cs-canvas-desk { overflow-x: auto; -webkit-overflow-scrolling: touch; }
62
- @media screen and (max-width: 1120px) {
63
+ @media screen and (max-width: 1280px) {
63
64
  .cs-canvas-desk > * { min-width: 960px; }
64
65
  }
65
66
 
66
67
  /* 6 — Very wide section padding eases in on phones */
67
- @media screen and (max-width: 620px) {
68
+ @media screen and (max-width: 640px) {
68
69
  section[style*="padding: 84px"], section[style*="padding: 80px"],
69
70
  section[style*="padding: 72px"] { padding-inline: 22px !important; }
70
71
  }
@@ -76,13 +77,13 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
76
77
  * Tablet: 3+ cols → 2. Phone: everything → 1 (declared after, so it wins at the
77
78
  * narrow width). Print is unaffected — the @page is wide, so these screen
78
79
  * breakpoints never fire during print/export. */
79
- @media screen and (max-width: 900px) {
80
+ @media screen and (max-width: 768px) {
80
81
  [style*="grid-template-columns: repeat(3"],
81
82
  [style*="grid-template-columns: repeat(4"],
82
83
  [style*="grid-template-columns: repeat(5"],
83
84
  [style*="grid-template-columns: repeat(6"] { grid-template-columns: repeat(2, 1fr) !important; }
84
85
  }
85
- @media screen and (max-width: 600px) {
86
+ @media screen and (max-width: 640px) {
86
87
  [style*="grid-template-columns: repeat(2"],
87
88
  [style*="grid-template-columns: repeat(3"],
88
89
  [style*="grid-template-columns: repeat(4"],
@@ -103,7 +104,7 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
103
104
  /* 8 — Touch targets reach the 44px minimum on phones/tablets (the system's a11y
104
105
  * floor). Base sidebar nav rows (39px) and the topbar search input (26px) are
105
106
  * fine for mouse on desktop but too small to tap; grow them on small screens. */
106
- @media screen and (max-width: 760px) {
107
+ @media screen and (max-width: 768px) {
107
108
  .cs-sidebar .cs-nav-item, .cs-nav-item { min-height: 44px; }
108
109
  .cs-search { display: flex; align-items: center; min-height: 44px; }
109
110
  .cs-search input, .cs-search select { min-height: 44px; }
@@ -118,7 +119,7 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
118
119
  * being propped open. It only breaks a token when it would otherwise overflow, so
119
120
  * ordinary prose is untouched. Scoped to the print-doc wrapper; the print @page is
120
121
  * wide, so this screen breakpoint never fires during export. */
121
- @media screen and (max-width: 760px) {
122
+ @media screen and (max-width: 768px) {
122
123
  .cs-desk, .cs-sheet { overflow-wrap: anywhere; }
123
124
  }
124
125
 
@@ -130,7 +131,7 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
130
131
  * attribute selector reliably overrides an inline grid-template-columns (a class
131
132
  * selector does not). Then let the app-region grids shrink (min-width:0) and the data
132
133
  * table scroll inside its panel instead of forcing the page wide. */
133
- @media screen and (max-width: 760px) {
134
+ @media screen and (max-width: 768px) {
134
135
  [style*="grid-template-columns: 248px 1fr"] { grid-template-columns: 1fr !important; }
135
136
  main { min-width: 0; }
136
137
  main > * { min-width: 0; }
package/base/shell.css CHANGED
@@ -17,7 +17,7 @@
17
17
  .cs-step { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; position: relative; padding-inline-end: 12px; }
18
18
  .cs-step:not(:last-child)::after { content: ""; position: absolute; inset-block-start: 13px; inset-inline-start: 34px; inline-size: calc(100% - 46px); block-size: 2px; background: var(--cs-color-border-default); }
19
19
  .cs-step__marker { inline-size: 28px; block-size: 28px; border-radius: 50%; display: grid; place-items: center; font-family: var(--cs-font-family-mono); font-weight: 700; font-size: var(--cs-font-size-sm); background: var(--cs-color-surface-raised); color: var(--cs-color-text-muted); border: 1px solid var(--cs-color-border-default); z-index: 1; }
20
- .cs-step--done .cs-step__marker { background: var(--cs-color-brand-umber); color: #fff; border-color: transparent; }
20
+ .cs-step--done .cs-step__marker { background: var(--cs-color-brand-umber); color: #fff; /* on-brand-umber ink */ border-color: transparent; }
21
21
  .cs-step--done:not(:last-child)::after { background: var(--cs-color-brand-umber); }
22
22
  .cs-step--active .cs-step__marker { background: var(--cs-color-brand-ochre); color: var(--cs-color-brand-umber); border-color: transparent; box-shadow: 0 0 0 4px color-mix(in oklab, var(--cs-color-brand-ochre) 28%, transparent); }
23
23
  .cs-step__title { font-weight: 700; font-size: var(--cs-font-size-sm); }
@@ -25,7 +25,7 @@
25
25
 
26
26
  /* Popover */
27
27
  .cs-popover { position: relative; display: inline-block; }
28
- .cs-popover__panel { position: absolute; inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px; z-index: var(--cs-depth-toast); }
28
+ .cs-popover__panel { position: absolute; inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px; z-index: var(--cs-depth-dropdown, 60); }
29
29
  .cs-popover__panel--end { inset-inline-start: auto; inset-inline-end: 0; }
30
30
 
31
31
  /* Drawer */
@@ -48,6 +48,12 @@
48
48
  .cs-cmdk__search { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-block-end: 1px solid var(--cs-color-border-default); }
49
49
  .cs-cmdk__search svg { color: var(--cs-color-text-muted); }
50
50
  .cs-cmdk__search input { flex: 1; border: 0; outline: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-md); color: var(--cs-color-text-primary); }
51
+ /* Wrapper ring — search input clears outline; focus-within restores ≥3:1 indicator (FIND-038). */
52
+ .cs-cmdk__search:focus-within {
53
+ outline: 2px solid var(--cs-color-text-primary);
54
+ outline-offset: -2px;
55
+ box-shadow: inset 0 0 0 2px var(--cs-color-accent-ochre);
56
+ }
51
57
  .cs-cmdk__list { max-block-size: 340px; overflow: auto; padding: 8px; display: grid; gap: 2px; }
52
58
  .cs-cmdk__label { font-size: var(--cs-font-size-xs); text-transform: uppercase; letter-spacing: var(--cs-letter-spacing-caps); color: var(--cs-color-text-muted); padding: 8px 10px 2px; }
53
59
  .cs-cmdk__item { display: flex; align-items: center; gap: 11px; inline-size: 100%; text-align: start; border: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); padding: 10px 12px; border-radius: var(--cs-radius-md); cursor: pointer; }
@@ -61,8 +61,33 @@ export function formatDate(d, lang) {
61
61
  }
62
62
  export function monthName(i, lang) { return lang === "vi" ? VI_MONTHS[i] : new Date(2000, i, 1).toLocaleDateString("en-US", { month: "long" }); }
63
63
  export function formatNumber(n, lang) { if (n == null || isNaN(n)) return ""; return new Intl.NumberFormat(lang === "vi" ? "vi-VN" : "en-US").format(n); }
64
- /** VN currency = "1.234.567 ₫"; EN = "$1,234,567". */
65
- export function formatCurrency(n, lang) {
64
+
65
+ /**
66
+ * Format a money amount. Currency is independent of display language when options are used.
67
+ *
68
+ * Call shapes (FIND-025):
69
+ * - Legacy: `formatCurrency(amount, "en"|"vi")` — preserves prior presentation
70
+ * (EN→USD-style `$1,234,567`; VI→`1.234.567 ₫`).
71
+ * - Preferred: `formatCurrency(amount, { currency, locale?, lang? })` —
72
+ * `Intl.NumberFormat(locale, { style: "currency", currency })`.
73
+ * `locale` defaults from `lang` (`vi`→`vi-VN`, else `en-US`).
74
+ */
75
+ export function formatCurrency(n, langOrOpts) {
66
76
  if (n == null || isNaN(n)) return "";
67
- return lang === "vi" ? new Intl.NumberFormat("vi-VN").format(n) + "\u00a0₫" : "$" + new Intl.NumberFormat("en-US").format(n);
77
+ const opts = langOrOpts && typeof langOrOpts === "object" ? langOrOpts : null;
78
+ if (opts && opts.currency) {
79
+ let locale = opts.locale;
80
+ if (!locale) {
81
+ locale = opts.lang === "vi" ? "vi-VN" : "en-US";
82
+ }
83
+ return new Intl.NumberFormat(locale, {
84
+ style: "currency",
85
+ currency: String(opts.currency).toUpperCase(),
86
+ currencyDisplay: "symbol",
87
+ }).format(Number(n));
88
+ }
89
+ const lang = typeof langOrOpts === "string" ? langOrOpts : (opts && opts.lang) || "en";
90
+ return lang === "vi"
91
+ ? new Intl.NumberFormat("vi-VN").format(n) + "\u00a0₫"
92
+ : "$" + new Intl.NumberFormat("en-US").format(n);
68
93
  }