@necrolab/dashboard 0.5.12 → 0.5.13

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 (54) hide show
  1. package/.playwright-mcp/verification-accounts-desktop.png +0 -0
  2. package/.playwright-mcp/verification-tasks-desktop.png +0 -0
  3. package/.playwright-mcp/verification-tasks-mobile.png +0 -0
  4. package/README.md +21 -0
  5. package/docs/plans/2026-02-08-tailwind-consolidation-results.md +476 -0
  6. package/docs/plans/2026-02-08-tailwind-consolidation.md +2416 -0
  7. package/package.json +1 -1
  8. package/src/App.vue +2 -163
  9. package/src/assets/css/components/buttons.scss +43 -95
  10. package/src/assets/css/components/forms.scss +10 -28
  11. package/src/assets/css/components/search-groups.scss +80 -0
  12. package/src/assets/css/components/tables.scss +0 -8
  13. package/src/assets/css/main.scss +2 -43
  14. package/src/components/Editors/Account/Account.vue +14 -220
  15. package/src/components/Editors/Account/AccountCreator.vue +0 -4
  16. package/src/components/Editors/Account/AccountView.vue +0 -1
  17. package/src/components/Editors/Account/CreateAccount.vue +36 -107
  18. package/src/components/Editors/Profile/CreateProfile.vue +46 -135
  19. package/src/components/Editors/Profile/Profile.vue +10 -213
  20. package/src/components/Editors/Profile/ProfileView.vue +0 -1
  21. package/src/components/Filter/Filter.vue +14 -17
  22. package/src/components/Filter/FilterPreview.vue +0 -6
  23. package/src/components/Table/Row.vue +1 -1
  24. package/src/components/Table/Table.vue +2 -16
  25. package/src/components/Tasks/CreateTaskAXS.vue +45 -104
  26. package/src/components/Tasks/CreateTaskTM.vue +58 -96
  27. package/src/components/Tasks/Task.vue +22 -209
  28. package/src/components/Tasks/TaskView.vue +5 -4
  29. package/src/components/Tasks/ViewTask.vue +201 -214
  30. package/src/components/icons/Copy.vue +6 -0
  31. package/src/components/icons/index.js +3 -1
  32. package/src/components/ui/ActionButtonGroup.vue +70 -0
  33. package/src/components/ui/FormField.vue +74 -0
  34. package/src/components/ui/InfoRow.vue +98 -0
  35. package/src/components/ui/Modal.vue +6 -47
  36. package/src/components/ui/Navbar.vue +15 -43
  37. package/src/components/ui/ReconnectIndicator.vue +4 -4
  38. package/src/components/ui/SectionCard.vue +24 -0
  39. package/src/components/ui/Splash.vue +1 -6
  40. package/src/components/ui/StatusBadge.vue +37 -0
  41. package/src/components/ui/controls/CountryChooser.vue +14 -58
  42. package/src/components/ui/controls/atomic/Dropdown.vue +16 -24
  43. package/src/components/ui/controls/atomic/MultiDropdown.vue +7 -1
  44. package/src/components/ui/controls/atomic/Switch.vue +13 -29
  45. package/src/composables/useCopyToClipboard.js +25 -0
  46. package/src/composables/useRowSelection.js +48 -0
  47. package/src/views/Accounts.vue +0 -81
  48. package/src/views/Console.vue +4 -21
  49. package/src/views/Editor.vue +48 -138
  50. package/src/views/FilterBuilder.vue +0 -23
  51. package/src/views/Login.vue +14 -63
  52. package/src/views/Profiles.vue +0 -82
  53. package/src/views/Tasks.vue +3 -24
  54. package/tailwind.config.js +47 -5
@@ -9,13 +9,13 @@
9
9
  <div>
10
10
  <div class="my-3 grid grid-cols-12 gap-3">
11
11
  <!-- Profile tag -->
12
- <div class="input-wrapper z-dropdown col-span-4">
12
+ <div class="input-wrapper col-span-4">
13
13
  <label class="label-override mb-2">
