@rojaostudio/ds 1.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 (291) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/brand/rojao-black-on-white.png +0 -0
  4. package/brand/rojao-black.png +0 -0
  5. package/brand/rojao-white-on-black.png +0 -0
  6. package/brand/rojao-white.png +0 -0
  7. package/dist/chunk-ORMEWXMH.js +37 -0
  8. package/dist/compat/generate.d.ts +6 -0
  9. package/dist/compat/generate.js +1 -0
  10. package/dist/compat/recipes.d.ts +1 -0
  11. package/dist/compat/recipes.js +1 -0
  12. package/dist/compat/themes.d.ts +1 -0
  13. package/dist/compat/themes.js +1 -0
  14. package/dist/compat/tokens.d.ts +1 -0
  15. package/dist/compat/tokens.js +1 -0
  16. package/dist/components/accordion.d.ts +35 -0
  17. package/dist/components/accordion.js +95 -0
  18. package/dist/components/alert.d.ts +24 -0
  19. package/dist/components/alert.js +72 -0
  20. package/dist/components/avatar.d.ts +45 -0
  21. package/dist/components/avatar.js +97 -0
  22. package/dist/components/badge.d.ts +45 -0
  23. package/dist/components/badge.js +114 -0
  24. package/dist/components/blocker-card.d.ts +42 -0
  25. package/dist/components/blocker-card.js +45 -0
  26. package/dist/components/bottom-sheet.d.ts +31 -0
  27. package/dist/components/bottom-sheet.js +120 -0
  28. package/dist/components/breadcrumb.d.ts +28 -0
  29. package/dist/components/breadcrumb.js +52 -0
  30. package/dist/components/button.d.ts +27 -0
  31. package/dist/components/button.js +124 -0
  32. package/dist/components/card.d.ts +27 -0
  33. package/dist/components/card.js +52 -0
  34. package/dist/components/chat-bubble.d.ts +16 -0
  35. package/dist/components/chat-bubble.js +55 -0
  36. package/dist/components/checkbox.d.ts +14 -0
  37. package/dist/components/checkbox.js +78 -0
  38. package/dist/components/chip-input.d.ts +26 -0
  39. package/dist/components/chip-input.js +182 -0
  40. package/dist/components/chips.d.ts +22 -0
  41. package/dist/components/chips.js +94 -0
  42. package/dist/components/choice-card.d.ts +16 -0
  43. package/dist/components/choice-card.js +60 -0
  44. package/dist/components/choice-carousel.d.ts +16 -0
  45. package/dist/components/choice-carousel.js +154 -0
  46. package/dist/components/choice-preview-card.d.ts +37 -0
  47. package/dist/components/choice-preview-card.js +39 -0
  48. package/dist/components/color-input.d.ts +20 -0
  49. package/dist/components/color-input.js +79 -0
  50. package/dist/components/combobox.d.ts +70 -0
  51. package/dist/components/combobox.js +213 -0
  52. package/dist/components/context-menu.d.ts +33 -0
  53. package/dist/components/context-menu.js +70 -0
  54. package/dist/components/copilot-hint.d.ts +18 -0
  55. package/dist/components/copilot-hint.js +63 -0
  56. package/dist/components/copy-field.d.ts +16 -0
  57. package/dist/components/copy-field.js +41 -0
  58. package/dist/components/currency-input.d.ts +32 -0
  59. package/dist/components/currency-input.js +138 -0
  60. package/dist/components/danger-zone.d.ts +20 -0
  61. package/dist/components/danger-zone.js +21 -0
  62. package/dist/components/data-table-header.d.ts +43 -0
  63. package/dist/components/data-table-header.js +205 -0
  64. package/dist/components/date-picker.d.ts +40 -0
  65. package/dist/components/date-picker.js +252 -0
  66. package/dist/components/divider.d.ts +20 -0
  67. package/dist/components/divider.js +47 -0
  68. package/dist/components/drawer.d.ts +26 -0
  69. package/dist/components/drawer.js +82 -0
  70. package/dist/components/dropzone.d.ts +19 -0
  71. package/dist/components/dropzone.js +65 -0
  72. package/dist/components/empty-state.d.ts +48 -0
  73. package/dist/components/empty-state.js +91 -0
  74. package/dist/components/fab.d.ts +38 -0
  75. package/dist/components/fab.js +100 -0
  76. package/dist/components/filter-chip.d.ts +54 -0
  77. package/dist/components/filter-chip.js +66 -0
  78. package/dist/components/floating-stepper.d.ts +44 -0
  79. package/dist/components/floating-stepper.js +53 -0
  80. package/dist/components/form-card-header.d.ts +13 -0
  81. package/dist/components/form-card-header.js +8 -0
  82. package/dist/components/icon-button.d.ts +17 -0
  83. package/dist/components/icon-button.js +80 -0
  84. package/dist/components/image-crop-modal.d.ts +59 -0
  85. package/dist/components/image-crop-modal.js +240 -0
  86. package/dist/components/image-upload.d.ts +72 -0
  87. package/dist/components/image-upload.js +271 -0
  88. package/dist/components/index.d.ts +85 -0
  89. package/dist/components/index.js +200 -0
  90. package/dist/components/input.d.ts +25 -0
  91. package/dist/components/input.js +136 -0
  92. package/dist/components/insight-card.d.ts +19 -0
  93. package/dist/components/insight-card.js +27 -0
  94. package/dist/components/label.d.ts +16 -0
  95. package/dist/components/label.js +43 -0
  96. package/dist/components/media-tile.d.ts +24 -0
  97. package/dist/components/media-tile.js +28 -0
  98. package/dist/components/menu.d.ts +50 -0
  99. package/dist/components/menu.js +80 -0
  100. package/dist/components/modal.d.ts +25 -0
  101. package/dist/components/modal.js +71 -0
  102. package/dist/components/notice.d.ts +50 -0
  103. package/dist/components/notice.js +103 -0
  104. package/dist/components/option-tile.d.ts +60 -0
  105. package/dist/components/option-tile.js +144 -0
  106. package/dist/components/page-shell.d.ts +29 -0
  107. package/dist/components/page-shell.js +36 -0
  108. package/dist/components/page-skeleton.d.ts +35 -0
  109. package/dist/components/page-skeleton.js +12 -0
  110. package/dist/components/page-tabs.d.ts +35 -0
  111. package/dist/components/page-tabs.js +55 -0
  112. package/dist/components/pagination.d.ts +31 -0
  113. package/dist/components/pagination.js +80 -0
  114. package/dist/components/paywall-banner.d.ts +37 -0
  115. package/dist/components/paywall-banner.js +42 -0
  116. package/dist/components/paywall.d.ts +44 -0
  117. package/dist/components/paywall.js +55 -0
  118. package/dist/components/phone-frame.d.ts +9 -0
  119. package/dist/components/phone-frame.js +18 -0
  120. package/dist/components/phone-input.d.ts +24 -0
  121. package/dist/components/phone-input.js +92 -0
  122. package/dist/components/pix-icon.d.ts +8 -0
  123. package/dist/components/pix-icon.js +24 -0
  124. package/dist/components/popover.d.ts +44 -0
  125. package/dist/components/popover.js +140 -0
  126. package/dist/components/pricing-card.d.ts +42 -0
  127. package/dist/components/pricing-card.js +29 -0
  128. package/dist/components/qr-display.d.ts +19 -0
  129. package/dist/components/qr-display.js +24 -0
  130. package/dist/components/radio.d.ts +33 -0
  131. package/dist/components/radio.js +97 -0
  132. package/dist/components/row-actions.d.ts +24 -0
  133. package/dist/components/row-actions.js +76 -0
  134. package/dist/components/saving-bar-context.d.ts +40 -0
  135. package/dist/components/saving-bar-context.js +125 -0
  136. package/dist/components/saving-bar.d.ts +18 -0
  137. package/dist/components/saving-bar.js +72 -0
  138. package/dist/components/search.d.ts +30 -0
  139. package/dist/components/search.js +81 -0
  140. package/dist/components/section-card.d.ts +14 -0
  141. package/dist/components/section-card.js +49 -0
  142. package/dist/components/section-header.d.ts +29 -0
  143. package/dist/components/section-header.js +7 -0
  144. package/dist/components/select.d.ts +21 -0
  145. package/dist/components/select.js +140 -0
  146. package/dist/components/selectable-card.d.ts +35 -0
  147. package/dist/components/selectable-card.js +27 -0
  148. package/dist/components/setting-row.d.ts +33 -0
  149. package/dist/components/setting-row.js +19 -0
  150. package/dist/components/settings-list.d.ts +25 -0
  151. package/dist/components/settings-list.js +22 -0
  152. package/dist/components/skeleton.d.ts +24 -0
  153. package/dist/components/skeleton.js +49 -0
  154. package/dist/components/slider.d.ts +32 -0
  155. package/dist/components/slider.js +79 -0
  156. package/dist/components/spinner.d.ts +14 -0
  157. package/dist/components/spinner.js +36 -0
  158. package/dist/components/step-progress.d.ts +12 -0
  159. package/dist/components/step-progress.js +24 -0
  160. package/dist/components/summary-bar.d.ts +31 -0
  161. package/dist/components/summary-bar.js +54 -0
  162. package/dist/components/table.d.ts +23 -0
  163. package/dist/components/table.js +80 -0
  164. package/dist/components/textarea.d.ts +21 -0
  165. package/dist/components/textarea.js +95 -0
  166. package/dist/components/themed.d.ts +36 -0
  167. package/dist/components/themed.js +22 -0
  168. package/dist/components/time-picker.d.ts +34 -0
  169. package/dist/components/time-picker.js +213 -0
  170. package/dist/components/toaster.d.ts +84 -0
  171. package/dist/components/toaster.js +284 -0
  172. package/dist/components/toggle-card-compact.d.ts +21 -0
  173. package/dist/components/toggle-card-compact.js +99 -0
  174. package/dist/components/toggle-card.d.ts +15 -0
  175. package/dist/components/toggle-card.js +76 -0
  176. package/dist/components/toggle-group.d.ts +67 -0
  177. package/dist/components/toggle-group.js +80 -0
  178. package/dist/components/toggle.d.ts +13 -0
  179. package/dist/components/toggle.js +64 -0
  180. package/dist/components/tooltip.d.ts +17 -0
  181. package/dist/components/tooltip.js +89 -0
  182. package/dist/components/typing-indicator.d.ts +8 -0
  183. package/dist/components/typing-indicator.js +27 -0
  184. package/dist/components/use-dismiss.d.ts +9 -0
  185. package/dist/components/use-dismiss.js +28 -0
  186. package/dist/components/use-focus-trap.d.ts +5 -0
  187. package/dist/components/use-focus-trap.js +54 -0
  188. package/dist/icons/index.d.ts +1 -0
  189. package/dist/icons/index.js +89 -0
  190. package/dist/targets/native/components/accordion.d.ts +18 -0
  191. package/dist/targets/native/components/accordion.js +122 -0
  192. package/dist/targets/native/components/alert.d.ts +16 -0
  193. package/dist/targets/native/components/alert.js +58 -0
  194. package/dist/targets/native/components/avatar.d.ts +25 -0
  195. package/dist/targets/native/components/avatar.js +88 -0
  196. package/dist/targets/native/components/badge.d.ts +27 -0
  197. package/dist/targets/native/components/badge.js +59 -0
  198. package/dist/targets/native/components/button.d.ts +18 -0
  199. package/dist/targets/native/components/button.js +84 -0
  200. package/dist/targets/native/components/card.d.ts +6 -0
  201. package/dist/targets/native/components/card.js +36 -0
  202. package/dist/targets/native/components/checkbox.d.ts +12 -0
  203. package/dist/targets/native/components/checkbox.js +59 -0
  204. package/dist/targets/native/components/chips.d.ts +17 -0
  205. package/dist/targets/native/components/chips.js +77 -0
  206. package/dist/targets/native/components/choice-card.d.ts +11 -0
  207. package/dist/targets/native/components/choice-card.js +52 -0
  208. package/dist/targets/native/components/context-menu.d.ts +11 -0
  209. package/dist/targets/native/components/context-menu.js +19 -0
  210. package/dist/targets/native/components/currency-input.d.ts +22 -0
  211. package/dist/targets/native/components/currency-input.js +105 -0
  212. package/dist/targets/native/components/danger-zone.d.ts +13 -0
  213. package/dist/targets/native/components/danger-zone.js +27 -0
  214. package/dist/targets/native/components/date-picker.d.ts +13 -0
  215. package/dist/targets/native/components/date-picker.js +185 -0
  216. package/dist/targets/native/components/divider.d.ts +9 -0
  217. package/dist/targets/native/components/divider.js +36 -0
  218. package/dist/targets/native/components/empty-state.d.ts +13 -0
  219. package/dist/targets/native/components/empty-state.js +10 -0
  220. package/dist/targets/native/components/fab.d.ts +25 -0
  221. package/dist/targets/native/components/fab.js +112 -0
  222. package/dist/targets/native/components/filter-chip.d.ts +22 -0
  223. package/dist/targets/native/components/filter-chip.js +70 -0
  224. package/dist/targets/native/components/form-field.d.ts +13 -0
  225. package/dist/targets/native/components/form-field.js +29 -0
  226. package/dist/targets/native/components/form-screen.d.ts +19 -0
  227. package/dist/targets/native/components/form-screen.js +88 -0
  228. package/dist/targets/native/components/google-icon.d.ts +8 -0
  229. package/dist/targets/native/components/google-icon.js +32 -0
  230. package/dist/targets/native/components/icon-button.d.ts +18 -0
  231. package/dist/targets/native/components/icon-button.js +80 -0
  232. package/dist/targets/native/components/icon.d.ts +11 -0
  233. package/dist/targets/native/components/icon.js +9 -0
  234. package/dist/targets/native/components/image-upload.d.ts +12 -0
  235. package/dist/targets/native/components/image-upload.js +95 -0
  236. package/dist/targets/native/components/index.d.ts +45 -0
  237. package/dist/targets/native/components/index.js +100 -0
  238. package/dist/targets/native/components/input.d.ts +17 -0
  239. package/dist/targets/native/components/input.js +103 -0
  240. package/dist/targets/native/components/list-item.d.ts +20 -0
  241. package/dist/targets/native/components/list-item.js +71 -0
  242. package/dist/targets/native/components/menu.d.ts +24 -0
  243. package/dist/targets/native/components/menu.js +71 -0
  244. package/dist/targets/native/components/modal.d.ts +15 -0
  245. package/dist/targets/native/components/modal.js +110 -0
  246. package/dist/targets/native/components/paywall-banner.d.ts +11 -0
  247. package/dist/targets/native/components/paywall-banner.js +46 -0
  248. package/dist/targets/native/components/paywall.d.ts +18 -0
  249. package/dist/targets/native/components/paywall.js +61 -0
  250. package/dist/targets/native/components/radio.d.ts +20 -0
  251. package/dist/targets/native/components/radio.js +71 -0
  252. package/dist/targets/native/components/search.d.ts +22 -0
  253. package/dist/targets/native/components/search.js +92 -0
  254. package/dist/targets/native/components/select.d.ts +17 -0
  255. package/dist/targets/native/components/select.js +86 -0
  256. package/dist/targets/native/components/sheet.d.ts +11 -0
  257. package/dist/targets/native/components/sheet.js +51 -0
  258. package/dist/targets/native/components/skeleton.d.ts +18 -0
  259. package/dist/targets/native/components/skeleton.js +52 -0
  260. package/dist/targets/native/components/slider.d.ts +18 -0
  261. package/dist/targets/native/components/slider.js +153 -0
  262. package/dist/targets/native/components/spinner.d.ts +7 -0
  263. package/dist/targets/native/components/spinner.js +10 -0
  264. package/dist/targets/native/components/stepper.d.ts +10 -0
  265. package/dist/targets/native/components/stepper.js +33 -0
  266. package/dist/targets/native/components/switch.d.ts +20 -0
  267. package/dist/targets/native/components/switch.js +68 -0
  268. package/dist/targets/native/components/text.d.ts +12 -0
  269. package/dist/targets/native/components/text.js +31 -0
  270. package/dist/targets/native/components/textarea.d.ts +13 -0
  271. package/dist/targets/native/components/textarea.js +92 -0
  272. package/dist/targets/native/components/theme.d.ts +18 -0
  273. package/dist/targets/native/components/theme.js +20 -0
  274. package/dist/targets/native/components/toaster.d.ts +35 -0
  275. package/dist/targets/native/components/toaster.js +159 -0
  276. package/dist/targets/native/fonts.d.ts +9 -0
  277. package/dist/targets/native/fonts.js +10 -0
  278. package/dist/targets/native/icons.d.ts +1 -0
  279. package/dist/targets/native/icons.js +1 -0
  280. package/dist/targets/native/index.d.ts +3 -0
  281. package/dist/targets/native/index.js +11 -0
  282. package/dist/targets/native/preset.cjs +69 -0
  283. package/dist/targets/native/resolve.d.ts +22 -0
  284. package/dist/targets/native/resolve.js +85 -0
  285. package/dist/targets/native/theme.css +118 -0
  286. package/dist/targets/native/theme.d.ts +117 -0
  287. package/dist/targets/native/theme.js +118 -0
  288. package/package.json +194 -0
  289. package/styles/_primitives.generated.css +284 -0
  290. package/styles/base.css +950 -0
  291. package/styles/themes/rojao.css +107 -0
