@antadesign/anta 0.1.1-dev.5 → 0.1.1-dev.7

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 (239) hide show
  1. package/README.md +15 -2
  2. package/dist/components/Button.d.ts +113 -0
  3. package/dist/components/Button.js +100 -0
  4. package/dist/components/Button.module.css +2 -0
  5. package/dist/components/Icon.d.ts +2 -1
  6. package/dist/components/Progress.d.ts +4 -2
  7. package/dist/components/Sticker.d.ts +31 -0
  8. package/dist/components/Sticker.js +17 -0
  9. package/dist/components/StickerAnimated.d.ts +23 -0
  10. package/dist/components/StickerAnimated.js +28 -0
  11. package/dist/components/Text.d.ts +6 -2
  12. package/dist/components/Text.js +2 -1
  13. package/dist/components/Title.d.ts +43 -0
  14. package/dist/components/Title.js +20 -0
  15. package/dist/components/__generated__/stickers/angry-animated.d.ts +3 -0
  16. package/dist/components/__generated__/stickers/angry-animated.js +7 -0
  17. package/dist/components/__generated__/stickers/angry.d.ts +3 -0
  18. package/dist/components/__generated__/stickers/angry.js +7 -0
  19. package/dist/components/__generated__/stickers/ask-animated.d.ts +3 -0
  20. package/dist/components/__generated__/stickers/ask-animated.js +7 -0
  21. package/dist/components/__generated__/stickers/ask.d.ts +3 -0
  22. package/dist/components/__generated__/stickers/ask.js +7 -0
  23. package/dist/components/__generated__/stickers/balance-animated.d.ts +3 -0
  24. package/dist/components/__generated__/stickers/balance-animated.js +7 -0
  25. package/dist/components/__generated__/stickers/balance.d.ts +3 -0
  26. package/dist/components/__generated__/stickers/balance.js +7 -0
  27. package/dist/components/__generated__/stickers/butterfly-animated.d.ts +3 -0
  28. package/dist/components/__generated__/stickers/butterfly-animated.js +7 -0
  29. package/dist/components/__generated__/stickers/butterfly-snake-animated.d.ts +3 -0
  30. package/dist/components/__generated__/stickers/butterfly-snake-animated.js +7 -0
  31. package/dist/components/__generated__/stickers/butterfly-snake.d.ts +3 -0
  32. package/dist/components/__generated__/stickers/butterfly-snake.js +7 -0
  33. package/dist/components/__generated__/stickers/butterfly.d.ts +3 -0
  34. package/dist/components/__generated__/stickers/butterfly.js +7 -0
  35. package/dist/components/__generated__/stickers/catch-animated.d.ts +3 -0
  36. package/dist/components/__generated__/stickers/catch-animated.js +7 -0
  37. package/dist/components/__generated__/stickers/catch.d.ts +3 -0
  38. package/dist/components/__generated__/stickers/catch.js +7 -0
  39. package/dist/components/__generated__/stickers/clap-animated.d.ts +3 -0
  40. package/dist/components/__generated__/stickers/clap-animated.js +7 -0
  41. package/dist/components/__generated__/stickers/clap.d.ts +3 -0
  42. package/dist/components/__generated__/stickers/clap.js +7 -0
  43. package/dist/components/__generated__/stickers/coding-animated.d.ts +3 -0
  44. package/dist/components/__generated__/stickers/coding-animated.js +7 -0
  45. package/dist/components/__generated__/stickers/coding.d.ts +3 -0
  46. package/dist/components/__generated__/stickers/coding.js +7 -0
  47. package/dist/components/__generated__/stickers/cowboy-animated.d.ts +3 -0
  48. package/dist/components/__generated__/stickers/cowboy-animated.js +7 -0
  49. package/dist/components/__generated__/stickers/cowboy.d.ts +3 -0
  50. package/dist/components/__generated__/stickers/cowboy.js +7 -0
  51. package/dist/components/__generated__/stickers/dance-animated.d.ts +3 -0
  52. package/dist/components/__generated__/stickers/dance-animated.js +7 -0
  53. package/dist/components/__generated__/stickers/dance.d.ts +3 -0
  54. package/dist/components/__generated__/stickers/dance.js +7 -0
  55. package/dist/components/__generated__/stickers/detective-animated.d.ts +3 -0
  56. package/dist/components/__generated__/stickers/detective-animated.js +7 -0
  57. package/dist/components/__generated__/stickers/detective.d.ts +3 -0
  58. package/dist/components/__generated__/stickers/detective.js +7 -0
  59. package/dist/components/__generated__/stickers/disapprove-animated.d.ts +3 -0
  60. package/dist/components/__generated__/stickers/disapprove-animated.js +7 -0
  61. package/dist/components/__generated__/stickers/disapprove.d.ts +3 -0
  62. package/dist/components/__generated__/stickers/disapprove.js +7 -0
  63. package/dist/components/__generated__/stickers/distracted-animated.d.ts +3 -0
  64. package/dist/components/__generated__/stickers/distracted-animated.js +7 -0
  65. package/dist/components/__generated__/stickers/distracted.d.ts +3 -0
  66. package/dist/components/__generated__/stickers/distracted.js +7 -0
  67. package/dist/components/__generated__/stickers/dive-animated.d.ts +3 -0
  68. package/dist/components/__generated__/stickers/dive-animated.js +7 -0
  69. package/dist/components/__generated__/stickers/dive.d.ts +3 -0
  70. package/dist/components/__generated__/stickers/dive.js +7 -0
  71. package/dist/components/__generated__/stickers/eat-animated.d.ts +3 -0
  72. package/dist/components/__generated__/stickers/eat-animated.js +7 -0
  73. package/dist/components/__generated__/stickers/eat.d.ts +3 -0
  74. package/dist/components/__generated__/stickers/eat.js +7 -0
  75. package/dist/components/__generated__/stickers/facepalm-animated.d.ts +3 -0
  76. package/dist/components/__generated__/stickers/facepalm-animated.js +7 -0
  77. package/dist/components/__generated__/stickers/facepalm.d.ts +3 -0
  78. package/dist/components/__generated__/stickers/facepalm.js +7 -0
  79. package/dist/components/__generated__/stickers/failed-animated.d.ts +3 -0
  80. package/dist/components/__generated__/stickers/failed-animated.js +7 -0
  81. package/dist/components/__generated__/stickers/failed.d.ts +3 -0
  82. package/dist/components/__generated__/stickers/failed.js +7 -0
  83. package/dist/components/__generated__/stickers/found-animated.d.ts +3 -0
  84. package/dist/components/__generated__/stickers/found-animated.js +7 -0
  85. package/dist/components/__generated__/stickers/found.d.ts +3 -0
  86. package/dist/components/__generated__/stickers/found.js +7 -0
  87. package/dist/components/__generated__/stickers/grow-animated.d.ts +3 -0
  88. package/dist/components/__generated__/stickers/grow-animated.js +7 -0
  89. package/dist/components/__generated__/stickers/grow.d.ts +3 -0
  90. package/dist/components/__generated__/stickers/grow.js +7 -0
  91. package/dist/components/__generated__/stickers/handstand-animated.d.ts +3 -0
  92. package/dist/components/__generated__/stickers/handstand-animated.js +7 -0
  93. package/dist/components/__generated__/stickers/handstand.d.ts +3 -0
  94. package/dist/components/__generated__/stickers/handstand.js +7 -0
  95. package/dist/components/__generated__/stickers/heart-animated.d.ts +3 -0
  96. package/dist/components/__generated__/stickers/heart-animated.js +7 -0
  97. package/dist/components/__generated__/stickers/heart.d.ts +3 -0
  98. package/dist/components/__generated__/stickers/heart.js +7 -0
  99. package/dist/components/__generated__/stickers/hello-animated.d.ts +3 -0
  100. package/dist/components/__generated__/stickers/hello-animated.js +7 -0
  101. package/dist/components/__generated__/stickers/hello.d.ts +3 -0
  102. package/dist/components/__generated__/stickers/hello.js +7 -0
  103. package/dist/components/__generated__/stickers/idea-animated.d.ts +3 -0
  104. package/dist/components/__generated__/stickers/idea-animated.js +7 -0
  105. package/dist/components/__generated__/stickers/idea.d.ts +3 -0
  106. package/dist/components/__generated__/stickers/idea.js +7 -0
  107. package/dist/components/__generated__/stickers/index.d.ts +99 -0
  108. package/dist/components/__generated__/stickers/index.js +198 -0
  109. package/dist/components/__generated__/stickers/laugh-animated.d.ts +3 -0
  110. package/dist/components/__generated__/stickers/laugh-animated.js +7 -0
  111. package/dist/components/__generated__/stickers/laugh.d.ts +3 -0
  112. package/dist/components/__generated__/stickers/laugh.js +7 -0
  113. package/dist/components/__generated__/stickers/love-animated.d.ts +3 -0
  114. package/dist/components/__generated__/stickers/love-animated.js +7 -0
  115. package/dist/components/__generated__/stickers/love.d.ts +3 -0
  116. package/dist/components/__generated__/stickers/love.js +7 -0
  117. package/dist/components/__generated__/stickers/nap-animated.d.ts +3 -0
  118. package/dist/components/__generated__/stickers/nap-animated.js +7 -0
  119. package/dist/components/__generated__/stickers/nap.d.ts +3 -0
  120. package/dist/components/__generated__/stickers/nap.js +7 -0
  121. package/dist/components/__generated__/stickers/party-animated.d.ts +3 -0
  122. package/dist/components/__generated__/stickers/party-animated.js +7 -0
  123. package/dist/components/__generated__/stickers/party.d.ts +3 -0
  124. package/dist/components/__generated__/stickers/party.js +7 -0
  125. package/dist/components/__generated__/stickers/passed-animated.d.ts +3 -0
  126. package/dist/components/__generated__/stickers/passed-animated.js +7 -0
  127. package/dist/components/__generated__/stickers/passed.d.ts +3 -0
  128. package/dist/components/__generated__/stickers/passed.js +7 -0
  129. package/dist/components/__generated__/stickers/peekaboo-animated.d.ts +3 -0
  130. package/dist/components/__generated__/stickers/peekaboo-animated.js +7 -0
  131. package/dist/components/__generated__/stickers/peekaboo.d.ts +3 -0
  132. package/dist/components/__generated__/stickers/peekaboo.js +7 -0
  133. package/dist/components/__generated__/stickers/pizza-animated.d.ts +3 -0
  134. package/dist/components/__generated__/stickers/pizza-animated.js +7 -0
  135. package/dist/components/__generated__/stickers/pizza.d.ts +3 -0
  136. package/dist/components/__generated__/stickers/pizza.js +7 -0
  137. package/dist/components/__generated__/stickers/puzzle-animated.d.ts +3 -0
  138. package/dist/components/__generated__/stickers/puzzle-animated.js +7 -0
  139. package/dist/components/__generated__/stickers/puzzle.d.ts +3 -0
  140. package/dist/components/__generated__/stickers/puzzle.js +7 -0
  141. package/dist/components/__generated__/stickers/sad-animated.d.ts +3 -0
  142. package/dist/components/__generated__/stickers/sad-animated.js +7 -0
  143. package/dist/components/__generated__/stickers/sad.d.ts +3 -0
  144. package/dist/components/__generated__/stickers/sad.js +7 -0
  145. package/dist/components/__generated__/stickers/scared-animated.d.ts +3 -0
  146. package/dist/components/__generated__/stickers/scared-animated.js +7 -0
  147. package/dist/components/__generated__/stickers/scared.d.ts +3 -0
  148. package/dist/components/__generated__/stickers/scared.js +7 -0
  149. package/dist/components/__generated__/stickers/scroll-animated.d.ts +3 -0
  150. package/dist/components/__generated__/stickers/scroll-animated.js +7 -0
  151. package/dist/components/__generated__/stickers/scroll.d.ts +3 -0
  152. package/dist/components/__generated__/stickers/scroll.js +7 -0
  153. package/dist/components/__generated__/stickers/search-animated.d.ts +3 -0
  154. package/dist/components/__generated__/stickers/search-animated.js +7 -0
  155. package/dist/components/__generated__/stickers/search.d.ts +3 -0
  156. package/dist/components/__generated__/stickers/search.js +7 -0
  157. package/dist/components/__generated__/stickers/shield-animated.d.ts +3 -0
  158. package/dist/components/__generated__/stickers/shield-animated.js +7 -0
  159. package/dist/components/__generated__/stickers/shield.d.ts +3 -0
  160. package/dist/components/__generated__/stickers/shield.js +7 -0
  161. package/dist/components/__generated__/stickers/shocked-animated.d.ts +3 -0
  162. package/dist/components/__generated__/stickers/shocked-animated.js +7 -0
  163. package/dist/components/__generated__/stickers/shocked.d.ts +3 -0
  164. package/dist/components/__generated__/stickers/shocked.js +7 -0
  165. package/dist/components/__generated__/stickers/sleep-animated.d.ts +3 -0
  166. package/dist/components/__generated__/stickers/sleep-animated.js +7 -0
  167. package/dist/components/__generated__/stickers/sleep.d.ts +3 -0
  168. package/dist/components/__generated__/stickers/sleep.js +7 -0
  169. package/dist/components/__generated__/stickers/stressed-animated.d.ts +3 -0
  170. package/dist/components/__generated__/stickers/stressed-animated.js +7 -0
  171. package/dist/components/__generated__/stickers/stressed.d.ts +3 -0
  172. package/dist/components/__generated__/stickers/stressed.js +7 -0
  173. package/dist/components/__generated__/stickers/suspicious-animated.d.ts +3 -0
  174. package/dist/components/__generated__/stickers/suspicious-animated.js +7 -0
  175. package/dist/components/__generated__/stickers/suspicious.d.ts +3 -0
  176. package/dist/components/__generated__/stickers/suspicious.js +7 -0
  177. package/dist/components/__generated__/stickers/thanks-animated.d.ts +3 -0
  178. package/dist/components/__generated__/stickers/thanks-animated.js +7 -0
  179. package/dist/components/__generated__/stickers/thanks.d.ts +3 -0
  180. package/dist/components/__generated__/stickers/thanks.js +7 -0
  181. package/dist/components/__generated__/stickers/think-animated.d.ts +3 -0
  182. package/dist/components/__generated__/stickers/think-animated.js +7 -0
  183. package/dist/components/__generated__/stickers/think-of-you-animated.d.ts +3 -0
  184. package/dist/components/__generated__/stickers/think-of-you-animated.js +7 -0
  185. package/dist/components/__generated__/stickers/think-of-you.d.ts +3 -0
  186. package/dist/components/__generated__/stickers/think-of-you.js +7 -0
  187. package/dist/components/__generated__/stickers/think.d.ts +3 -0
  188. package/dist/components/__generated__/stickers/think.js +7 -0
  189. package/dist/components/__generated__/stickers/thumbs-up-animated.d.ts +3 -0
  190. package/dist/components/__generated__/stickers/thumbs-up-animated.js +7 -0
  191. package/dist/components/__generated__/stickers/thumbs-up.d.ts +3 -0
  192. package/dist/components/__generated__/stickers/thumbs-up.js +7 -0
  193. package/dist/components/__generated__/stickers/vacation-animated.d.ts +3 -0
  194. package/dist/components/__generated__/stickers/vacation-animated.js +7 -0
  195. package/dist/components/__generated__/stickers/vacation.d.ts +3 -0
  196. package/dist/components/__generated__/stickers/vacation.js +7 -0
  197. package/dist/components/__generated__/stickers/wait-animated.d.ts +3 -0
  198. package/dist/components/__generated__/stickers/wait-animated.js +7 -0
  199. package/dist/components/__generated__/stickers/wait.d.ts +3 -0
  200. package/dist/components/__generated__/stickers/wait.js +7 -0
  201. package/dist/components/__generated__/stickers/wink-animated.d.ts +3 -0
  202. package/dist/components/__generated__/stickers/wink-animated.js +7 -0
  203. package/dist/components/__generated__/stickers/wink.d.ts +3 -0
  204. package/dist/components/__generated__/stickers/wink.js +7 -0
  205. package/dist/components/__generated__/stickers/work-animated.d.ts +3 -0
  206. package/dist/components/__generated__/stickers/work-animated.js +7 -0
  207. package/dist/components/__generated__/stickers/work.d.ts +3 -0
  208. package/dist/components/__generated__/stickers/work.js +7 -0
  209. package/dist/components/__generated__/stickers/zen-animated.d.ts +3 -0
  210. package/dist/components/__generated__/stickers/zen-animated.js +7 -0
  211. package/dist/components/__generated__/stickers/zen.d.ts +3 -0
  212. package/dist/components/__generated__/stickers/zen.js +7 -0
  213. package/dist/elements/a-button.css +733 -0
  214. package/dist/elements/a-button.d.ts +10 -0
  215. package/dist/elements/a-button.js +76 -0
  216. package/dist/elements/a-icon.css +31 -6
  217. package/dist/elements/a-icon.shapes.css +9 -1
  218. package/dist/elements/a-icon.shapes.d.ts +5 -2
  219. package/dist/elements/a-icon.shapes.js +2 -0
  220. package/dist/elements/a-progress.css +7 -9
  221. package/dist/elements/a-sticker-animated.css +9 -0
  222. package/dist/elements/a-sticker-animated.d.ts +38 -0
  223. package/dist/elements/a-sticker-animated.js +79 -0
  224. package/dist/elements/a-sticker.css +9 -0
  225. package/dist/elements/a-sticker.d.ts +18 -0
  226. package/dist/elements/a-sticker.js +30 -0
  227. package/dist/elements/a-text.css +14 -5
  228. package/dist/elements/a-title.css +64 -0
  229. package/dist/elements/index.d.ts +7 -0
  230. package/dist/elements/index.js +19 -0
  231. package/dist/general_types.d.ts +120 -4
  232. package/dist/generate-icons.mjs +5 -3
  233. package/dist/generate-stickers.mjs +293 -0
  234. package/dist/index.d.ts +8 -0
  235. package/dist/index.js +8 -0
  236. package/dist/jsx-runtime.d.ts +6 -1
  237. package/dist/reset.css +96 -11
  238. package/dist/tokens.css +186 -182
  239. package/package.json +17 -4