14
14
  Profile Tag
15
15
  <TagIcon />
16
16
  </label>
17
17
  <Dropdown
18
- :class="`input-default dropdown w-full ${errors.includes('profileTag') ? 'error' : ''}`"
18
+ :class="`input-default dropdown w-full`"
19
19
  :default="ui.profile.tags[0]"
20
20
  :options="ui.profile.tags"
21
21
  :onClick="(f) => (profile.tag = f)"
@@ -23,22 +23,16 @@
23
23
  </div>
24
24
 
25
25
  <!-- Card Number -->
26
- <div class="input-wrapper z-0 col-span-8">
27
- <label class="label-override mb-2">
28
- Card Number
29
- <CartIcon />
30
- </label>
31
- <div :class="`input-default ${errors.includes('cardNumber') ? 'error' : ''}`">
32
- <input
33
- ref="cardNumberInput"
34
- placeholder="Enter card number"
35
- v-model="displayCardNumber"
36
- maxlength="23"
37
- inputmode="numeric"
38
- @input="handleCreditCardUpdate"
39
- @focus="formatCardNumberDisplay" />
40
- </div>
41
- </div>
26
+ <FormField label="Card Number" :icon="CartIcon" :error="errors.includes('cardNumber')" z-index="0" class="col-span-8">
27
+ <input
28
+ ref="cardNumberInput"
29
+ placeholder="Enter card number"
30
+ v-model="displayCardNumber"
31
+ maxlength="23"
32
+ inputmode="numeric"
33
+ @input="handleCreditCardUpdate"
34
+ @focus="formatCardNumberDisplay" />
35
+ </FormField>
42
36
 
43
37
  <!-- Country chooser -->
44
38
  <div class="input-wrapper col-span-2">
@@ -55,7 +49,7 @@
55
49
 
56
50
  <!-- Exp Year -->
57
51
  <div class="input-wrapper col-span-5">
58
- <label class="label-override z-0 mb-2">
52
+ <label class="label-override mb-2">
59
53
  Expiry Year
60
54
  <TimerIcon />
61
55
  </label>
@@ -74,7 +68,7 @@
74
68
  </div>
75
69
 
76
70
  <!-- Exp Month -->
77
- <div class="input-wrapper z-2 col-span-5">
71
+ <div class="input-wrapper col-span-5">
78
72
  <label class="label-override mb-2">
79
73
  Expiry Month
80
74
  <TimerIcon />
@@ -88,40 +82,28 @@
88
82
  </div>
89
83
 
90
84
  <!-- CVV -->
91
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
92
- <label class="label-override mb-2">
93
- CVV
94
- <ShieldIcon />
95
- </label>
96
- <div :class="`input-default ${errors.includes('cvv') ? 'error' : ''}`">
97
- <input
98
- placeholder="183"
99
- min="100"
100
- max="9999"
101
- maxlength="4"
102
- minlength="3"
103
- v-model="profile.cvv" />
104
- </div>
105
- </div>
85
+ <FormField label="CVV" :icon="ShieldIcon" :error="errors.includes('cvv')" z-index="0" class="col-span-6 md:col-span-4">
86
+ <input
87
+ placeholder="183"
88
+ min="100"
89
+ max="9999"
90
+ maxlength="4"
91
+ minlength="3"
92
+ v-model="profile.cvv" />
93
+ </FormField>
106
94
 
107
95
  <!-- City -->
108
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
109
- <label class="label-override mb-2">
110
- City
111
- <StadiumIcon />
112
- </label>
113
- <div :class="`input-default ${errors.includes('city') ? 'error' : ''}`">
114
- <input placeholder="Denver" v-model="profile.city" />
115
- </div>
116
- </div>
96
+ <FormField label="City" :icon="StadiumIcon" :error="errors.includes('city')" z-index="0" class="col-span-6 md:col-span-4">
97
+ <input placeholder="Denver" v-model="profile.city" />
98
+ </FormField>
117
99
 