@@ -0,0 +1,950 @@
1
+ /* ─────────────────────────────────────────────────────────────
2
+ ROJAO DS — base.css
3
+ Import this AFTER @import "tailwindcss" in each project:
4
+
5
+ @import "tailwindcss";
6
+ @import "@rojaostudio/ds/styles/base.css";
7
+
8
+ Then either override semantic vars in :root, or import a brand
9
+ theme that already references primitives:
10
+ @import "@rojaostudio/ds/styles/themes/taiq.css";
11
+
12
+ Primitives (--color-cream-900, --color-cobalt-700, etc) come from
13
+ _primitives.generated.css, which is built from tokens/index.ts.
14
+ Run `pnpm build:tokens` in the DS to regenerate.
15
+ ───────────────────────────────────────────────────────────── */
16
+
17
+ /* Primitives — auto-generated from tokens/index.ts */
18
+ @import "./_primitives.generated.css";
19
+
20
+ /* ── CSS Custom Properties — light (default, neutral theme) ── */
21
+ /* .ds-scope: qualquer wrapper que precise recalcular tokens de COMPONENTE (ex.
22
+ --option-tile-bg) sob um override local de token SEMÂNTICO (ex. --surface-default)
23
+ adota esta classe — var() dentro de custom property só resolve 1x, no elemento onde a
24
+ regra é casada; sem um seletor casando aqui, o token derivado herda o valor já resolvido
25
+ de :root e nunca recalcula (rojaostudio/rojao-ds#69). */
26
+ :root, .ds-scope {
27
+ /* Font — override per project; generic fallbacks here */
28
+ --font-family: sans-serif;
29
+ --font-family-mono: monospace;
30
+ --font-family-display: var(--font-family);
31
+
32
+ /* Brand — primary é a cor que pinta CTA, sidebar, marca. Override per project */
33
+ --brand-primary: #171717;
34
+ --brand-hover: #404040;
35
+ --brand-on-primary: #ffffff;
36
+ --brand-secondary: #ffffff;
37
+ --brand-on-secondary: #171717;
38
+ --brand-text: #171717; /* cor de marca legível como TEXTO sobre surface (AA) */
39
+
40
+ /* Brand accent — destaque (badge, link, focus). */
41
+ --brand-accent: #9c27b0; /* deep-purple/500 — override per project */
42
+ --brand-accent-light: #f3e5f5; /* deep-purple/50 */
43
+ --brand-on-accent: #ffffff;
44
+
45
+ /* Surface */
46
+ --surface-page: #fafafa;
47
+ --surface-default: #ffffff;
48
+ --surface-raised: #f5f5f5;
49
+ --surface-overlay: #171717;
50
+
51
+ /* Scrim atrás de overlays (Modal, Drawer, BottomSheet) — antes hardcoded bg-black/50 */
52
+ --overlay-scrim: var(--color-blackAlpha-500);
53
+
54
+ /* Shell — superfície escura permanente (sidebar, topbar, widgets sobre o shell).
55
+ Texto/borda "on-shell" são branco translúcido (sempre sobre fundo escuro),
56
+ então não mudam entre light/dark. Tema pode sobrescrever --surface-shell. */
57
+ --surface-shell: #0f1115;
58
+ --text-on-shell: #f4f4f5;
59
+ --text-on-shell-muted: color-mix(in srgb, #ffffff 60%, transparent);
60
+ --text-on-shell-subtle: color-mix(in srgb, #ffffff 32%, transparent);
61
+ --border-on-shell: color-mix(in srgb, #ffffff 12%, transparent);
62
+
63
+ /* Border */
64
+ --border-subtle: #f5f5f5;
65
+ --border-default: #e5e5e5;
66
+ --border-strong: #d4d4d4;
67
+ /* Borda de CONTROLE — 3:1 sobre a superfície (WCAG 1.4.11). As de cima são decoração
68
+ e ficam sutis de propósito; esta identifica o componente. Ver rojao-ds#87. */
69
+ --border-control: #737373;
70
+ --border-focus: #000000;
71
+
72
+ /* Text */
73
+ --text-primary: #171717;
74
+ --text-secondary: #404040;
75
+ /* 600, nao 500: sobre a --surface-raised (#f5f5f5) o #737373 da 4.35 e reprova. #109 */
76
+ --text-muted: #525252;
77
+ --text-disabled: #a3a3a3;
78
+ --text-inverse: #ffffff;
79
+ --text-placeholder: #525252; /* conteudo, nao isento — o #a3a3a3 dava 2.49 */
80
+ /* Superficie invertida — par do --text-inverse acima. O @theme inline exporta
81
+ --color-surface-invert, mas a origem nunca existiu aqui: bg-surface-invert nao
82
+ pintava nada e o par dava 1:1 (branco sobre transparente). Ver rojao-ds#93. */
83
+ --surface-invert: #171717;
84
+
85
+ /* Icon */
86
+ --icon-default: #262626;
87
+
88
+ /* State — disabled (alphas pra esmaecer sobre qualquer fundo)
89
+ Set padrão usa blackAlpha — pra superfícies CLARAS (paper, white, cream).
90
+ Pra superfícies ESCURAS (overlay, dark modal), usar --state-disabled-on-dark-*. */
91
+ --state-disabled-surface: var(--color-blackAlpha-50); /* 5% preto */
92
+ --state-disabled-text: var(--color-blackAlpha-400); /* 40% preto */
93
+ --state-disabled-border: var(--color-blackAlpha-100); /* 10% preto */
94
+
95
+ --state-disabled-on-dark-surface: var(--color-whiteAlpha-50); /* 5% branco */
96
+ --state-disabled-on-dark-text: var(--color-whiteAlpha-400); /* 40% branco */
97
+ --state-disabled-on-dark-border: var(--color-whiteAlpha-100); /* 10% branco */
98
+
99
+ /* ── Semantic feedback — 4 categorias (danger/success/warning/info)
100
+ × 4 tokens (forte / soft / border / text). Override por tema. ── */
101
+ /* Referenciam as paletas core (Rojão) — seguem a mecânica e flipam no dark.
102
+ -text aponta pro step que passa 4.5:1 SOBRE o -soft (medido nas cores Rojão). */
103
+ --danger: var(--color-red-500);
104
+ --danger-soft: var(--color-red-100);
105
+ --danger-border: var(--color-red-200);
106
+ --danger-text: var(--color-red-800); /* 10.7:1 on soft */
107
+
108
+ --success: var(--color-green-500);
109
+ --success-soft: var(--color-green-100);
110
+ --success-border: var(--color-green-200);
111
+ --success-text: var(--color-green-800); /* 10.1:1 on soft */
112
+
113
+ --warning: var(--color-amber-500);
114
+ --warning-soft: var(--color-amber-100);
115
+ --warning-border: var(--color-amber-200);
116
+ --warning-text: var(--color-amber-900); /* âmbar Rojão é dourado → 900 (4.6:1); 800 não passa */
117
+
118
+ --info: var(--color-blue-500);
119
+ --info-soft: var(--color-blue-100);
120
+ --info-border: var(--color-blue-200);
121
+ --info-text: var(--color-blue-800); /* 10.2:1 on soft */
122
+
123
+ /* ── Attention — escala de URGÊNCIA temporal (countdown/trial), 3 degraus de
124
+ intensidade crescente (low → medium → high). Diferente de warning, que é um
125
+ estado pontual: attention comunica "o tempo está correndo", subindo a saturação
126
+ do amarelo Rojão (yellow-50 → 100 → 200), nunca vermelho (não é erro, é oferta
127
+ com prazo). Texto SEMPRE quase-preto (neutral-900) — par amarelo+preto é o de
128
+ maior legibilidade que existe (~13:1, calibrado p/ baixa visão). Amarelo é claro
129
+ o bastante p/ NÃO flipar no dark: a faixa fica amarela nos dois modos. ── */
130
+ --attention-low-soft: var(--color-yellow-50);
131
+ --attention-low-border: var(--color-yellow-100);
132
+ --attention-low-text: var(--color-neutral-900); /* ~16:1 on soft */
133
+ --attention-medium-soft: var(--color-yellow-100);
134
+ --attention-medium-border: var(--color-yellow-200);
135
+ --attention-medium-text: var(--color-neutral-900); /* ~15:1 on soft */
136
+ --attention-high-soft: var(--color-yellow-200);
137
+ --attention-high-border: var(--color-yellow-300);
138
+ --attention-high-text: var(--color-neutral-900); /* ~13:1 on soft */
139
+ /* CTA sobre o banner: o fundo amarelo é FIXO (não flipa), então a ação também precisa
140
+ ser fixa — brand-primary viraria branco no dark e sumiria no amarelo. Escuro sólido
141
+ + texto claro; o outline usa -action como borda/texto. */
142
+ --attention-action: var(--color-neutral-900);
143
+ --attention-on-action: var(--color-white);
144
+
145
+ /* ── Avatar/monograma — paleta categórica DECORATIVA para placeholder
146
+ de produto/cliente sem foto: fundo soft + inicial em tom escuro (≥4.5:1).
147
+ O app escolhe o índice por hash do nome (cor estável por item). Evita
148
+ red/green (feedback) e amber/yellow (attention) para não confundir significado.
149
+ Flipa para tonalidades escuras no .dark. */
150
+ --avatar-1-bg: var(--color-blue-100); --avatar-1-fg: var(--color-blue-800);
151
+ --avatar-2-bg: var(--color-purple-100); --avatar-2-fg: var(--color-purple-800);
152
+ --avatar-3-bg: var(--color-teal-100); --avatar-3-fg: var(--color-teal-800);
153
+ --avatar-4-bg: var(--color-orange-100); --avatar-4-fg: var(--color-orange-800);
154
+ --avatar-5-bg: var(--color-pink-100); --avatar-5-fg: var(--color-pink-800);
155
+ --avatar-6-bg: var(--color-indigo-100); --avatar-6-fg: var(--color-indigo-800);
156
+
157
+ /* ── Data-viz: paleta categórica (gráficos/donuts). Okabe-Ito —
158
+ colorblind-safe, distinguível em light e dark. Override no .dark. ── */
159
+ --chart-1: #0072b2; /* azul */
160
+ --chart-2: #e69f00; /* laranja */
161
+ --chart-3: #009e73; /* verde */
162
+ --chart-4: #d55e00; /* vermelho-tijolo */
163
+ --chart-5: #cc79a7; /* roxo */
164
+ --chart-6: #56b4e9; /* azul-céu */
165
+
166
+ --neutral: var(--color-neutral-500);
167
+ --neutral-soft: var(--color-neutral-100);
168
+ --neutral-border: var(--color-neutral-200);
169
+ --neutral-text: var(--color-neutral-700); /* 9.4:1 on soft */
170
+
171
+ /* ── Aliases legados — apontam pros tokens unificados acima.
172
+ Migrar consumers gradualmente; os components do DS já usam os novos. ── */
173
+ --action-danger-fill: var(--danger);
174
+ --action-danger-fill-hover: var(--danger);
175
+ --action-danger-border: var(--danger);
176
+ --action-danger-text: var(--danger-text);
177
+ --action-danger-hover: var(--danger-soft);
178
+
179
+ /* @deprecated — use --danger/--success/--warning/--info diretamente.
180
+ --feedback-* são aliases mantidos por compat (só --insight-alert-* ainda os
181
+ consome); serão removidos na v1.0. NÃO usar em código novo. (Rojão) */
182
+ --feedback-danger: var(--danger);
183
+ --feedback-danger-badge: var(--danger-soft);
184
+ --feedback-danger-border: var(--danger-border);
185
+ --feedback-danger-text: var(--danger-text);
186
+
187
+ --feedback-success: var(--success);
188
+ --feedback-success-badge: var(--success-soft);
189
+ --feedback-success-border: var(--success-border);
190
+ --feedback-success-text: var(--success-text);
191
+
192
+ --feedback-warning: var(--warning);
193
+ --feedback-warning-badge: var(--warning-soft);
194
+ --feedback-warning-border: var(--warning-border);
195
+ --feedback-warning-text: var(--warning-text);
196
+
197
+ --feedback-info: var(--info);
198
+ --feedback-info-badge: var(--info-soft);
199
+ --feedback-info-border: var(--info-border);
200
+ --feedback-info-text: var(--info-text);
201
+
202
+ --status-active: var(--success);
203
+ --status-active-text: var(--success-text);
204
+ --status-pending: var(--warning);
205
+ --status-pending-text: var(--warning-text);
206
+ --status-error: var(--danger);
207
+ --status-error-text: var(--danger-text);
208
+ /* Inactive fundiu com --state-disabled-*. Tokens legados apontam pra lá. */
209
+ --status-inactive: var(--state-disabled-text);
210
+ --status-inactive-text: var(--state-disabled-text);
211
+
212
+ /* Radius */
213
+ --radius-control: 0.5rem; /* 8px */
214
+ --radius-card: 0.5rem; /* 8px */
215
+ --radius-avatar: var(--radius-control); /* herda control; temas com pill/square sobrescrevem */
216
+ --radius-badge: 9999px; /* full — px intencional */
217
+ --radius-tooltip: 0.5rem; /* 8px */
218
+ --radius-toast: 1rem; /* 16px */
219
+
220
+ /* Space — control */
221
+ --space-control-height-sm: 2rem; /* 32px */
222
+ --space-control-height-md: 2.5rem; /* 40px */
223
+ --space-control-height-lg: 3rem; /* 48px */
224
+ --space-control-padding-x-sm: 0.75rem; /* 12px */
225
+ --space-control-padding-x-md: 1rem; /* 16px */
226
+ --space-control-padding-x-lg: 1.25rem; /* 20px */
227
+ --space-control-padding-y-sm: 0.25rem; /* 4px */
228
+ --space-control-padding-y-md: 0.5rem; /* 8px */
229
+ --space-control-padding-y-lg: 0.75rem; /* 12px */
230
+ --space-control-gap-sm: 0.25rem; /* 4px */
231
+ --space-control-gap-md: 0.5rem; /* 8px */
232
+ --space-control-gap-lg: 0.5rem; /* 8px */
233
+
234
+ /* Typography — rem para WCAG 1.4.4; clamp() em textos de conteúdo para fluidez */
235
+ --font-size-caption: clamp(0.6875rem, 0.6875rem + 0.15vw, 0.75rem);
236
+ --font-size-label: clamp(0.75rem, 0.75rem + 0.2vw, 0.875rem);
237
+ --font-size-body: clamp(0.875rem, 0.875rem + 0.25vw, 1rem);
238
+ --font-size-button-sm: 0.75rem; /* botões: fixo para affordance consistente */
239
+ --font-size-button-md: 0.875rem;
240
+ --font-size-button-lg: 1rem;
241
+ --font-size-heading-sm: clamp(1rem, 1rem + 0.25vw, 1.125rem);
242
+ --font-size-heading-md: clamp(1.125rem, 1.125rem + 0.3vw, 1.25rem);
243
+ --font-size-heading-lg: clamp(1.375rem, 1.375rem + 0.4vw, 1.5rem);
244
+ /* Display — headlines de landing/hero. Responsivo (mobile → desktop) por padrão,
245
+ no lugar dos text-[Npx] fixos. Consumir: text-[length:var(--font-size-display-lg)]. */
246
+ --font-size-display-sm: clamp(2rem, 1.6rem + 2vw, 2.5rem); /* 32 → 40 */
247
+ --font-size-display-md: clamp(2.5rem, 1.8rem + 3.5vw, 3.5rem); /* 40 → 56 */
248
+ --font-size-display-lg: clamp(3rem, 2rem + 5vw, 4.5rem); /* 48 → 72 */
249
+ --font-size-display-xl: clamp(3.5rem, 2.2rem + 6.5vw, 5.5rem); /* 56 → 88 */
250
+
251
+ --font-weight-label: 400;
252
+ --font-weight-button: 500;
253
+ --font-weight-caption: 400;
254
+ --font-weight-heading: 600;
255
+
256
+ /* Eyebrow / overline — micro-rótulo uppercase de section headers (SectionHeader) */
257
+ --font-size-eyebrow: 0.6875rem; /* 11px — fixo: rótulo, não conteúdo */
258
+ --font-weight-eyebrow: 600;
259
+ --letter-spacing-eyebrow: 0.12em;
260
+
261
+ /* Line-height unitless — proporcional ao font-size do elemento */
262
+ --line-height-caption: 1.33;
263
+ --line-height-label: 1.43;
264
+ --line-height-body: 1.5;
265
+ --line-height-heading-sm: 1.5;
266
+ --line-height-heading-md: 1.6;
267
+
268
+ /*
269
+ * Component tokens — padrão de arquitetura
270
+ *
271
+ * Cada componente tem seus tokens definidos aqui com valores semânticos como defaults.
272
+ * Os themes (styles/themes/*.css) sobrescrevem APENAS os tokens cujo comportamento
273
+ * de marca desvia do semântico (ex: taiq dark usa zinc-100, não --brand-primary).
274
+ * Nunca referenciar primitivos diretamente aqui — sempre via vars semânticas.
275
+ */
276
+
277
+ /* FilterChip — component tokens */
278
+ --filter-chip-padding-x: 0.75rem; /* 12px */
279
+ --filter-chip-padding-y: 0.25rem; /* 4px */
280
+ --filter-chip-radius: 9999px;
281
+
282
+ --filter-chip-color-surface-inactive: var(--surface-default);
283
+ --filter-chip-color-surface-active: color-mix(in srgb, var(--brand-primary) 12%, transparent);
284
+ --filter-chip-color-surface-hover: var(--surface-raised);
285
+ --filter-chip-color-surface-disabled: var(--surface-default);
286
+
287
+ --filter-chip-color-stroke-inactive: var(--border-default);
288
+ --filter-chip-color-stroke-active: var(--brand-primary);
289
+ --filter-chip-color-stroke-hover: var(--border-strong);
290
+ --filter-chip-color-stroke-disabled: var(--border-default);
291
+
292
+ --filter-chip-color-text-inactive: var(--text-muted);
293
+ --filter-chip-color-text-active: var(--brand-primary);
294
+ --filter-chip-color-text-hover: var(--text-secondary);
295
+ --filter-chip-color-text-disabled: var(--text-disabled);
296
+
297
+ /* FilterChipGroup — component tokens */
298
+ --filter-chip-group-gap: var(--space-control-gap-md);
299
+
300
+ /* FAB — component tokens */
301
+ --fab-cta-bg: var(--brand-primary);
302
+ --fab-cta-bg-hover: var(--brand-hover);
303
+ --fab-cta-text: var(--brand-on-primary);
304
+
305
+ --fab-save-bg: var(--surface-overlay);
306
+ --fab-save-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.25), 0 8px 10px -6px rgb(0 0 0 / 0.1);
307
+ --fab-save-discard-border: color-mix(in srgb, var(--text-inverse) 30%, transparent);
308
+ --fab-save-discard-border-hover: color-mix(in srgb, var(--text-inverse) 50%, transparent);
309
+ --fab-save-discard-text: var(--text-disabled);
310
+ --fab-save-discard-text-hover: var(--text-inverse);
311
+ --fab-save-primary-bg: var(--brand-secondary);
312
+ --fab-save-primary-bg-hover: var(--surface-raised);
313
+ --fab-save-primary-text: var(--brand-on-secondary);
314
+
315
+ /* SavingBar — component tokens */
316
+ --saving-bar-bg: var(--surface-overlay);
317
+ --saving-bar-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.25), 0 8px 10px -6px rgb(0 0 0 / 0.1);
318
+ --saving-bar-message: var(--text-muted);
319
+ --saving-bar-discard-border: color-mix(in srgb, var(--text-inverse) 30%, transparent);
320
+ --saving-bar-discard-border-hover: color-mix(in srgb, var(--text-inverse) 50%, transparent);
321
+ --saving-bar-discard-text: var(--text-disabled);
322
+ --saving-bar-discard-text-hover: var(--text-inverse);
323
+ --saving-bar-save-bg: var(--brand-on-primary);
324
+ --saving-bar-save-bg-hover: color-mix(in srgb, var(--brand-on-primary) 85%, transparent);
325
+ --saving-bar-save-text: var(--brand-primary);
326
+
327
+ /* PageTabs — component tokens */
328
+ --page-tabs-bg: var(--surface-default);
329
+ --page-tabs-border: var(--border-default);
330
+ --page-tabs-text: var(--text-muted);
331
+ --page-tabs-text-hover: var(--text-secondary);
332
+ --page-tabs-text-active: var(--text-primary);
333
+ --page-tabs-indicator-active: var(--brand-primary);
334
+ --page-tabs-indicator-hover: var(--border-strong);
335
+ --page-tabs-count-bg: var(--surface-raised);
336
+ --page-tabs-count-text: var(--text-secondary);
337
+ --page-tabs-count-bg-active: var(--brand-primary);
338
+ --page-tabs-count-text-active: var(--brand-on-primary);
339
+ --page-tabs-soon-bg: var(--surface-raised);
340
+ --page-tabs-soon-text: var(--text-disabled);
341
+ --page-tabs-dot-bg: color-mix(in srgb, var(--status-active) 15%, transparent);
342
+ --page-tabs-dot-text: var(--status-active-text);
343
+ --page-tabs-dot-indicator: var(--status-active);
344
+
345
+ /* Form controls — active state color (toggle track, checkbox, radio).
346
+ Separate from brand-primary so themes can use a functional indicator
347
+ (e.g. green) instead of the brand accent color. */
348
+ --toggle-track-active: var(--brand-primary);
349
+
350
+ /* Selection fill — CTAs, filled pills, cart item selected, finalize button.
351
+ Decoupled from --brand-primary so themes can set black/white instead of
352
+ the brand accent color for interactive selections. */
353
+ --selection-fill-active: var(--brand-primary);
354
+ --selection-on-fill-active: var(--brand-on-primary);
355
+
356
+ /* ChoiceCard — component tokens */
357
+ --choice-card-bg: var(--surface-default);
358
+ --choice-card-bg-active: var(--brand-primary);
359
+ --choice-card-border: var(--border-default);
360
+ --choice-card-border-hover: var(--border-strong);
361
+ --choice-card-border-active: var(--brand-primary);
362
+ --choice-card-label: var(--text-primary);
363
+ --choice-card-label-active: var(--brand-on-primary);
364
+ --choice-card-description: var(--text-muted);
365
+ --choice-card-description-active: color-mix(in srgb, var(--brand-on-primary) 70%, transparent);
366
+ --choice-card-icon-bg: var(--surface-raised);
367
+ --choice-card-icon-bg-active: color-mix(in srgb, var(--brand-on-primary) 10%, transparent);
368
+ --choice-card-icon: var(--text-secondary);
369
+ --choice-card-icon-active: var(--brand-on-primary);
370
+ --choice-card-radio-border: var(--border-strong);
371
+ --choice-card-radio-border-active: var(--brand-on-primary);
372
+ --choice-card-radio-dot: var(--brand-on-primary);
373
+
374
+ /* OptionTile — grade de setores/sub-nichos do onboarding (#449).
375
+ MESMA FAMÍLIA visual do ChoiceCard (os dois single-choice): casca idle suave
376
+ (border-default, hover border-strong) e selecionado = fill SÓLIDO, derivado dos
377
+ tokens SEMÂNTICOS de seleção (--selection-fill-active/--selection-on-fill-active) —
378
+ temas que sobrescrevem a camada de seleção (ex. taiq dark → zinc-100) propagam pra
379
+ cá sem redeclarar cada token de componente. Baixa visão: a seleção é distinguível
380
+ por MAIS que cor (fill sólido de alto contraste + check redundante — o check
381
+ inverte: badge on-fill, glifo fill). Todo conteúdo sobre o fill ativo usa o par
382
+ on-fill, nunca tokens de superfície clara. */
383
+ --option-tile-bg: var(--surface-default);
384
+ --option-tile-bg-active: var(--selection-fill-active);
385
+ --option-tile-border: var(--border-default);
386
+ --option-tile-border-hover: var(--border-strong);
387
+ --option-tile-border-active: var(--selection-fill-active);
388
+ --option-tile-label: var(--text-primary);
389
+ --option-tile-label-active: var(--selection-on-fill-active);
390
+ --option-tile-icon-bg: var(--surface-raised);
391
+ --option-tile-icon: var(--text-secondary);
392
+ --option-tile-icon-bg-active: color-mix(in srgb, var(--selection-on-fill-active) 10%, transparent);
393
+ --option-tile-icon-active: var(--selection-on-fill-active);
394
+ --option-tile-check: var(--selection-on-fill-active);
395
+ --option-tile-check-icon: var(--selection-fill-active);
396
+
397
+ /* SectionCard — component tokens */
398
+ --section-card-border: var(--border-default);
399
+ --section-card-border-active: var(--brand-primary);
400
+ --section-card-header-bg-active: var(--brand-primary);
401
+ --section-card-header-bg-hover: var(--surface-raised);
402
+ --section-card-label: var(--text-secondary);
403
+ --section-card-label-active: var(--brand-on-primary);
404
+ --section-card-badge: var(--text-muted);
405
+ --section-card-badge-active: var(--text-disabled);
406
+ --section-card-chevron: var(--text-muted);
407
+ --section-card-divider: var(--border-subtle);
408
+
409
+ /* InsightCard — component tokens */
410
+ --insight-alert-border: var(--feedback-warning-border);
411
+ --insight-alert-bg: var(--feedback-warning-badge);
412
+ --insight-alert-badge-bg: var(--feedback-warning-badge);
413
+ --insight-alert-badge-text: var(--feedback-warning-text);
414
+
415
+ --insight-opportunity-border: var(--feedback-success-border);
416
+ --insight-opportunity-bg: var(--feedback-success-badge);
417
+ --insight-opportunity-badge-bg: var(--feedback-success-badge);
418
+ --insight-opportunity-badge-text: var(--feedback-success-text);
419
+
420
+ --insight-tip-border: var(--feedback-info-border);
421
+ --insight-tip-bg: var(--feedback-info-badge);
422
+ --insight-tip-badge-bg: var(--feedback-info-badge);
423
+ --insight-tip-badge-text: var(--feedback-info-text);
424
+
425
+ --insight-title-color: var(--text-primary);
426
+ --insight-description-color: var(--text-secondary);
427
+ --insight-potential-color: var(--text-muted);
428
+
429
+ --insight-action-bg: var(--surface-default);
430
+ --insight-action-bg-hover: var(--surface-raised);
431
+ --insight-action-border: var(--border-default);
432
+ --insight-action-text: var(--text-secondary);
433
+
434
+ /* SummaryBar — component tokens (reference semantic vars → flip with .dark automatically) */
435
+ --summary-bar-bg: var(--surface-default);
436
+ --summary-bar-border: var(--border-subtle);
437
+ --summary-bar-divider: var(--border-subtle);
438
+ --summary-bar-label: var(--text-muted);
439
+ --summary-bar-value: var(--text-primary);
440
+ --summary-bar-value-positive: var(--success-text);
441
+ --summary-bar-value-negative: var(--danger-text);
442
+ --summary-bar-value-warning: var(--warning-text);
443
+ --summary-bar-value-muted: var(--text-muted);
444
+
445
+ /* EmptyState — component tokens */
446
+ --empty-state-icon-color: var(--border-strong);
447
+ --empty-state-title-color: var(--text-primary);
448
+ --empty-state-description-color: var(--text-muted);
449
+ --empty-state-cta-bg: var(--brand-primary);
450
+ --empty-state-cta-bg-hover: var(--brand-hover);
451
+ --empty-state-cta-text: var(--brand-on-primary);
452
+
453
+ /* ChatBubble — component tokens */
454
+ --chat-bubble-bot-bg: color-mix(in srgb, var(--brand-primary) 12%, var(--surface-default));
455
+ --chat-bubble-bot-text: var(--text-primary);
456
+ --chat-bubble-user-bg: var(--surface-raised);
457
+ --chat-bubble-user-text: var(--text-primary);
458
+ --chat-bubble-radius-lg: 1rem; /* 16px */
459
+ --chat-bubble-radius-sm: 0.25rem; /* 4px */
460
+ --chat-bubble-padding-y: 0.75rem; /* 12px */
461
+ --chat-bubble-padding-x: 1rem; /* 16px */
462
+ --chat-bubble-max-width: 30rem; /* 480px */
463
+ --chat-bubble-editing-border: var(--brand-primary);
464
+ --chat-bubble-dim-opacity: 0.4;
465
+
466
+ /* TypingIndicator — component tokens */
467
+ --typing-dot-size: 0.375rem; /* 6px */
468
+ --typing-dot-gap: 0.25rem; /* 4px */
469
+ --typing-dot-color: var(--text-muted);
470
+
471
+ /* ChoiceCarousel — component tokens */
472
+ --choice-carousel-card-width-mobile: 10rem; /* 160px */
473
+ --choice-carousel-card-width-desktop: 12.5rem; /* 200px */
474
+ --choice-carousel-gap: 0.75rem; /* 12px */
475
+ --choice-carousel-chevron-bg: var(--surface-default);
476
+ --choice-carousel-chevron-border: var(--border-default);
477
+ --choice-carousel-chevron-text: var(--text-secondary);
478
+ --choice-carousel-chevron-bg-hover: var(--surface-raised);
479
+
480
+ /* Tooltip */
481
+ --tooltip-bg: #171717;
482
+ --tooltip-text: #ffffff;
483
+
484
+ /* Toast — notification card escura nos DOIS themes (inverse surface, como
485
+ Tooltip). Tint lateral e badge vêm das cores semânticas via color-mix. */
486
+ --toast-bg: #1e1e1e;
487
+ --toast-text: #fafafa;
488
+ --toast-text-muted: #a3a3a3;
489
+ --toast-border: color-mix(in srgb, white 10%, transparent);
490
+
491
+ /* Shadow */
492
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
493
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
494
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
495
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
496
+
497
+ /* Z-index */
498
+ --z-dropdown: 1000;
499
+ --z-modal: 1050;
500
+ --z-drawer: 1050;
501
+ --z-tooltip: 9999;
502
+
503
+ /* Opacity */
504
+ --opacity-disabled: 0.5;
505
+
506
+ /* Misc */
507
+ --size-icon: 1.5rem; /* 24px */
508
+ --border-width: 1px; /* px intencional — 1px é sempre 1 pixel físico */
509
+ }
510
+
511
+ /* ── Dark mode overrides ── */
512
+ /* .ds-scope.dark: mesma razão do .ds-scope acima, versão escura — ver #69. */
513
+ .dark, .ds-scope.dark {
514
+ color-scheme: dark;
515
+
516
+ /* Brand inverts in dark */
517
+ --brand-primary: #ffffff;
518
+ --brand-hover: #e5e5e5;
519
+ --brand-on-primary: #000000;
520
+ --brand-secondary: #000000;
521
+ --brand-on-secondary: #ffffff;
522
+
523
+ /* Surface */
524
+ --surface-page: #111111;
525
+ --surface-default: #1e1e1e;
526
+ --surface-raised: #262626;
527
+ --surface-overlay: #f5f5f5;
528
+
529
+ /* Border — alpha-based so they adapt to any surface underneath */
530
+ --border-subtle: color-mix(in srgb, white 8%, transparent);
531
+ --border-default: color-mix(in srgb, white 8%, transparent);
532
+ --border-strong: color-mix(in srgb, white 22%, transparent);
533
+ --border-control: color-mix(in srgb, white 40%, transparent);
534
+ --border-focus: #ffffff;
535
+
536
+ /* Text */
537
+ --text-primary: #fafafa; /* neutral[50] */
538
+ /* O muted estava no mesmo degrau do claro (#737373) e reprovava em AA nas TRES
539
+ superficies escuras — 3.98 / 3.52 / 3.19. Subir so ele o empataria com o
540
+ secondary, entao a escala inteira sobe um degrau e a hierarquia se mantem:
541
+ 12.74 / 11.25 / 10.21 no secondary e 7.49 / 6.61 / 6.00 no muted. rojao-ds#91 e #92. */
542
+ --text-secondary: #d4d4d4; /* neutral[300] */
543
+ --text-muted: #a3a3a3; /* neutral[400] */
544
+ --text-disabled: #525252; /* neutral[600] */
545
+ --text-inverse: #171717; /* neutral[900] */
546
+ --text-placeholder: #a3a3a3; /* neutral[400] — o #737373 dava 3.19 sobre a raised */
547
+ --surface-invert: #fafafa; /* neutral[50] — par do --text-inverse. rojao-ds#93 */
548
+
549
+ /* Icon */
550
+ --icon-default: #a3a3a3;
551
+
552
+ /* Data-viz — variantes mais claras p/ contraste ≥3:1 no fundo escuro */
553
+ --chart-1: #4da3db;
554
+ --chart-2: #f0b84d;
555
+ --chart-3: #3fc79a;
556
+ --chart-4: #f07a3d;
557
+ --chart-5: #dd9bc2;
558
+ --chart-6: #8fd0f2;
559
+
560
+ /* Action */
561
+ /* Action — danger */
562
+ --action-danger-fill: #ef4444;
563
+ --action-danger-fill-hover: #dc2626;
564
+ --action-danger-border: #f87171;
565
+ --action-danger-text: #f87171;
566
+ --action-danger-hover: rgb(220 38 38 / 0.1);
567
+
568
+ /* State — disabled */
569
+ --state-disabled-surface: var(--surface-default);
570
+ --state-disabled-text: var(--text-disabled);
571
+ --state-disabled-border: var(--border-default);
572
+
573
+ /* Semantic feedback — dark (transparent overlay on dark surface) */
574
+ --danger-soft: color-mix(in srgb, var(--color-red-500) 20%, transparent);
575
+ --danger-border: color-mix(in srgb, var(--color-red-500) 40%, transparent);
576
+ --danger-text: var(--color-red-200);
577
+
578
+ --success-soft: color-mix(in srgb, var(--color-green-500) 20%, transparent);
579
+ --success-border: color-mix(in srgb, var(--color-green-500) 40%, transparent);
580
+ --success-text: var(--color-green-200);
581
+
582
+ --warning-soft: color-mix(in srgb, var(--color-amber-500) 20%, transparent);
583
+ --warning-border: color-mix(in srgb, var(--color-amber-500) 40%, transparent);
584
+ --warning-text: var(--color-amber-200);
585
+
586
+ --info-soft: color-mix(in srgb, var(--color-blue-500) 20%, transparent);
587
+ --info-border: color-mix(in srgb, var(--color-blue-500) 40%, transparent);
588
+ --info-text: var(--color-blue-200);
589
+
590
+ /* Attention NÃO flipa no dark: amarelo+preto é legível em qualquer tema (faixa de
591
+ advertência). Herda os valores do :root acima — sem override aqui de propósito. */
592
+
593
+ /* Avatar/monograma — tonalidades escuras para contraste ≥4.5:1 sobre fundo escuro */
594
+ --avatar-1-bg: var(--color-blue-900); --avatar-1-fg: var(--color-blue-200);
595
+ --avatar-2-bg: var(--color-purple-900); --avatar-2-fg: var(--color-purple-200);
596
+ --avatar-3-bg: var(--color-teal-900); --avatar-3-fg: var(--color-teal-200);
597
+ --avatar-4-bg: var(--color-orange-900); --avatar-4-fg: var(--color-orange-200);
598
+ --avatar-5-bg: var(--color-pink-900); --avatar-5-fg: var(--color-pink-200);
599
+ --avatar-6-bg: var(--color-indigo-900); --avatar-6-fg: var(--color-indigo-200);
600
+
601
+ /* Feedback legacy aliases — dark (kept for compat, mirrors semantic tokens above) */
602
+ --feedback-danger: #f44336;
603
+ --feedback-danger-badge: rgb(244 67 54 / 0.2);
604
+ --feedback-danger-border: rgb(244 67 54 / 0.4);
605
+ --feedback-danger-text: #ef9a9a;
606
+
607
+ --feedback-success: #4caf50;
608
+ --feedback-success-badge: rgb(76 175 80 / 0.2);
609
+ --feedback-success-border: rgb(76 175 80 / 0.4);
610
+ --feedback-success-text: #a5d6a7;
611
+
612
+ --feedback-warning: #ffc107;
613
+ --feedback-warning-badge: rgb(255 193 7 / 0.2);
614
+ --feedback-warning-border: rgb(255 193 7 / 0.4);
615
+ --feedback-warning-text: #ffe082;
616
+
617
+ --feedback-info: #2196f3;
618
+ --feedback-info-badge: rgb(33 150 243 / 0.2);
619
+ --feedback-info-border: rgb(33 150 243 / 0.4);
620
+ --feedback-info-text: #90caf9;
621
+
622
+ /* Status — unchanged in dark */
623
+
624
+ /* Tooltip — dark (inverted: light bg on dark surface) */
625
+ --tooltip-bg: #f5f5f5;
626
+ --tooltip-text: #171717;
627
+
628
+ /* Toast — continua escuro, mas um degrau acima das surfaces escuras */
629
+ --toast-bg: #262626;
630
+
631
+ /* ChatBubble — dark */
632
+ --chat-bubble-bot-bg: color-mix(in srgb, var(--brand-primary) 18%, var(--surface-raised));
633
+ --chat-bubble-user-bg: var(--surface-raised);
634
+ }
635
+
636
+ /* Headers usam a fonte display do tema atual (cai pra --font-family se theme
637
+ não definiu display). Aplicado em cascata pra qualquer h1-h6 ou elemento
638
+ com classe .font-display. Components customizados podem sobrescrever. */
639
+ h1, h2, h3, h4, h5, h6 {
640
+ font-family: var(--font-family-display, var(--font-family));
641
+ }
642
+
643
+ /* TypingIndicator dot animation */
644
+ @keyframes rojao-typing-pulse {
645
+ 0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
646
+ 30% { opacity: 1; transform: translateY(-2px); }
647
+ }
648
+
649
+ /* Slider — esconde track nativo (visual é via div), customiza thumb */
650
+ .rojao-slider {
651
+ height: var(--rojao-slider-thumb-size);
652
+ }
653
+ .rojao-slider::-webkit-slider-runnable-track {
654
+ background: transparent;
655
+ height: var(--rojao-slider-track-h);
656
+ }
657
+ .rojao-slider::-moz-range-track {
658
+ background: transparent;
659
+ height: var(--rojao-slider-track-h);
660
+ }
661
+ .rojao-slider::-webkit-slider-thumb {
662
+ -webkit-appearance: none;
663
+ appearance: none;
664
+ width: var(--rojao-slider-thumb-size);
665
+ height: var(--rojao-slider-thumb-size);
666
+ border-radius: 9999px;
667
+ background: var(--brand-primary);
668
+ border: 2px solid var(--surface-default);
669
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);
670
+ cursor: pointer;
671
+ margin-top: calc((var(--rojao-slider-track-h) - var(--rojao-slider-thumb-size)) / 2);
672
+ position: relative;
673
+ z-index: 2;
674
+ }
675
+ .rojao-slider::-moz-range-thumb {
676
+ width: var(--rojao-slider-thumb-size);
677
+ height: var(--rojao-slider-thumb-size);
678
+ border-radius: 9999px;
679
+ background: var(--brand-primary);
680
+ border: 2px solid var(--surface-default);
681
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);
682
+ cursor: pointer;
683
+ }
684
+ .rojao-slider:focus-visible::-webkit-slider-thumb {
685
+ outline: 2px solid var(--border-focus);
686
+ outline-offset: 2px;
687
+ }
688
+ .rojao-slider:focus-visible::-moz-range-thumb {
689
+ outline: 2px solid var(--border-focus);
690
+ outline-offset: 2px;
691
+ }
692
+
693
+ /* BottomSheet — slide-up + backdrop fade */
694
+ @keyframes rojao-bottom-sheet-slide-up {
695
+ from { transform: translateY(100%); }
696
+ to { transform: translateY(0); }
697
+ }
698
+ @keyframes rojao-bottom-sheet-fade-in {
699
+ from { opacity: 0; }
700
+ to { opacity: 1; }
701
+ }
702
+ .rojao-bottom-sheet--enter { animation: rojao-bottom-sheet-slide-up 250ms cubic-bezier(0.16, 1, 0.3, 1); }
703
+ .rojao-bottom-sheet--backdrop-enter { animation: rojao-bottom-sheet-fade-in 200ms ease-out; }
704
+ @media (prefers-reduced-motion: reduce) {
705
+ .rojao-bottom-sheet--enter, .rojao-bottom-sheet--backdrop-enter { animation: none; }
706
+ }
707
+
708
+ /* Toaster — Material 3 motion (150ms ease-out enter, 75ms ease-in exit) */
709
+ @keyframes rojao-toast-enter-bottom {
710
+ from { opacity: 0; transform: translateY(20px); }
711
+ to { opacity: 1; transform: translateY(0); }
712
+ }
713
+ @keyframes rojao-toast-exit-bottom {
714
+ from { opacity: 1; transform: translateY(0); }
715
+ to { opacity: 0; transform: translateY(20px); }
716
+ }
717
+ @keyframes rojao-toast-enter-top {
718
+ from { opacity: 0; transform: translateY(-20px); }
719
+ to { opacity: 1; transform: translateY(0); }
720
+ }
721
+ @keyframes rojao-toast-exit-top {
722
+ from { opacity: 1; transform: translateY(0); }
723
+ to { opacity: 0; transform: translateY(-20px); }
724
+ }
725
+ .rojao-toast--enter-bottom { animation: rojao-toast-enter-bottom 150ms ease-out; }
726
+ .rojao-toast--enter-top { animation: rojao-toast-enter-top 150ms ease-out; }
727
+ .rojao-toast--exit-bottom { animation: rojao-toast-exit-bottom 75ms ease-in forwards; }
728
+ .rojao-toast--exit-top { animation: rojao-toast-exit-top 75ms ease-in forwards; }
729
+ @media (prefers-reduced-motion: reduce) {
730
+ .rojao-toast--enter-top, .rojao-toast--enter-bottom,
731
+ .rojao-toast--exit-top, .rojao-toast--exit-bottom { animation: none; }
732
+ }
733
+
734
+ /* ── Control size utilities — h-control-sm/md/lg, size-control-sm/md/lg ── */
735
+ @utility h-control-sm { height: var(--space-control-height-sm); }
736
+ @utility h-control-md { height: var(--space-control-height-md); }
737
+ @utility h-control-lg { height: var(--space-control-height-lg); }
738
+ @utility size-control-sm { width: var(--space-control-height-sm); height: var(--space-control-height-sm); }
739
+ @utility size-control-md { width: var(--space-control-height-md); height: var(--space-control-height-md); }
740
+ @utility size-control-lg { width: var(--space-control-height-lg); height: var(--space-control-height-lg); }
741
+
742
+ /* ── Semantic text styles — the per-brand editable type layer ──────────────
743
+ Components use these instead of the raw Tailwind scale (text-sm/text-base),
744
+ so a brand's type override (--font-size-*) propagates. Defaults match the raw
745
+ scale 1:1 (caption=12=xs, label=14=sm, body=16=base, heading-sm=18=lg…).
746
+ Weight stays on the component (font-medium etc.) to avoid conflicts. */
747
+ @utility text-caption { font-size: var(--font-size-caption); line-height: var(--line-height-caption); }
748
+ @utility text-label { font-size: var(--font-size-label); line-height: var(--line-height-label); }
749
+ @utility text-body { font-size: var(--font-size-body); line-height: var(--line-height-body); }
750
+ @utility text-button-sm { font-size: var(--font-size-button-sm); line-height: var(--line-height-caption); }
751
+ @utility text-button-md { font-size: var(--font-size-button-md); line-height: var(--line-height-label); }
752
+ @utility text-button-lg { font-size: var(--font-size-button-lg); line-height: var(--line-height-body); }
753
+ @utility text-heading-sm { font-size: var(--font-size-heading-sm); line-height: var(--line-height-heading-sm); }
754
+ @utility text-heading-md { font-size: var(--font-size-heading-md); line-height: var(--line-height-heading-md); }
755
+ @utility text-heading-lg { font-size: var(--font-size-heading-lg); line-height: 1.25; }
756
+
757
+ /* ── @theme — exporta utilities Tailwind a partir das CSS vars ── */
758
+ @theme inline {
759
+ /* Font */
760
+ --font-sans: var(--font-family);
761
+ --font-mono: var(--font-family-mono);
762
+ --font-display: var(--font-family-display, var(--font-family));
763
+ /* editorial: serifa de marketing/landing (cai pra display, depois sans). Gera font-editorial. */
764
+ --font-editorial: var(--font-family-editorial, var(--font-family-display, var(--font-family)));
765
+
766
+ /* Brand */
767
+ --color-selection-fill-active: var(--selection-fill-active);
768
+ --color-selection-on-fill-active: var(--selection-on-fill-active);
769
+
770
+ --color-brand-primary: var(--brand-primary);
771
+ --color-brand-hover: var(--brand-hover);
772
+ --color-brand-on-primary: var(--brand-on-primary);
773
+ --color-brand-secondary: var(--brand-secondary);
774
+ --color-brand-on-secondary: var(--brand-on-secondary);
775
+
776
+ /* Brand accent */
777
+ --color-brand-accent: var(--brand-accent);
778
+ --color-brand-accent-light: var(--brand-accent-light);
779
+ --color-brand-on-accent: var(--brand-on-accent);
780
+
781
+ /* Surface */
782
+ --color-surface-page: var(--surface-page);
783
+ --color-surface-default: var(--surface-default);
784
+ --color-surface-raised: var(--surface-raised);
785
+ --color-surface-overlay: var(--surface-overlay);
786
+ --color-surface-invert: var(--surface-invert);
787
+ /* Shell: --color-on-shell gera text-on-shell + bg-on-shell; -line gera border-on-shell-line.
788
+ (Tailwind v4: `--color-{nome}` vira utilities `text-{nome}`/`bg-{nome}`/`border-{nome}`.) */
789
+ --color-surface-shell: var(--surface-shell);
790
+ --color-on-shell: var(--text-on-shell);
791
+ --color-on-shell-muted: var(--text-on-shell-muted);
792
+ --color-on-shell-subtle: var(--text-on-shell-subtle);
793
+ --color-on-shell-line: var(--border-on-shell);
794
+
795
+ /* Stroke (border colors) */
796
+ --color-stroke-subtle: var(--border-subtle);
797
+ --color-stroke-default: var(--border-default);
798
+ --color-stroke-strong: var(--border-strong);
799
+ --color-stroke-control: var(--border-control);
800
+ --color-stroke-focus: var(--border-focus);
801
+
802
+ /* Fg (foreground / text colors) */
803
+ --color-fg-primary: var(--text-primary);
804
+ --color-fg-secondary: var(--text-secondary);
805
+ --color-fg-muted: var(--text-muted);
806
+ --color-fg-disabled: var(--text-disabled);
807
+ --color-fg-inverse: var(--text-inverse);
808
+ --color-fg-placeholder: var(--text-placeholder);
809
+
810
+ /* Icon */
811
+ --color-icon-default: var(--icon-default);
812
+
813
+ /* Action */
814
+ /* Action — danger */
815
+ --color-action-danger-fill: var(--action-danger-fill);
816
+ --color-action-danger-fill-hover: var(--action-danger-fill-hover);
817
+ --color-action-danger-border: var(--action-danger-border);
818
+ --color-action-danger-text: var(--action-danger-text);
819
+ --color-action-danger-hover: var(--action-danger-hover);
820
+
821
+ /* State — disabled */
822
+ --color-state-disabled-surface: var(--state-disabled-surface);
823
+ --color-state-disabled-text: var(--state-disabled-text);
824
+ --color-state-disabled-border: var(--state-disabled-border);
825
+
826
+ --color-state-disabled-on-dark-surface: var(--state-disabled-on-dark-surface);
827
+ --color-state-disabled-on-dark-text: var(--state-disabled-on-dark-text);
828
+ --color-state-disabled-on-dark-border: var(--state-disabled-on-dark-border);
829
+
830
+ /* Semantic feedback (unificado: danger/success/warning/info) */
831
+ --color-danger: var(--danger);
832
+ --color-danger-soft: var(--danger-soft);
833
+ --color-danger-border: var(--danger-border);
834
+ --color-danger-text: var(--danger-text);
835
+
836
+ --color-success: var(--success);
837
+ --color-success-soft: var(--success-soft);
838
+ --color-success-border: var(--success-border);
839
+ --color-success-text: var(--success-text);
840
+
841
+ --color-warning: var(--warning);
842
+ --color-warning-soft: var(--warning-soft);
843
+ --color-warning-border: var(--warning-border);
844
+ --color-warning-text: var(--warning-text);
845
+
846
+ --color-info: var(--info);
847
+ --color-info-soft: var(--info-soft);
848
+ --color-info-border: var(--info-border);
849
+ --color-info-text: var(--info-text);
850
+
851
+ /* Attention — escala de urgência (countdown/trial). Gera bg-attention-{low,medium,high}-soft,
852
+ text-attention-*-text, border-attention-*-border. 3 fundos amarelos + texto quase-preto. */
853
+ --color-attention-low-soft: var(--attention-low-soft);
854
+ --color-attention-low-border: var(--attention-low-border);
855
+ --color-attention-low-text: var(--attention-low-text);
856
+ --color-attention-medium-soft: var(--attention-medium-soft);
857
+ --color-attention-medium-border: var(--attention-medium-border);
858
+ --color-attention-medium-text: var(--attention-medium-text);
859
+ --color-attention-high-soft: var(--attention-high-soft);
860
+ --color-attention-high-border: var(--attention-high-border);
861
+ --color-attention-high-text: var(--attention-high-text);
862
+ --color-attention-action: var(--attention-action);
863
+ --color-attention-on-action: var(--attention-on-action);
864
+
865
+ /* Avatar/monograma — bg-avatar-1, text-avatar-1-fg, …, até avatar-6 */
866
+ --color-avatar-1-bg: var(--avatar-1-bg); --color-avatar-1-fg: var(--avatar-1-fg);
867
+ --color-avatar-2-bg: var(--avatar-2-bg); --color-avatar-2-fg: var(--avatar-2-fg);
868
+ --color-avatar-3-bg: var(--avatar-3-bg); --color-avatar-3-fg: var(--avatar-3-fg);
869
+ --color-avatar-4-bg: var(--avatar-4-bg); --color-avatar-4-fg: var(--avatar-4-fg);
870
+ --color-avatar-5-bg: var(--avatar-5-bg); --color-avatar-5-fg: var(--avatar-5-fg);
871
+ --color-avatar-6-bg: var(--avatar-6-bg); --color-avatar-6-fg: var(--avatar-6-fg);
872
+
873
+ /* Data-viz categórica (gráficos) — bg-chart-1, text-chart-1, … */
874
+ --color-chart-1: var(--chart-1);
875
+ --color-chart-2: var(--chart-2);
876
+ --color-chart-3: var(--chart-3);
877
+ --color-chart-4: var(--chart-4);
878
+ --color-chart-5: var(--chart-5);
879
+ --color-chart-6: var(--chart-6);
880
+
881
+ --color-neutral: var(--neutral);
882
+ --color-neutral-soft: var(--neutral-soft);
883
+ --color-neutral-border: var(--neutral-border);
884
+ --color-neutral-text: var(--neutral-text);
885
+
886
+ /* Legacy feedback aliases (mantém compat enquanto migra consumers) */
887
+ --color-feedback-danger: var(--feedback-danger);
888
+ --color-feedback-danger-badge: var(--feedback-danger-badge);
889
+ --color-feedback-danger-border: var(--feedback-danger-border);
890
+ --color-feedback-danger-text: var(--feedback-danger-text);
891
+
892
+ --color-feedback-success: var(--feedback-success);
893
+ --color-feedback-success-badge: var(--feedback-success-badge);
894
+ --color-feedback-success-border: var(--feedback-success-border);
895
+ --color-feedback-success-text: var(--feedback-success-text);
896
+
897
+ --color-feedback-warning: var(--feedback-warning);
898
+ --color-feedback-warning-badge: var(--feedback-warning-badge);
899
+ --color-feedback-warning-border: var(--feedback-warning-border);
900
+ --color-feedback-warning-text: var(--feedback-warning-text);
901
+
902
+ --color-feedback-info: var(--feedback-info);
903
+ --color-feedback-info-badge: var(--feedback-info-badge);
904
+ --color-feedback-info-border: var(--feedback-info-border);
905
+ --color-feedback-info-text: var(--feedback-info-text);
906
+
907
+ /* Status */
908
+ --color-status-active: var(--status-active);
909
+ --color-status-active-text: var(--status-active-text);
910
+ --color-status-pending: var(--status-pending);
911
+ --color-status-pending-text: var(--status-pending-text);
912
+ --color-status-error: var(--status-error);
913
+ --color-status-error-text: var(--status-error-text);
914
+ --color-status-inactive: var(--status-inactive);
915
+ --color-status-inactive-text: var(--status-inactive-text);
916
+ }
917
+
918
+ /**
919
+ * Foco visível — o padrão do sistema, e não decisão de cada produto.
920
+ *
921
+ * Até 13/08/2026 o DS não definia foco em lugar nenhum além do slider. Todo
922
+ * produto que o consome herdava o outline do navegador, que qualquer `border`
923
+ * ou `rounded` acaba encobrindo — e um painel inteiro navegado por teclado sem
924
+ * saber onde se está viola o 2.4.7 (WCAG AA) por omissão do sistema, não por
925
+ * descuido de quem consome.
926
+ *
927
+ * `:focus-visible` e não `:focus`: o anel aparece para quem navega por teclado
928
+ * e não para quem clica com o mouse, que é a diferença entre indicar e poluir.
929
+ *
930
+ * O `offset` existe para o anel não encostar na borda do próprio controle —
931
+ * sem ele, num botão com borda da mesma família de cor, o anel some dentro da
932
+ * borda. E ele é desenhado com a cor da superfície, então funciona igual sobre
933
+ * fundo claro e sobre o escuro do chrome.
934
+ */
935
+ @layer base {
936
+ :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
937
+ outline: 2px solid var(--border-focus);
938
+ outline-offset: 2px;
939
+ border-radius: inherit;
940
+ }
941
+
942
+ /**
943
+ * Quem já resolve o próprio foco fica de fora: `:where()` tem
944
+ * especificidade zero, então qualquer regra do componente vence esta sem
945
+ * precisar de `!important`.
946
+ */
947
+ :where(a, button, input, select, textarea, summary, [tabindex]):focus:not(:focus-visible) {
948
+ outline: none;
949
+ }
950
+ }