@@ -0,0 +1,733 @@
1
+ @layer anta {
2
+ /* Shared constants + the neutral tone tokens — neutral is the
3
+ implicit default, so unset buttons inherit these directly. Named
4
+ tones (brand, critical, info, success, warning) override via
5
+ `[tone="X"]` selectors below.
6
+ Neutral chip uses a softer 5% rest alpha (other tones use 10%). */
7
+ a-button,
8
+ a[role="button"] {
9
+ --button-primary-fg: #ffffff;
10
+
11
+ --button-focus: #503cb4;
12
+
13
+ --bg-primary-disabled: #ece9ec;
14
+ --bg-secondary-disabled: #f6f4f6;
15
+ --fg-disabled-primary: #afa9b1;
16
+ --fg-disabled: #afa9b1;
17
+
18
+ --button-loading-stripe: 14px;
19
+ --button-loading-stripe-gap: 16px;
20
+ --button-loading-period: 30px;
21
+ --button-loading-angle: 125deg;
22
+ /* Project the diagonal period onto x so the slide loops seamlessly. */
23
+ --button-loading-x-period: calc(
24
+ var(--button-loading-period) / cos(var(--button-loading-angle) - 90deg)
25
+ );
26
+ --button-loading-opacity: 0.25;
27
+ --button-loading-blur: 2.5px;
28
+
29
+ --button-bg-primary-rest: #635b65;
30
+ --button-bg-primary-hover: #534c57;
31
+ --button-bg-primary-active: #49424c;
32
+ --button-fg-primary-rest: var(--button-primary-fg);
33
+
34
+ --button-bg-secondary-rest: #45374c12;
35
+ --button-bg-secondary-hover: #44374b1a;
36
+ --button-bg-secondary-active: #44374b26;
37
+ --button-fg-secondary-rest: #534c57;
38
+ --button-fg-secondary-hover: #49424c;
39
+
40
+ --button-fg-tertiary-rest: #635b65;
41
+ --button-fg-tertiary-hover: #534c57;
42
+ --button-bg-tertiary-hover: #44374b0d;
43
+ --button-bg-tertiary-active: #44374b1a;
44
+
45
+ --button-fg-quaternary-rest: #635b65;
46
+ --button-fg-quaternary-hover: #49424c;
47
+
48
+ /* Layout */
49
+ --button-padding-x: 9px;
50
+ --button-padding-y: 5px;
51
+ --button-max-width: 100%;
52
+ --button-max-height: 100%;
53
+
54
+ /* Transitions */
55
+ --button-timing-in: 75ms ease-in;
56
+ --button-timing-active: 50ms linear;
57
+ --button-timing-out: 150ms ease-out;
58
+ --button-loading-duration: 0.5s;
59
+ }
60
+
61
+ a-button[tone="brand"],
62
+ a[role="button"][tone="brand"] {
63
+ --button-bg-primary-rest: #5f4bc3;
64
+ --button-bg-primary-hover: #503cb4;
65
+ --button-bg-primary-active: #483493;
66
+ --button-fg-primary-rest: var(--button-primary-fg);
67
+
68
+ --button-bg-secondary-rest: #7460d71a;
69
+ --button-bg-secondary-hover: #7460d726;
70
+ --button-bg-secondary-active: #7460d733;
71
+ --button-fg-secondary-rest: #5f4bc3;
72
+ --button-fg-secondary-hover: #503cb4;
73
+
74
+ --button-fg-tertiary-rest: #5f4bc3;
75
+ --button-fg-tertiary-hover: #503cb4;
76
+ --button-bg-tertiary-hover: #7460d71a;
77
+ --button-bg-tertiary-active: #7460d726;
78
+
79
+ --button-fg-quaternary-rest: #5f4bc3;
80
+ --button-fg-quaternary-hover: #483493;
81
+ }
82
+
83
+ /* Critical/warning tertiary active steps heavier (20% vs 15%). */
84
+ a-button[tone="critical"],
85
+ a[role="button"][tone="critical"] {
86
+ --button-bg-primary-rest: #c9302c;
87
+ --button-bg-primary-hover: #b02120;
88
+ --button-bg-primary-active: #a01c1c;
89
+ --button-fg-primary-rest: var(--button-primary-fg);
90
+
91
+ --button-bg-secondary-rest: #de45451a;
92
+ --button-bg-secondary-hover: #de454526;
93
+ --button-bg-secondary-active: #de454533;
94
+ --button-fg-secondary-rest: #c9302c;
95
+ --button-fg-secondary-hover: #b02120;
96
+
97
+ --button-fg-tertiary-rest: #c9302c;
98
+ --button-fg-tertiary-hover: #b02120;
99
+ --button-bg-tertiary-hover: #de45451a;
100
+ --button-bg-tertiary-active: #de454533;
101
+
102
+ --button-fg-quaternary-rest: #c9302c;
103
+ --button-fg-quaternary-hover: #a01c1c;
104
+ }
105
+
106
+ a-button[tone="info"],
107
+ a[role="button"][tone="info"] {
108
+ --button-bg-primary-rest: #1f6eb2;
109
+ --button-bg-primary-hover: #1a5b93;
110
+ --button-bg-primary-active: #175082;
111
+ --button-fg-primary-rest: var(--button-primary-fg);
112
+
113
+ --button-bg-secondary-rest: #2686d91a;
114
+ --button-bg-secondary-hover: #2686d926;
115
+ --button-bg-secondary-active: #2686d933;
116
+ --button-fg-secondary-rest: #1f6eb2;
117
+ --button-fg-secondary-hover: #1a5b93;
118
+
119
+ --button-fg-tertiary-rest: #1f6eb2;
120
+ --button-fg-tertiary-hover: #1a5b93;
121
+ --button-bg-tertiary-hover: #2686d91a;
122
+ --button-bg-tertiary-active: #2686d926;
123
+
124
+ --button-fg-quaternary-rest: #1f6eb2;
125
+ --button-fg-quaternary-hover: #175082;
126
+ }
127
+
128
+ a-button[tone="success"],
129
+ a[role="button"][tone="success"] {
130
+ --button-bg-primary-rest: #2a7e43;
131
+ --button-bg-primary-hover: #226737;
132
+ --button-bg-primary-active: #1f5c31;
133
+ --button-fg-primary-rest: var(--button-primary-fg);
134
+
135
+ --button-bg-secondary-rest: #3295501a;
136
+ --button-bg-secondary-hover: #32955026;
137
+ --button-bg-secondary-active: #32955033;
138
+ --button-fg-secondary-rest: #2a7e43;
139
+ --button-fg-secondary-hover: #226737;
140
+
141
+ --button-fg-tertiary-rest: #2a7e43;
142
+ --button-fg-tertiary-hover: #226737;
143
+ --button-bg-tertiary-hover: #3295501a;
144
+ --button-bg-tertiary-active: #32955026;
145
+
146
+ --button-fg-quaternary-rest: #2a7e43;
147
+ --button-fg-quaternary-hover: #1f5c31;
148
+ }
149
+
150
+ a-button[tone="warning"],
151
+ a[role="button"][tone="warning"] {
152
+ --button-bg-primary-rest: #c37416;
153
+ --button-bg-primary-hover: #ae6613;
154
+ --button-bg-primary-active: #995200;
155
+ --button-fg-primary-rest: var(--button-primary-fg);
156
+
157
+ --button-bg-secondary-rest: #c374161a;
158
+ --button-bg-secondary-hover: #c3741626;
159
+ --button-bg-secondary-active: #c3741633;
160
+ --button-fg-secondary-rest: #c37416;
161
+ --button-fg-secondary-hover: #ae6613;
162
+
163
+ --button-fg-tertiary-rest: #c37416;
164
+ --button-fg-tertiary-hover: #ae6613;
165
+ --button-bg-tertiary-hover: #c374161a;
166
+ --button-bg-tertiary-active: #c3741633;
167
+
168
+ --button-fg-quaternary-rest: #c37416;
169
+ --button-fg-quaternary-hover: #995200;
170
+ }
171
+
172
+ /* Dark mode — heavier alphas (30/40% vs 10/15%) so chips stay legible
173
+ against a dark page bg. Neutral's anchor flips to a lilac (#e4d1ef);
174
+ mixing a dark gray into a dark bg yields no contrast. The constants
175
+ block also carries the neutral tone tokens since neutral is the
176
+ implicit default. */
177
+ .dark a-button,
178
+ .dark a[role="button"] {
179
+ --button-focus: #a897fc;
180
+
181
+ --bg-primary-disabled: #272329;
182
+ --bg-secondary-disabled: #1d1a1e;
183
+ --fg-disabled-primary: #776e77;
184
+ --fg-disabled: #635b65;
185
+
186
+ --button-bg-primary-rest: #534c57;
187
+ --button-bg-primary-hover: #635b65;
188
+ --button-bg-primary-active: #938d96;
189
+
190
+ --button-bg-secondary-rest: #e4d1ef1c;
191
+ --button-bg-secondary-hover: #e4d1ef24;
192
+ --button-bg-secondary-active: #e4d1ef2e;
193
+ --button-fg-secondary-rest: #c1b9c1;
194
+ --button-fg-secondary-hover: #d4ced4;
195
+
196
+ --button-fg-tertiary-rest: #afa9b1;
197
+ --button-fg-tertiary-hover: #afa9b1;
198
+ --button-bg-tertiary-hover: #e4d1ef14;
199
+ --button-bg-tertiary-active: #e4d1ef21;
200
+
201
+ --button-fg-quaternary-rest: #afa9b1;
202
+ --button-fg-quaternary-hover: #cac4ca;
203
+ }
204
+
205
+ .dark a-button[tone="brand"],
206
+ .dark a[role="button"][tone="brand"] {
207
+ --button-bg-primary-rest: #503cb4;
208
+ --button-bg-primary-hover: #5f4bc3;
209
+ --button-bg-primary-active: #7460d7;
210
+
211
+ --button-bg-secondary-rest: #7460d73b;
212
+ --button-bg-secondary-hover: #7460d747;
213
+ --button-bg-secondary-active: #7460d754;
214
+ --button-fg-secondary-rest: #c5baff;
215
+ --button-fg-secondary-hover: #d2cbf6;
216
+
217
+ --button-fg-tertiary-rest: #ada0ee;
218
+ --button-fg-tertiary-hover: #bcb1f1;
219
+ --button-bg-tertiary-hover: #7460d73b;
220
+ --button-bg-tertiary-active: #7460d747;
221
+
222
+ --button-fg-quaternary-rest: #ada0ee;
223
+ --button-fg-quaternary-hover: #c7bef4;
224
+ }
225
+
226
+ .dark a-button[tone="critical"],
227
+ .dark a[role="button"][tone="critical"] {
228
+ --button-bg-primary-rest: #b02120;
229
+ --button-bg-primary-hover: #c9302c;
230
+ --button-bg-primary-active: #de4545;
231
+
232
+ --button-bg-secondary-rest: #de45453b;
233
+ --button-bg-secondary-hover: #de454547;
234
+ --button-bg-secondary-active: #de454554;
235
+ --button-fg-secondary-rest: #ffabac;
236
+ --button-fg-secondary-hover: #f4c2c2;
237
+
238
+ --button-fg-tertiary-rest: #e78e90;
239
+ --button-fg-tertiary-hover: #efa4a4;
240
+ --button-bg-tertiary-hover: #de45453b;
241
+ --button-bg-tertiary-active: #de454547;
242
+
243
+ --button-fg-quaternary-rest: #e78e90;
244
+ --button-fg-quaternary-hover: #ffabac;
245
+ }
246
+
247
+ .dark a-button[tone="info"],
248
+ .dark a[role="button"][tone="info"] {
249
+ --button-bg-primary-rest: #1a5b93;
250
+ --button-bg-primary-hover: #1f6eb2;
251
+ --button-bg-primary-active: #2686d9;
252
+
253
+ --button-bg-secondary-rest: #2686d93b;
254
+ --button-bg-secondary-hover: #2686d947;
255
+ --button-bg-secondary-active: #2686d954;
256
+ --button-fg-secondary-rest: #9ed2ff;
257
+ --button-fg-secondary-hover: #bad6f3;
258
+
259
+ --button-fg-tertiary-rest: #7db6e8;
260
+ --button-fg-tertiary-hover: #93c5ec;
261
+ --button-bg-tertiary-hover: #2686d93b;
262
+ --button-bg-tertiary-active: #2686d947;
263
+
264
+ --button-fg-quaternary-rest: #7db6e8;
265
+ --button-fg-quaternary-hover: #a6cdef;
266
+ }
267
+
268
+ .dark a-button[tone="success"],
269
+ .dark a[role="button"][tone="success"] {
270
+ --button-bg-primary-rest: #226737;
271
+ --button-bg-primary-hover: #2a7e43;
272
+ --button-bg-primary-active: #329550;
273
+
274
+ --button-bg-secondary-rest: #3295503b;
275
+ --button-bg-secondary-hover: #32955047;
276
+ --button-bg-secondary-active: #32955054;
277
+ --button-fg-secondary-rest: #8ceca9;
278
+ --button-fg-secondary-hover: #b3e5c2;
279
+
280
+ --button-fg-tertiary-rest: #74cd8e;
281
+ --button-fg-tertiary-hover: #88d7a0;
282
+ --button-bg-tertiary-hover: #3295503b;
283
+ --button-bg-tertiary-active: #32955047;
284
+
285
+ --button-fg-quaternary-rest: #74cd8e;
286
+ --button-fg-quaternary-hover: #9ddeb1;
287
+ }
288
+
289
+ .dark a-button[tone="warning"],
290
+ .dark a[role="button"][tone="warning"] {
291
+ --button-bg-primary-rest: #7f410b;
292
+ --button-bg-primary-hover: #995200;
293
+ --button-bg-primary-active: #ae6613;
294
+
295
+ --button-bg-secondary-rest: #c374163b;
296
+ --button-bg-secondary-hover: #c3741647;
297
+ --button-bg-secondary-active: #c3741654;
298
+ --button-fg-secondary-rest: #f7c06e;
299
+ --button-fg-secondary-hover: #f3cc91;
300
+
301
+ --button-fg-tertiary-rest: #e1a452;
302
+ --button-fg-tertiary-hover: #edb25a;
303
+ --button-bg-tertiary-hover: #c374163b;
304
+ --button-bg-tertiary-active: #c3741647;
305
+
306
+ --button-fg-quaternary-rest: #e1a452;
307
+ --button-fg-quaternary-hover: #f0bf75;
308
+ }
309
+
310
+ a-button,
311
+ a[role="button"] {
312
+ user-select: none;
313
+ display: inline-flex;
314
+ align-items: center;
315
+ gap: 0.5ch;
316
+ overflow: hidden;
317
+ cursor: pointer;
318
+ /* Don't shrink in a flex parent — `overflow: hidden` would clip
319
+ the icon/label silently. Consumers can opt back in if needed. */
320
+ flex-shrink: 0;
321
+
322
+ color: var(--button-fg);
323
+ background-color: var(--button-bg);
324
+ border-radius: 4px;
325
+ text-decoration: none;
326
+
327
+ font-size: 15px;
328
+ font-family: var(--sans-serif);
329
+ font-weight: 450;
330
+ /* All upstream axes must be re-stated here — `font-variation-settings`
331
+ replaces, it doesn't merge with inherited values. Dropping
332
+ "slnt"/"ital" would revert them to the font file's non-zero
333
+ defaults and Safari would render button labels italic. */
334
+ font-variation-settings: "wdth" 88, "slnt" 0, "ital" 0;
335
+ line-height: 18px;
336
+ letter-spacing: 0.05ch;
337
+
338
+ text-overflow: ellipsis;
339
+ text-wrap: nowrap;
340
+ white-space: nowrap;
341
+
342
+ max-width: var(--button-max-width);
343
+ max-height: var(--button-max-height);
344
+ padding-inline: var(--button-padding-x);
345
+ padding-block: var(--button-padding-y);
346
+
347
+ & > a-button-label {
348
+ display: inline-block;
349
+ text-overflow: ellipsis;
350
+ text-wrap: nowrap;
351
+ white-space: nowrap;
352
+ overflow: hidden;
353
+ min-width: 0;
354
+ /* Optical centering: a 17px line box + 1px bottom padding keeps the
355
+ label box at 18px (so button heights are unchanged) while nudging
356
+ the glyphs up ~0.5px, which reads as vertically centered for the
357
+ Antithesis-sans metrics. */
358
+ line-height: 17px;
359
+ padding-bottom: 1px;
360
+ /* Switch to flex when the label has inline children so they
361
+ align on a baseline with a small gap. */
362
+ &:has(> *) {
363
+ display: inline-flex;
364
+ gap: 0.25ch;
365
+ }
366
+ }
367
+
368
+ & > * {
369
+ pointer-events: none;
370
+ }
371
+
372
+ & a-icon {
373
+ transition: color var(--button-timing-out);
374
+ }
375
+
376
+ transition:
377
+ color var(--button-timing-out),
378
+ background-color var(--button-timing-out);
379
+
380
+ &:hover,
381
+ &:focus-visible {
382
+ transition:
383
+ color var(--button-timing-in),
384
+ background-color var(--button-timing-in);
385
+ & a-icon {
386
+ transition: color var(--button-timing-in);
387
+ }
388
+ }
389
+
390
+ &:active,
391
+ &[selected] {
392
+ transition:
393
+ color var(--button-timing-active),
394
+ background-color var(--button-timing-active);
395
+ & a-icon {
396
+ transition: color var(--button-timing-active);
397
+ }
398
+ }
399
+
400
+ &[disabled] {
401
+ pointer-events: none;
402
+ cursor: not-allowed;
403
+ /* Skip transitions on disabled — a `.dark` toggle would flash
404
+ the underlying tone hue mid-resolve. */
405
+ transition: none;
406
+ & a-icon {
407
+ transition: none;
408
+ }
409
+ }
410
+
411
+ &:focus-visible {
412
+ outline: 1px solid var(--button-focus);
413
+ outline-offset: 1px;
414
+ }
415
+
416
+ /* Selected gets a 0.5px inset ring in the current fg color. */
417
+ &[selected] {
418
+ box-shadow: inset 0 0 0 0.5px currentColor;
419
+ }
420
+
421
+ /* Quaternary: instant in every direction — hover-in, press, and
422
+ return to rest all snap with no transition. */
423
+ &[priority="quaternary"] {
424
+ --button-timing-in: 0s;
425
+ --button-timing-active: 0s;
426
+ --button-timing-out: 0s;
427
+ }
428
+
429
+ &[size="small"] {
430
+ --button-padding-y: 3px;
431
+ --button-padding-x: 7px;
432
+ }
433
+ &[size="large"] {
434
+ --button-padding-y: 7px;
435
+ --button-padding-x: 13px;
436
+ }
437
+
438
+ /* Underline only on background-less priorities (tertiary, quaternary).
439
+ Rest: 0.5px hairline at 75% alpha. Hover (and sustained [selected]):
440
+ 1px thickness at 100% alpha. Active returns to rest. Mirrors the
441
+ prose-link rule used by <Text>. */
442
+ &[priority="tertiary"],
443
+ &[priority="quaternary"] {
444
+ &[underline="solid"] {
445
+ text-decoration: underline solid;
446
+ }
447
+ &[underline="dashed"] {
448
+ text-decoration: underline dashed;
449
+ }
450
+ &[underline="dotted"] {
451
+ text-decoration: underline dotted;
452
+ }
453
+ &[underline] {
454
+ text-decoration-color: color-mix(in srgb, currentColor 75%, transparent);
455
+ text-decoration-thickness: 1px;
456
+ text-underline-offset: 3px;
457
+ &[selected] {
458
+ text-decoration-color: var(--button-fg);
459
+ text-decoration-thickness: 1px;
460
+ }
461
+ /* Hover only on real-pointer devices — gating avoids the sticky
462
+ hover-underline that lingers after a tap on touch screens. */
463
+ @media (hover: hover) and (pointer: fine) {
464
+ &:hover {
465
+ text-decoration-color: var(--button-fg);
466
+ text-decoration-thickness: 1px;
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ &[priority="quaternary"][paddingless] {
473
+ --button-padding-x: 0;
474
+ --button-padding-y: 0;
475
+ }
476
+
477
+ /* Icon-only — square padding plus a min-size pin when the button
478
+ has exactly one child and it's an `a-icon`. Purely structural,
479
+ no opt-in attribute: consumers writing raw `<a-button>` get
480
+ icon-button styling just by passing a single `<a-icon>` inside. */
481
+ &:has(> a-icon:only-child) {
482
+ --button-padding-y: 5px;
483
+ --button-padding-x: 5px;
484
+ min-width: 28px;
485
+ min-height: 28px;
486
+ /* Centre the icon when the host is given an explicit width / height
487
+ larger than the natural square — without this the icon sits at the
488
+ padding-start edge. No-op when the button is at its intrinsic
489
+ square size. */
490
+ justify-content: center;
491
+ &[size="small"] {
492
+ --button-padding-y: 3px;
493
+ --button-padding-x: 3px;
494
+ min-width: 24px;
495
+ min-height: 24px;
496
+ }
497
+ &[size="large"] {
498
+ --button-padding-y: 7px;
499
+ --button-padding-x: 7px;
500
+ min-width: 32px;
501
+ min-height: 32px;
502
+ }
503
+ }
504
+
505
+ /* Optical side padding: an icon at an edge needs less breathing room
506
+ than a text edge, so tighten the padding on whichever side a
507
+ (non-only) icon occupies — leading icon trims the start, trailing
508
+ icon trims the end — to ~2px under the text-edge padding (8px → 6px
509
+ at medium). `max(0px, …)` keeps paddingless/quaternary at 0.
510
+ Icon-only buttons are handled by the rule above. */
511
+ &:has(> a-icon:first-child:not(:only-child)) {
512
+ padding-inline-start: max(0px, var(--button-padding-x) - 2px);
513
+ }
514
+ &:has(> a-icon:last-child:not(:only-child)) {
515
+ padding-inline-end: max(0px, var(--button-padding-x) - 2px);
516
+ }
517
+
518
+ &[loading] {
519
+ position: relative;
520
+ pointer-events: none;
521
+ cursor: wait;
522
+ &::before {
523
+ content: "";
524
+ position: absolute;
525
+ top: 0;
526
+ bottom: 0;
527
+ /* Overshoot left by one x-period so the loop seam lines up. */
528
+ left: calc(0px - var(--button-loading-x-period));
529
+ right: 0;
530
+ pointer-events: none;
531
+ background: repeating-linear-gradient(
532
+ var(--button-loading-angle),
533
+ transparent 0,
534
+ transparent var(--button-loading-stripe-gap),
535
+ currentColor var(--button-loading-stripe-gap),
536
+ currentColor
537
+ calc(
538
+ var(--button-loading-stripe-gap) + var(--button-loading-stripe)
539
+ )
540
+ );
541
+ opacity: var(--button-loading-opacity);
542
+ filter: blur(var(--button-loading-blur));
543
+ will-change: transform;
544
+ animation: btn-loading-slide var(--button-loading-duration) linear
545
+ infinite;
546
+ /* Desync instances so a row doesn't pulse in lockstep. */
547
+ animation-delay: -9999s;
548
+ }
549
+ }
550
+
551
+ /* Custom tone — any non-named `tone` value. Primary uses the literal
552
+ color as-is; the other priorities derive from the source HUE via
553
+ oklch relative color, with lightness/chroma/alpha pinned near Brand
554
+ so any hue reads like a sibling of the named tones. The `--_tone-*`
555
+ knobs below are the only numbers to tune; the dark block re-tunes
556
+ them and the formulas resolve against whichever value computes.
557
+ JSX wrapper writes `--button-tone-source` inline for SSR / older
558
+ engines; the typed attr() fallback picks up raw `<a-button tone="…">`
559
+ on Chrome 133+ / Safari 18.2+. (oklch relative color: Chrome 119+,
560
+ Safari 16.4+, Firefox 128+.) */
561
+ &[tone]:not(
562
+ [tone="brand"],
563
+ [tone="neutral"],
564
+ [tone="critical"],
565
+ [tone="info"],
566
+ [tone="success"],
567
+ [tone="warning"]
568
+ ) {
569
+ --button-tone-source: attr(tone type(<color>), transparent);
570
+
571
+ /* Tunable knobs (light mode). */
572
+ --_tone-fg-l: 0.46; /* fg rest lightness */
573
+ --_tone-fg-strong-l: 0.40; /* fg hover / active lightness */
574
+ --_tone-fg-c: 0.17; /* fg chroma */
575
+ --_tone-bg-l: 0.54; /* tinted-bg lightness */
576
+ --_tone-bg-c: 0.16; /* tinted-bg chroma */
577
+ --_tone-bg-a-rest: 0.10; /* tinted-bg alpha (rest) */
578
+ --_tone-bg-a-hover: 0.15; /* tinted-bg alpha (hover) */
579
+ --_tone-bg-a-active: 0.20; /* tinted-bg alpha (active) */
580
+ --_tone-primary-l-rest: 0.5; /* primary-fill lightness (rest) */
581
+ --_tone-primary-l-hover: 0.45; /* primary-fill lightness (hover) */
582
+ --_tone-primary-l-active: 0.4; /* primary-fill lightness (active) */
583
+
584
+ /* Primary — source hue & chroma, lightness pinned near Brand's
585
+ primary fill so any input lands at a Brand-like lightness instead
586
+ of using the raw color. Re-tunes for dark mode through the knobs
587
+ (the `.dark` block below), exactly like the Brand tone does. */
588
+ --button-bg-primary-rest: oklch(from var(--button-tone-source) var(--_tone-primary-l-rest) c h);
589
+ --button-bg-primary-hover: oklch(from var(--button-tone-source) var(--_tone-primary-l-hover) c h);
590
+ --button-bg-primary-active: oklch(from var(--button-tone-source) var(--_tone-primary-l-active) c h);
591
+ --button-fg-primary-rest: var(--button-primary-fg);
592
+
593
+ /* Secondary / tertiary / quaternary fg — source hue, pinned L/C. */
594
+ --button-fg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);
595
+ --button-fg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);
596
+ --button-fg-tertiary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);
597
+ --button-fg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);
598
+ --button-fg-quaternary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);
599
+ --button-fg-quaternary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);
600
+
601
+ /* Tinted backgrounds — source hue, pinned L, brand-like alphas. */
602
+ --button-bg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));
603
+ --button-bg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));
604
+ --button-bg-secondary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-active));
605
+ --button-bg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));
606
+ --button-bg-tertiary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));
607
+ }
608
+
609
+ /* Custom tone, dark mode — same formulas, re-tuned knobs: lighter fg
610
+ and heavier tint alphas to read against a dark page. */
611
+ .dark &[tone]:not(
612
+ [tone="brand"],
613
+ [tone="neutral"],
614
+ [tone="critical"],
615
+ [tone="info"],
616
+ [tone="success"],
617
+ [tone="warning"]
618
+ ) {
619
+ --_tone-fg-l: 0.78;
620
+ --_tone-fg-strong-l: 0.85;
621
+ --_tone-fg-c: 0.11;
622
+ --_tone-bg-l: 0.58;
623
+ --_tone-bg-a-rest: 0.23;
624
+ --_tone-bg-a-hover: 0.28;
625
+ --_tone-bg-a-active: 0.33;
626
+ /* Primary fill lightness, dark mode (Brand inverts rest/hover and
627
+ lifts active to read against a dark page). */
628
+ --_tone-primary-l-rest: 0.45;
629
+ --_tone-primary-l-hover: 0.5;
630
+ --_tone-primary-l-active: 0.57;
631
+ }
632
+
633
+ /* Wire the per-tone vars into the final fg/bg colors. Secondary
634
+ is the default — declared unscoped so a bare `a-button` consumer
635
+ selector can override it without bumping specificity. Primary,
636
+ tertiary, and quaternary match an explicit `[priority="…"]` attr
637
+ and win on specificity (primary's constant fg beats the unscoped
638
+ :hover on source order). */
639
+ --button-fg: var(--button-fg-secondary-rest);
640
+ --button-bg: var(--button-bg-secondary-rest);
641
+ /* Hover styling is gated to real-pointer devices so it doesn't stick
642
+ after a tap on touch screens (where :hover lingers until the next
643
+ tap elsewhere). :active / [selected] below stay ungated — they're
644
+ the correct press feedback on touch. */
645
+ @media (hover: hover) and (pointer: fine) {
646
+ &:hover {
647
+ --button-fg: var(--button-fg-secondary-hover);
648
+ --button-bg: var(--button-bg-secondary-hover);
649
+ }
650
+ }
651
+ &:active,
652
+ &[selected] {
653
+ --button-fg: var(--button-fg-secondary-hover);
654
+ --button-bg: var(--button-bg-secondary-active);
655
+ }
656
+ &[priority="primary"] {
657
+ --button-fg: var(--button-fg-primary-rest);
658
+ --button-bg: var(--button-bg-primary-rest);
659
+ @media (hover: hover) and (pointer: fine) {
660
+ &:hover {
661
+ --button-bg: var(--button-bg-primary-hover);
662
+ }
663
+ }
664
+ &:active,
665
+ &[selected] {
666
+ --button-bg: var(--button-bg-primary-active);
667
+ }
668
+ }
669
+ &[priority="tertiary"] {
670
+ --button-fg: var(--button-fg-tertiary-rest);
671
+ --button-bg: transparent;
672
+ @media (hover: hover) and (pointer: fine) {
673
+ &:hover {
674
+ --button-fg: var(--button-fg-tertiary-hover);
675
+ --button-bg: var(--button-bg-tertiary-hover);
676
+ }
677
+ }
678
+ &:active,
679
+ &[selected] {
680
+ --button-fg: var(--button-fg-tertiary-hover);
681
+ --button-bg: var(--button-bg-tertiary-active);
682
+ }
683
+ }
684
+ &[priority="quaternary"] {
685
+ /* Rest fg is the quaternary tone at 82% alpha — slightly faded, so a
686
+ quaternary button reads as quieter than a (full-opacity) tertiary
687
+ one. Hover / active restore full opacity. */
688
+ --button-fg: color-mix(in oklch, var(--button-fg-quaternary-rest) 82%, transparent);
689
+ --button-bg: transparent;
690
+ @media (hover: hover) and (pointer: fine) {
691
+ &:hover {
692
+ --button-fg: var(--button-fg-quaternary-hover);
693
+ }
694
+ }
695
+ &[selected] {
696
+ --button-fg: var(--button-fg-quaternary-hover);
697
+ }
698
+ /* Pressing lightens the rest color by 0.05 (oklch L) for a subtle
699
+ press feedback in light mode — declared after :hover so it wins
700
+ while the pointer is still over the button. Dark mode returns to
701
+ the rest color (lightening would brighten the already-light fg). */
702
+ &:active {
703
+ --button-fg: oklch(from var(--button-fg-quaternary-rest) calc(l + 0.05) c h);
704
+ }
705
+ .dark &:active {
706
+ --button-fg: var(--button-fg-quaternary-rest);
707
+ }
708
+ }
709
+
710
+ /* Set bg/color directly (not the vars) so inline-style
711
+ `--button-bg` overrides can't keep a disabled button alive.
712
+ Secondary disabled is the default; other priorities override below. */
713
+ &[disabled] {
714
+ background-color: var(--bg-secondary-disabled);
715
+ color: var(--fg-disabled);
716
+ &[priority="primary"] {
717
+ background-color: var(--bg-primary-disabled);
718
+ color: var(--fg-disabled-primary);
719
+ }
720
+ &[priority="tertiary"],
721
+ &[priority="quaternary"] {
722
+ background-color: transparent;
723
+ color: var(--fg-disabled);
724
+ }
725
+ }
726
+ }
727
+ }
728
+
729
+ @keyframes btn-loading-slide {
730
+ to {
731
+ transform: translateX(var(--button-loading-x-period));
732
+ }
733
+ }