118
100
  <!-- State -->
119
- <div class="input-wrapper z-1 col-span-6 md:col-span-4">
101
+ <div class="input-wrapper col-span-6 md:col-span-4">
120
102
  <label class="label-override mb-2">
121
103
  State
122
104
  <SandclockIcon />
123
105
  </label>
124
- <div v-if="profile.country === 'US'" :class="`${errors.includes('state') ? 'error' : ''}`">
106
+ <div v-if="profile.country === 'US'">
125
107
  <Dropdown
126
108
  class="input-default w-full"
127
109
  default="Select State"
@@ -131,32 +113,20 @@
131
113
  rightAmount="right-2"
132
114
  :value="profile.state" />
133
115
  </div>
134
- <div v-else :class="`input-default ${errors.includes('state') ? 'error' : ''}`">
116
+ <div v-else class="input-default">
135
117
  <input disabled placeholder="N/A" value="" />
136
118
  </div>
137
119
  </div>
138
120
 
139
121
  <!-- Zip -->
140
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
141
- <label class="label-override mb-2">
142
- Zip
143
- <KeyIcon />
144
- </label>
145
- <div :class="`input-default ${errors.includes('zipCode') ? 'error' : ''}`">
146
- <input placeholder="10005" type="number" min="1" max="12" v-model="profile.zipCode" />
147
- </div>
148
- </div>
122
+ <FormField label="Zip" :icon="KeyIcon" :error="errors.includes('zipCode')" z-index="0" class="col-span-6 md:col-span-4">
123
+ <input placeholder="10005" type="number" min="1" max="12" v-model="profile.zipCode" />
124
+ </FormField>
149
125
 
150
126
  <!-- Address -->
151
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
152
- <label class="label-override mb-2">
153
- Address
154
- <HandIcon />
155
- </label>
156
- <div :class="`input-default ${errors.includes('address') ? 'error' : ''}`">
157
- <input placeholder="100 5th Avenue" v-model="profile.address" />
158
- </div>
159
- </div>
127
+ <FormField label="Address" :icon="HandIcon" :error="errors.includes('address')" z-index="0" class="col-span-6 md:col-span-4">
128
+ <input placeholder="100 5th Avenue" v-model="profile.address" />
129
+ </FormField>
160
130
 
161
131
  <!-- Generate -->
162
132
  <div class="input-wrapper z-0 col-span-6 md:col-span-4">
@@ -199,12 +169,7 @@
199
169
  <div class="col-span-6">
200
170
  <label class="label-override mb-2">Status</label>
201
171
  <div class="flex items-center gap-3 h-10">
202
- <div v-if="ui.currentlyEditing.enabled" class="enabled-badge-large">
203
- <CheckmarkIcon />
204
- </div>
205
- <div v-else class="disabled-badge-large">
206
- <CloseXIcon />
207
- </div>
172
+ <StatusBadge :enabled="ui.currentlyEditing.enabled" size="large" />
208
173
  <span class="text-sm font-medium" :class="ui.currentlyEditing.enabled ? 'text-green-400' : 'text-red-400'">
209
174
  {{ ui.currentlyEditing.enabled ? 'Enabled' : 'Disabled' }}
210
175
  </span>
@@ -222,75 +187,22 @@
222
187
  </Modal>
223
188
  </template>
224
189
  <style lang="scss" scoped>
225
- .enabled-badge-large {
226
- @apply flex items-center justify-center rounded-full;
227
- background: oklch(0.72 0.15 145 / 0.12);
228
- border: 1.5px solid oklch(0.72 0.15 145);
229
- width: 26px;
230
- height: 26px;
231
- padding: 0;
232
-
233
- svg {
234
- color: oklch(0.72 0.15 145) !important;
235
- width: 14px !important;
236
- height: auto !important;
237
- max-height: 14px !important;
238
- display: block;
239
- margin: 0;
240
- }
241
-
242
- svg path {
243
- stroke: oklch(0.72 0.15 145) !important;
244
- fill: oklch(0.72 0.15 145) !important;
245
- }
246
- }
247
-
248
- .disabled-badge-large {
249
- @apply flex items-center justify-center rounded-full;
250
- background: oklch(0.60 0.20 25 / 0.12);
251
- border: 1.5px solid oklch(0.60 0.20 25);
252
- width: 26px;
253
- height: 26px;
254
- padding: 0;
255
- color: oklch(0.60 0.20 25) !important;
190
+ .label-override {
191
+ @apply flex items-center;
192
+ color: #e1e1e4 !important;
256
193
 
257
194
  svg {
258
- color: oklch(0.60 0.20 25) !important;
259
- width: 14px !important;
260
- height: 14px !important;
261
- display: block;
262
- margin: 0;
263
- fill: oklch(0.60 0.20 25) !important;
264
- }
265
-
266
- svg path {
267
- stroke: oklch(0.60 0.20 25) !important;
268
- fill: oklch(0.60 0.20 25) !important;
269
- }
270
- }
195
+ @apply ml-2;
271
196
 
272
- .input-wrapper {
273
- label {
274
- @apply flex;
197
+ path {
198
+ fill: #e1e1e4 !important;
199
+ }
275
200
  }
276
201
  }
277
- .z-0 {
278
- z-index: 0 !important;
279
- }
280
- .z-1 {
281
- z-index: 1 !important;
282
- }
283
- .z-2 {
284
- z-index: 2 !important;
285
- }
286
-
287
- .error {
288
- border-width: 2px !important;
289
- border-color: rgb(238 130 130) !important;
290
- }
291
202
  </style>
292
203
  <script setup>
293
204
  import Modal from "@/components/ui/Modal.vue";
205
+ import FormField from "@/components/ui/FormField.vue";
294
206
  import {
295
207
  MailIcon,
296
208
  CartIcon,
@@ -302,11 +214,10 @@ import {
302
214
  SandclockIcon,
303
215
  TimerIcon,
304
216
  TagIcon,
305
- WildcardIcon,
306
- CheckmarkIcon,
307
- CloseXIcon
217
+ WildcardIcon
308
218
  } from "@/components/icons";
309
219
  import { EditIcon } from "@/components/icons";
220
+ import StatusBadge from "@/components/ui/StatusBadge.vue";
310
221
  import TagLabel from "@/components/Editors/TagLabel.vue";
311
222
  import ProfileCountryChooser from "@/components/Editors/Profile/ProfileCountryChooser.vue";
312
223
  import { useUIStore } from "@/stores/ui";
@@ -32,13 +32,8 @@
32
32
  <div class="col-span-1">
33
33
  <h4 class="text-white">{{ expDate() }}</h4>
34
34
  </div>
35
- <div class="col-span-1">
36
- <div v-if="props.profile.enabled" class="enabled-badge">
37
- <CheckmarkIcon class="w-3.5 h-3.5" />
38
- </div>
39
- <div v-else class="disabled-badge">
40
- <CloseXIcon class="w-3.5 h-3.5" />
41
- </div>
35
+ <div class="col-span-1 flex justify-center">
36
+ <StatusBadge :enabled="props.profile.enabled" size="small" />
42
37
  </div>
43
38
 
44
39
  <div class="col-span-1 hidden lg:block">
@@ -48,7 +43,7 @@
48
43
  </div>
49
44
 
50
45
  <div class="col-span-1 flex">
51
- <ul class="profile-buttons">
46
+ <ActionButtonGroup>
52
47
  <li>
53
48
  <button @click="edit">
54
49
  <EditIcon />
@@ -67,192 +62,25 @@
67
62
  <li>
68
63
  <button @click="deleteProfile"><TrashIcon /></button>
69
64
  </li>
70
- </ul>
65
+ </ActionButtonGroup>
71
66
  </div>
72
67
  </Row>
73
68
  </template>
74
69
  <style lang="scss" scoped>
75
- .enabled-badge {
76
- @apply flex items-center justify-center mx-auto rounded-full;
77
- background: oklch(0.72 0.15 145 / 0.12);
78
- border: 1.5px solid oklch(0.72 0.15 145);
79
- width: 24px;
80
- height: 24px;
81
- padding: 0;
82
-
83
- svg {
84
- color: oklch(0.72 0.15 145) !important;
85
- width: 12px !important;
86
- height: auto !important;
87
- max-height: 12px !important;
88
- display: block;
89
- margin: 0;
90
- }
91
-
92
- svg path {
93
- stroke: oklch(0.72 0.15 145) !important;
94
- fill: oklch(0.72 0.15 145) !important;
95
- }
96
- }
97
-
98
- .disabled-badge {
99
- @apply flex items-center justify-center mx-auto rounded-full;
100
- background: oklch(0.60 0.20 25 / 0.12);
101
- border: 1.5px solid oklch(0.60 0.20 25);
102
- width: 24px;
103
- height: 24px;
104
- padding: 0;
105
- color: oklch(0.60 0.20 25) !important;
106
-
107
- svg {
108
- color: oklch(0.60 0.20 25) !important;
109
- width: 12px !important;
110
- height: 12px !important;
111
- display: block;
112
- margin: 0;
113
- fill: oklch(0.60 0.20 25) !important;
114
- }
115
-
116
- svg path {
117
- stroke: oklch(0.60 0.20 25) !important;
118
- fill: oklch(0.60 0.20 25) !important;
119
- }
120
- }
121
-
122
70
  h4 {
123
71
  @apply text-center;
124
72
  }
125
- .profile-buttons {
126
- @apply mx-auto flex items-center justify-center rounded;
127
- background: oklch(0.2046 0 0);
128
- border: 2px solid oklch(0.2809 0 0);
129
- padding: 3px;
130
- gap: 2px;
131
- flex-shrink: 0;
132
- overflow: visible;
133
-
134
- button {
135
- @apply relative flex items-center justify-center rounded border-0 outline-0 transition-all duration-150;
136
- background: transparent;
137
- width: 28px;
138
- height: 28px;
139
- color: oklch(0.90 0 0);
140
- border-radius: 6px;
141
-
142
- &:hover {
143
- background: oklch(0.72 0.15 145 / 0.15);
144
- color: oklch(1 0 0);
145
- }
146
-
147
- &:active {
148
- background: oklch(0.72 0.15 145 / 0.25);
149
- }
150
- }
151
-
152
- svg,
153
- img {
154
- width: 16px;
155
- height: 16px;
156
- position: relative;
157
- z-index: 1;
158
- }
159
-
160
- svg path {
161
- fill: currentColor;
162
- }
163
- }
164
-
165
- // Tablet sizing - medium buttons
166
- @media (min-width: 768px) and (max-width: 1023px) {
167
- .profile-buttons {
168
- padding: 2px;
169
- gap: 1px;
170
- border-radius: 6px;
171
-
172
- button {
173
- width: 26px;
174
- height: 26px;
175
- border-radius: 5px;
176
- }
177
-
178
- svg,
179
- img {
180
- width: 14px;
181
- height: 14px;
182
- }
183
- }
184
- }
185
-
186
- // Desktop sizing - large buttons
187
- @media (min-width: 1024px) {
188
- .profile-buttons {
189
- padding: 3px;
190
- gap: 2px;
191
- border-radius: 8px;
192
-
193
- button {
194
- width: 28px;
195
- height: 28px;
196
- border-radius: 6px;
197
- }
198
-
199
- svg,
200
- img {
201
- width: 16px;
202
- height: 16px;
203
- }
204
- }
205
- }
206
-
207
- // Mobile specific styling
208
- @media (max-width: 640px) {
209
- .profile-buttons {
210
- padding: 1px;
211
- gap: 1px;
212
- border-radius: 4px;
213
- border: 2px solid oklch(0.2809 0 0) !important;
214
- max-width: 100%;
215
- min-height: 28px;
216
- height: auto;
217
- flex-wrap: wrap;
218
- justify-content: center;
219
- align-items: center;
220
- background: oklch(0.2046 0 0);
221
-
222
- button {
223
- width: 20px;
224
- height: 20px;
225
- border-radius: 3px;
226
- min-width: 20px;
227
- border: none !important;
228
- flex-shrink: 0;
229
- margin: 0.5px;
230
- background: transparent;
231
-
232
- &:hover {
233
- background: oklch(0.72 0.15 145 / 0.15);
234
- }
235
-
236
- &:active {
237
- background: oklch(0.72 0.15 145 / 0.25);
238
- }
239
- }
240
-
241
- svg,
242
- img {
243
- width: 12px;
244
- height: 12px;
245
- }
246
- }
247
- }
248
73
  </style>
249
74
  <script setup>
250
75
  import { Row } from "@/components/Table";
251
- import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon, CheckmarkIcon, CloseXIcon } from "@/components/icons";
76
+ import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon } from "@/components/icons";
252
77
  import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
78
+ import StatusBadge from "@/components/ui/StatusBadge.vue";
79
+ import ActionButtonGroup from "@/components/ui/ActionButtonGroup.vue";
253
80
  import { useUIStore } from "@/stores/ui";
254
81
  import { validateCard } from "@/stores/utils";
255
82
  import TagLabel from "@/components/Editors/TagLabel.vue";
83
+ import { useRowSelection } from "@/composables/useRowSelection";
256
84
 
257
85
  const ui = useUIStore();
258
86
 
@@ -280,38 +108,7 @@ const edit = () => {
280
108
  const deleteProfile = async () => await ui.deleteProfile(props.profile.id);
281
109
 
282
110
  // Double-click/tap selection
283
- let lastTapTime = 0;
284
- const DOUBLE_TAP_DELAY = 300; // ms
285
-
286
- const handleDoubleClick = (event) => {
287
- // Prevent if clicking on buttons or checkbox
288
- if (event.target.closest('button') || event.target.closest('.checkbox')) {
289
- return;
290
- }
111
+ const { handleDoubleClick, handleTouchStart, handleTouchEnd } = useRowSelection(() => {
291
112
  ui.toggleProfileSelected(props.profile.id);
292
- };
293
-
294
- const handleTouchStart = (event) => {
295
- // Store touch time for double-tap detection
296
- const currentTime = Date.now();
297
- const tapGap = currentTime - lastTapTime;
298
-
299
- if (tapGap < DOUBLE_TAP_DELAY && tapGap > 0) {
300
- // Double-tap detected
301
- if (!event.target.closest('button') && !event.target.closest('.checkbox')) {
302
- event.preventDefault(); // Prevent zoom
303
- ui.toggleProfileSelected(props.profile.id);
304
- }
305
- }
306
-
307
- lastTapTime = currentTime;
308
- };
309
-
310
- const handleTouchEnd = (event) => {
311
- // Prevent default to avoid potential zoom issues
312
- // but only if not interacting with buttons/checkbox
313
- if (event.target.closest('button') || event.target.closest('.checkbox')) {
314
- return;
315
- }
316
- };
113
+ });
317
114
  </script>
@@ -75,7 +75,6 @@ h4 {
75
75
  }
76
76
 
77
77
  .empty-state {
78
- color: #969696;
79
78
  font-size: 14px;
80
79
  font-weight: 500;
81
80
  }
@@ -289,22 +289,22 @@ props.filterBuilder.onUpdate(() => {
289
289
  <style scoped>
290
290
  .filter-card {
291
291
  @apply bg-dark-500 border-dark-550 relative;
292
- border: 1px solid rgba(61, 62, 68, 0.3);
292
+ @apply border-dark-625/30;
293
+ border-width: 1px;
293
294
  margin-bottom: 8px;
294
295
  transition: all 0.15s ease-out;
295
296
  }
296
297
 
297
298
  .filter-card:hover:not(.expanded-filter) {
298
- border-color: rgba(61, 62, 68, 0.6);
299
- background-color: rgba(46, 47, 52, 0.8);
299
+ @apply border-dark-625/60 bg-dark-475/80;
300
300
  }
301
301
 
302
302
  .expanded-filter:hover {
303
- border-color: rgba(61, 62, 68, 0.8);
303
+ @apply border-dark-625/80;
304
304
  }
305
305
 
306
306
  .filter-card + .filter-card {
307
- border-top: 1px solid rgba(61, 62, 68, 0.2);
307
+ @apply border-t border-t-dark-625/20;
308
308
  }
309
309
 
310
310
  .filter-type-badge {
@@ -333,24 +333,23 @@ props.filterBuilder.onUpdate(() => {
333
333
 
334
334
  .filter-input {
335
335
  @apply border border-dark-550 rounded px-2 py-1.5 text-sm text-white focus:outline-none transition-colors;
336
- background-color: rgba(35, 36, 41, 0.9);
337
- color: white;
336
+ @apply bg-dark-450/90;
338
337
  }
339
338
 
340
339
  .filter-input:focus {
341
340
  border-color: oklch(0.28 0 0);
342
- background-color: rgba(46, 47, 52, 0.9);
341
+ @apply bg-dark-475/90;
343
342
  }
344
343
 
345
344
  .filter-input::placeholder {
346
- color: #9CA3AF;
345
+ @apply text-light-400;
347
346
  }
348
347
 
349
348
  .filter-action-btn {
350
349
  @apply flex items-center justify-center rounded-full transition-all duration-200 border-2 border-transparent;
351
350
  width: 28px;
352
351
  height: 28px;
353
- color: #9CA3AF;
352
+ @apply text-light-400;
354
353
  background-color: rgba(35, 36, 41, 0.8);
355
354
  backdrop-filter: blur(4px);
356
355
  }
@@ -369,25 +368,23 @@ props.filterBuilder.onUpdate(() => {
369
368
  }
370
369
 
371
370
  .drag-btn:hover {
372
- background-color: rgba(68, 69, 75, 0.8);
371
+ @apply bg-dark-675/80;
373
372
  border-color: oklch(0.28 0 0);
374
373
  }
375
374
 
376
375
  .delete-btn:hover {
377
- background-color: rgba(239, 68, 68, 0.8);
378
- border-color: #F87171;
379
- color: #F87171;
376
+ @apply bg-error-500/80 border-error-400 text-error-400;
380
377
  }
381
378
 
382
379
  .drag-handle.sortable-chosen {
383
380
  border: 1px solid oklch(0.28 0 0);
384
- background-color: rgba(68, 69, 75, 0.2);
381
+ @apply bg-dark-675/20;
385
382
  }
386
383
 
387
384
  .filter-card.sortable-ghost {
388
385
  @apply opacity-50;
389
386
  border: 1px solid oklch(0.28 0 0);
390
- background-color: rgba(68, 69, 75, 0.1);
387
+ @apply bg-dark-675/10;
391
388
  }
392
389
 
393
390
  .filter-card.sortable-drag {
@@ -412,7 +409,7 @@ props.filterBuilder.onUpdate(() => {
412
409
  }
413
410
 
414
411
  .excluded-filter {
415
- border-left: 4px solid #EE8282;
412
+ @apply border-l-4 border-l-error-300;
416
413
  }
417
414
 
418
415
  .normal-filter {
@@ -60,12 +60,6 @@
60
60
  }
61
61
  }
62
62
 
63
- .input-wrapper {
64
- label {
65
- @apply flex;
66
- }
67
- }
68
-
69
63
  /* Prism.js syntax highlighting styles */
70
64
  .editor-container {
71
65
  position: relative;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="px-2 md:px-4 text-xs grid text-white py-4 items-center h-full hover:bg-dark-500 transition-colors">
2
+ <div class="px-2 md:px-4 text-xs grid text-white py-4 items-center min-h-full hover:bg-dark-500 transition-colors">
3
3
  <slot />
4
4
  </div>
5
5
  </template>