@necrolab/dashboard 0.5.15 → 0.5.17

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 (137) hide show
  1. package/backend/api.js +2 -3
  2. package/eslint.config.js +46 -0
  3. package/index.html +2 -1
  4. package/package.json +5 -2
  5. package/src/App.vue +70 -566
  6. package/src/assets/css/base/mixins.scss +72 -0
  7. package/src/assets/css/base/reset.scss +0 -2
  8. package/src/assets/css/base/scroll.scss +43 -36
  9. package/src/assets/css/base/typography.scss +9 -10
  10. package/src/assets/css/base/variables.scss +43 -0
  11. package/src/assets/css/components/accessibility.scss +37 -0
  12. package/src/assets/css/components/buttons.scss +61 -74
  13. package/src/assets/css/components/forms.scss +31 -32
  14. package/src/assets/css/components/headers.scss +13 -21
  15. package/src/assets/css/components/modals.scss +2 -2
  16. package/src/assets/css/components/search-groups.scss +28 -22
  17. package/src/assets/css/components/tables.scss +5 -7
  18. package/src/assets/css/components/toasts.scss +7 -7
  19. package/src/assets/css/components/utilities.scss +295 -0
  20. package/src/assets/css/main.scss +55 -139
  21. package/src/components/Auth/LoginForm.vue +7 -86
  22. package/src/components/Console/ConsoleToolbar.vue +123 -0
  23. package/src/components/Editors/Account/Account.vue +12 -12
  24. package/src/components/Editors/Account/AccountView.vue +38 -111
  25. package/src/components/Editors/Account/CreateAccount.vue +11 -61
  26. package/src/components/Editors/Account/{AccountCreator.vue → CreateAccountBatch.vue} +28 -59
  27. package/src/components/Editors/AdminFileEditor.vue +179 -0
  28. package/src/components/Editors/Profile/CreateProfile.vue +77 -150
  29. package/src/components/Editors/Profile/Profile.vue +20 -21
  30. package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
  31. package/src/components/Editors/Profile/ProfileView.vue +41 -116
  32. package/src/components/Editors/ProxyFileEditor.vue +86 -0
  33. package/src/components/Editors/TagLabel.vue +16 -55
  34. package/src/components/Editors/TagToggle.vue +20 -8
  35. package/src/components/Filter/Filter.vue +66 -79
  36. package/src/components/Filter/FilterPreview.vue +153 -135
  37. package/src/components/Filter/PriceSortToggle.vue +36 -43
  38. package/src/components/Table/Header.vue +1 -1
  39. package/src/components/Table/Table.vue +45 -51
  40. package/src/components/Tasks/CheckStock.vue +7 -16
  41. package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
  42. package/src/components/Tasks/Controls/MobileControls.vue +5 -20
  43. package/src/components/Tasks/CreateTaskAXS.vue +20 -118
  44. package/src/components/Tasks/CreateTaskTM.vue +33 -189
  45. package/src/components/Tasks/EventDetailRow.vue +21 -0
  46. package/src/components/Tasks/MassEdit.vue +6 -16
  47. package/src/components/Tasks/QuickSettings.vue +140 -216
  48. package/src/components/Tasks/ScrapeVenue.vue +4 -13
  49. package/src/components/Tasks/Stats.vue +20 -39
  50. package/src/components/Tasks/Task.vue +64 -270
  51. package/src/components/Tasks/TaskLabel.vue +9 -3
  52. package/src/components/Tasks/TaskView.vue +45 -64
  53. package/src/components/Tasks/Utilities.vue +10 -44
  54. package/src/components/Tasks/ViewTask.vue +23 -107
  55. package/src/components/icons/Close.vue +2 -8
  56. package/src/components/icons/Gear.vue +8 -8
  57. package/src/components/icons/Hash.vue +5 -0
  58. package/src/components/icons/Key.vue +2 -8
  59. package/src/components/icons/Pencil.vue +2 -8
  60. package/src/components/icons/Profile.vue +2 -8
  61. package/src/components/icons/Sell.vue +2 -8
  62. package/src/components/icons/Spinner.vue +4 -7
  63. package/src/components/icons/Wildcard.vue +2 -8
  64. package/src/components/icons/index.js +3 -5
  65. package/src/components/ui/ActionButtonGroup.vue +113 -52
  66. package/src/components/ui/BalanceIndicator.vue +60 -0
  67. package/src/components/ui/EmptyState.vue +24 -0
  68. package/src/components/ui/EnableDisableToggle.vue +23 -0
  69. package/src/components/ui/FormField.vue +49 -49
  70. package/src/components/ui/IconLabel.vue +23 -0
  71. package/src/components/ui/InfoRow.vue +21 -54
  72. package/src/components/ui/Modal.vue +161 -54
  73. package/src/components/ui/Navbar.vue +63 -44
  74. package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
  75. package/src/components/ui/ReconnectIndicator.vue +111 -124
  76. package/src/components/ui/SectionCard.vue +6 -14
  77. package/src/components/ui/Splash.vue +2 -10
  78. package/src/components/ui/StatusBadge.vue +26 -28
  79. package/src/components/ui/TaskToggle.vue +54 -0
  80. package/src/components/ui/controls/CountryChooser.vue +29 -66
  81. package/src/components/ui/controls/EyeToggle.vue +1 -1
  82. package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
  83. package/src/components/ui/controls/atomic/Dropdown.vue +103 -139
  84. package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -120
  85. package/src/components/ui/controls/atomic/Switch.vue +21 -84
  86. package/src/composables/useCodeEditor.js +117 -0
  87. package/src/composables/useColorMapping.js +15 -0
  88. package/src/composables/useCopyToClipboard.js +1 -1
  89. package/src/composables/useDateFormatting.js +21 -0
  90. package/src/composables/useDeviceDetection.js +14 -0
  91. package/src/composables/useDropdownPosition.js +1 -4
  92. package/src/composables/useDynamicTableHeight.js +31 -0
  93. package/src/composables/useEnableDisable.js +6 -0
  94. package/src/composables/useFilterCSS.js +71 -0
  95. package/src/composables/useFormValidation.js +92 -0
  96. package/src/composables/useGetAllTags.js +9 -0
  97. package/src/composables/useIOSViewportHandling.js +76 -0
  98. package/src/composables/useNotchHandling.js +306 -0
  99. package/src/composables/useRowSelection.js +0 -3
  100. package/src/composables/useTableRender.js +23 -0
  101. package/src/composables/useTicketPricing.js +16 -0
  102. package/src/composables/useWindowDimensions.js +21 -0
  103. package/src/composables/useZoomPrevention.js +96 -0
  104. package/src/constants/tableLayout.js +14 -0
  105. package/src/libs/Filter.js +14 -20
  106. package/src/libs/panzoom.js +1 -5
  107. package/src/libs/utils/array.js +58 -0
  108. package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
  109. package/src/libs/utils/eventUrl.js +40 -0
  110. package/src/libs/utils/string.js +3 -0
  111. package/src/libs/utils/time.js +20 -0
  112. package/src/libs/utils/validation.js +64 -0
  113. package/src/main.js +0 -2
  114. package/src/stores/connection.js +1 -29
  115. package/src/stores/logger.js +6 -12
  116. package/src/stores/sampleData.js +1 -2
  117. package/src/stores/ui.js +80 -71
  118. package/src/utils/tableHelpers.js +1 -0
  119. package/src/views/Accounts.vue +19 -38
  120. package/src/views/Console.vue +74 -253
  121. package/src/views/Editor.vue +47 -1114
  122. package/src/views/FilterBuilder.vue +190 -461
  123. package/src/views/Login.vue +3 -28
  124. package/src/views/Profiles.vue +17 -32
  125. package/src/views/Tasks.vue +51 -38
  126. package/tailwind.config.js +82 -71
  127. package/workbox-config.cjs +47 -5
  128. package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2438
  129. package/exit +0 -209
  130. package/run +0 -177
  131. package/src/assets/css/base/color-fallbacks.scss +0 -10
  132. package/src/assets/img/background.svg.backup +0 -11
  133. package/src/components/icons/SquareCheck.vue +0 -18
  134. package/src/components/icons/SquareUncheck.vue +0 -18
  135. package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
  136. package/switch-branch.sh +0 -41
  137. /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
@@ -0,0 +1,295 @@
1
+ /* ==========================================================================
2
+ UTILITY CLASSES - Complex reusable patterns
3
+ Extracted from inline classes to improve maintainability
4
+ ========================================================================== */
5
+
6
+ @use "../base/mixins" as *;
7
+
8
+ /* Minimal form input - transparent background for use within labeled containers */
9
+ .form-input-minimal {
10
+ @apply w-full h-full text-sm text-white bg-transparent border-0 outline-none px-2 py-1;
11
+ @apply transition-colors duration-150;
12
+
13
+ &:focus {
14
+ @apply outline-none border-0 shadow-none;
15
+ }
16
+
17
+ &::placeholder {
18
+ @apply text-light-500;
19
+ }
20
+ }
21
+
22
+ /* Form field with label - LoginForm, QuickSettings pattern */
23
+ .form-field-labeled {
24
+ @apply text-white bg-dark-500 px-3 rounded-lg border-2 border-dark-550 flex items-center justify-between h-11 transition-[border-color] duration-150;
25
+
26
+ &:hover {
27
+ @apply border-dark-650;
28
+ }
29
+
30
+ &:focus-within {
31
+ @apply border-accent-green !important;
32
+ @include focus-ring-accent;
33
+ }
34
+ }
35
+
36
+ /* Smaller variant (h-10) for QuickSettings */
37
+ .form-field-labeled-sm {
38
+ @apply text-white bg-dark-500 px-3 rounded-lg border-2 border-dark-550 flex items-center justify-between h-10 transition-colors duration-150;
39
+
40
+ &:hover {
41
+ @apply border-dark-650;
42
+ }
43
+
44
+ &:focus-within {
45
+ @apply border-accent-green !important;
46
+ @include focus-ring-accent;
47
+ }
48
+
49
+ /* Dropdown opened state */
50
+ &:has(.dropdown.opened) {
51
+ @apply border-accent-green !important;
52
+ @include focus-ring-accent;
53
+ }
54
+ }
55
+
56
+ /* Action button with responsive sizing */
57
+ .btn-action-responsive {
58
+ @apply h-10 rounded-md text-xs flex items-center justify-center font-medium px-4;
59
+ @apply transition-all duration-150 btn-focus-ring;
60
+ @include dark-button-base;
61
+ @include scale-hover;
62
+ }
63
+
64
+ .btn-action-responsive:not(.bg-green-400):not(.bg-red-400):not(.bg-blue-400):hover {
65
+ @apply border-dark-700;
66
+ }
67
+
68
+ /* Console scroll button */
69
+ .console-scroll-btn {
70
+ @apply flex h-10 w-10 items-center justify-center rounded border-2 border-dark-550 bg-dark-400 shadow-sm transition-all duration-150 btn-focus-ring;
71
+
72
+ &:hover {
73
+ @apply border-accent-green;
74
+ @include focus-ring-accent;
75
+ }
76
+ }
77
+
78
+ /* Console main container with responsive heights */
79
+ .console-main {
80
+ @apply relative overflow-x-auto overflow-y-auto rounded border-2 border-dark-550 bg-dark-400 p-2 font-mono text-white;
81
+ height: calc(100vh - 20rem);
82
+ max-height: calc(100vh - 20rem);
83
+ scroll-padding: 0.5rem;
84
+ -webkit-overflow-scrolling: touch;
85
+ overscroll-behavior: contain;
86
+ min-height: 12rem !important;
87
+ touch-action: pan-y pan-up pan-down;
88
+
89
+ @screen md {
90
+ height: calc(100vh - 18rem);
91
+ max-height: calc(100vh - 18rem);
92
+ }
93
+
94
+ @screen lg {
95
+ height: calc(100vh - 16rem);
96
+ max-height: calc(100vh - 16rem);
97
+ padding: 1.25rem;
98
+ }
99
+
100
+ @screen mobile-portrait {
101
+ height: calc(100vh - 22rem);
102
+ max-height: calc(100vh - 22rem);
103
+ overflow: auto;
104
+ padding: 0.25rem;
105
+ font-size: 0.75rem;
106
+ line-height: 1rem;
107
+ }
108
+
109
+ @media (orientation: landscape) and (max-width: 1023px) {
110
+ height: calc(100vh - 12rem);
111
+ max-height: calc(100vh - 12rem);
112
+ }
113
+
114
+ @media (max-width: 767px) and (orientation: landscape) {
115
+ height: auto;
116
+ max-height: 65vh;
117
+ }
118
+ }
119
+
120
+ /* FilterBuilder action button */
121
+ .filter-action-btn {
122
+ @apply flex h-8 items-center justify-center gap-1 rounded-md border border-dark-650 bg-dark-400 px-3 text-xs font-medium text-white transition-all duration-150 hover:border-dark-700 btn-focus-ring;
123
+ @include scale-hover;
124
+
125
+ svg {
126
+ @apply mr-1;
127
+ }
128
+ }
129
+
130
+ /* Checkbox base - atomic/Checkbox.vue pattern */
131
+ .checkbox-base {
132
+ @apply relative flex items-center justify-center cursor-pointer shrink-0 rounded-full border-2 bg-transparent transition-all duration-200 ease-out;
133
+ @apply focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent-green focus-visible:outline-offset-2;
134
+
135
+ @media (hover: hover) {
136
+ &:hover {
137
+ @apply scale-105;
138
+ }
139
+ }
140
+ }
141
+
142
+ /* Task status badge */
143
+ .task-status-badge {
144
+ @apply mx-auto flex w-fit items-center justify-center rounded-lg border-2 border-dark-750 bg-dark-400 px-3 py-1.5 gap-1.5 max-w-full pointer-events-none;
145
+
146
+ @screen md {
147
+ padding-left: 0.5rem;
148
+ padding-right: 0.5rem;
149
+ padding-top: 0.25rem;
150
+ padding-bottom: 0.25rem;
151
+ gap: 0.25rem;
152
+ }
153
+
154
+ @screen sm {
155
+ border-width: 2px;
156
+ padding-left: 0.25rem;
157
+ padding-right: 0.25rem;
158
+ padding-top: 0.125rem;
159
+ padding-bottom: 0.125rem;
160
+ }
161
+ }
162
+
163
+ /* Stats/Queue badge pattern */
164
+ .stat-badge {
165
+ @apply flex h-10 min-w-0 items-center justify-between gap-2 rounded-lg px-3 text-sm bg-dark-400 border-2 border-dark-550;
166
+ }
167
+
168
+ /* Mobile control buttons */
169
+ .btn-control-mobile {
170
+ @apply flex h-10 w-20 items-center justify-center gap-x-1 rounded-md border border-dark-650 bg-dark-400 px-3 text-xs+ font-medium text-white transition-all duration-150 hover:border-dark-700 btn-focus-ring;
171
+ }
172
+
173
+ /* Desktop control button variants */
174
+ .btn-control-success {
175
+ @apply bg-green-400 disabled:opacity-70 border-none min-w-20 max-w-30 flex-grow xl:flex-initial flex text-white text-xs font-medium justify-center items-center rounded-md h-10 transition-all duration-200;
176
+ @include scale-hover-safe;
177
+ }
178
+
179
+ .btn-control-danger {
180
+ @apply bg-red-400 disabled:opacity-70 border-none min-w-20 max-w-30 flex-grow xl:flex-initial flex text-white text-xs font-medium justify-center items-center rounded-md h-10 transition-all duration-200;
181
+ @include scale-hover-safe;
182
+ }
183
+
184
+ /* Stat header with icon - Stats component badges */
185
+ .stat-header {
186
+ @apply flex items-center gap-1 whitespace-nowrap text-sm font-semibold text-light-300;
187
+ }
188
+
189
+ /* Empty state icon - EmptyState component, TaskView, FilterBuilder, Console */
190
+ .empty-state-icon {
191
+ @apply mb-3 h-12 w-12 text-dark-400 opacity-50;
192
+ }
193
+
194
+ /* Stat value display - Stats component badge values */
195
+ .stat-value {
196
+ @apply flex items-center justify-center whitespace-nowrap text-xs font-bold text-light-300;
197
+ }
198
+
199
+ /* Grid cell center - Profile/Account editor icon cells */
200
+ .grid-cell-center {
201
+ @apply col-span-1 flex items-center justify-center;
202
+ }
203
+
204
+ /* Transparent input - Console and Tasks search inputs */
205
+ .transparent-input {
206
+ @apply h-full w-full bg-transparent text-sm text-white outline-none;
207
+ }
208
+
209
+ .icon-md {
210
+ @apply h-4 w-4;
211
+ }
212
+
213
+ /* Flex with gap variants - consolidates 51+ repeated patterns */
214
+ .flex-gap-1 {
215
+ @apply flex gap-1;
216
+ }
217
+
218
+ .flex-gap-2 {
219
+ @apply flex gap-2;
220
+ }
221
+
222
+ .flex-gap-3 {
223
+ @apply flex gap-3;
224
+ }
225
+
226
+ /* Standard transition - used throughout the app */
227
+ .transition-standard {
228
+ @apply transition-all duration-150;
229
+ }
230
+
231
+ /* Badge pattern for version/stat chips - QuickSettings pattern */
232
+ .badge-version {
233
+ @apply flex items-center gap-x-1.5 px-2.5 py-1.5 rounded-lg border bg-dark-400 border-dark-550;
234
+ }
235
+
236
+ /* Icon button container - 8x8 flex centered button pattern */
237
+ .icon-button {
238
+ @apply flex h-8 w-8 flex-shrink-0 items-center justify-center rounded;
239
+ }
240
+
241
+ /* Icon size utilities for common patterns */
242
+ .icon-sm {
243
+ @apply h-3 w-3;
244
+ }
245
+
246
+ .icon-lg {
247
+ @apply h-5 w-5;
248
+ }
249
+
250
+ .icon-xl {
251
+ @apply h-6 w-6;
252
+ }
253
+
254
+ /* Square size utilities */
255
+ .size-8 {
256
+ @apply h-8 w-8;
257
+ }
258
+
259
+ .size-10 {
260
+ @apply h-10 w-10;
261
+ }
262
+
263
+ /* Common button pattern - dark with border */
264
+ .btn-dark-bordered {
265
+ @apply rounded-md border border-dark-650 bg-dark-400;
266
+ }
267
+
268
+ /* Flex layout utilities */
269
+ .flex-between {
270
+ @apply flex items-center justify-between;
271
+ }
272
+
273
+ /* Text utilities */
274
+ .text-button {
275
+ @apply text-white text-xs font-medium;
276
+ }
277
+
278
+ /* Padding combinations */
279
+ .pad-3-2 {
280
+ @apply px-3 py-2;
281
+ }
282
+
283
+ /* Square size utilities */
284
+ .square-8 {
285
+ @apply h-8 w-8;
286
+ }
287
+
288
+ /* Border + rounded combinations */
289
+ .dark-border-rounded {
290
+ @apply rounded border border-dark-650;
291
+ }
292
+
293
+ .dark-border-rounded-md {
294
+ @apply rounded-md border border-dark-650;
295
+ }
@@ -3,11 +3,11 @@
3
3
  Modular SCSS architecture with @use imports
4
4
  ========================================================================== */
5
5
 
6
- /* Module imports */
7
6
  @use "base/reset";
8
7
  @use "base/scroll";
9
8
  @use "base/typography";
10
- @use "base/color-fallbacks";
9
+ @use "base/variables";
10
+ @use "base/mixins" as *;
11
11
  @use "components/buttons";
12
12
  @use "components/forms";
13
13
  @use "components/toasts";
@@ -15,69 +15,44 @@
15
15
  @use "components/tables";
16
16
  @use "components/search-groups";
17
17
  @use "components/headers";
18
+ @use "components/utilities";
19
+ @use "components/accessibility";
18
20
 
19
21
  /* ==========================================================================
20
22
  BODY LAYOUT & BACKGROUND
21
23
  ========================================================================== */
22
24
 
23
25
  html {
24
- background-color: oklch(0.1822 0 0);
26
+ @apply bg-dark-300;
25
27
  min-height: 100vh;
26
28
  min-height: 100dvh;
27
29
  }
28
30
 
29
31
  body {
30
- background-color: oklch(0.1822 0 0);
32
+ @apply bg-dark-300;
31
33
  position: relative;
32
34
  min-height: 100vh;
33
35
  min-height: 100dvh;
34
-
35
- &::before {
36
- content: "";
37
- position: fixed;
38
- top: 0;
39
- left: 0;
40
- right: 0;
41
- bottom: 0;
42
- background-image: url("@/assets/img/background.svg");
43
- background-position: center center;
44
- background-size: cover;
45
- background-repeat: no-repeat;
46
- -webkit-background-size: cover;
47
- z-index: -1;
48
- pointer-events: none;
49
- will-change: transform;
50
- -webkit-transform: translateZ(0);
51
- transform: translateZ(0);
52
-
53
- // Extend into safe areas only in PWA mode
54
- @media (display-mode: standalone) {
55
- top: -50px;
56
- left: -50px;
57
- right: -50px;
58
- bottom: -50px;
59
- }
60
- }
61
36
  }
62
37
 
63
38
  /* Global icon color consistency */
64
39
  svg {
65
- color: oklch(0.9 0 0) !important;
40
+ color: var(--color-text-primary) !important;
66
41
  }
67
42
 
68
- /* For stroke icons (Eye, etc) - stroke on svg element */
43
+ /* For stroke-based icons */
69
44
  svg[stroke] path,
70
45
  svg[stroke] circle,
71
46
  svg[stroke] line {
72
- stroke: oklch(0.9 0 0) !important;
47
+ stroke: var(--color-text-primary) !important;
73
48
  }
74
49
 
75
- /* For filled icons with explicit fill */
50
+ /* For fill-based icons */
76
51
  svg path[fill]:not([fill="none"]),
77
52
  svg circle[fill]:not([fill="none"]),
78
53
  svg rect[fill]:not([fill="none"]),
79
54
  svg polygon[fill]:not([fill="none"]) {
80
- fill: oklch(0.9 0 0) !important;
55
+ fill: var(--color-text-primary) !important;
81
56
  }
82
57
 
83
58
  /* For filled icons without explicit fill attribute */
@@ -85,46 +60,42 @@ svg:not([stroke]):not([fill="none"]) path:not([fill]),
85
60
  svg:not([stroke]):not([fill="none"]) circle:not([fill]),
86
61
  svg:not([stroke]):not([fill="none"]) rect:not([fill]),
87
62
  svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
88
- fill: oklch(0.9 0 0) !important;
63
+ fill: var(--color-text-primary) !important;
89
64
  }
90
65
 
91
- /* Badge icon color exceptions - override ALL global white rules */
92
66
  .enabled-badge svg,
93
67
  .enabled-badge-large svg {
94
- color: oklch(0.72 0.15 145) !important;
95
- fill: oklch(0.72 0.15 145) !important;
68
+ color: var(--color-primary) !important;
69
+ fill: var(--color-primary) !important;
96
70
  }
97
71
 
98
72
  .disabled-badge svg,
99
73
  .disabled-badge-large svg {
100
- color: oklch(0.60 0.20 25) !important;
101
- fill: oklch(0.60 0.20 25) !important;
74
+ color: var(--color-disabled) !important;
75
+ fill: var(--color-disabled) !important;
102
76
  }
103
77
 
104
78
  .enabled-badge svg *,
105
79
  .enabled-badge-large svg * {
106
- fill: oklch(0.72 0.15 145) !important;
107
- stroke: oklch(0.72 0.15 145) !important;
80
+ fill: var(--color-primary) !important;
81
+ stroke: var(--color-primary) !important;
108
82
  }
109
83
 
110
84
  .disabled-badge svg *,
111
85
  .disabled-badge-large svg * {
112
- fill: oklch(0.60 0.20 25) !important;
113
- stroke: oklch(0.60 0.20 25) !important;
86
+ fill: var(--color-disabled) !important;
87
+ stroke: var(--color-disabled) !important;
114
88
  }
115
89
 
116
90
  /* ==========================================================================
117
91
  PWA MODE FIXES
118
92
  ========================================================================== */
119
93
 
120
- // Add padding to all page headers in PWA mode to prevent hiding under navbar
121
94
  @media (display-mode: standalone) {
122
- // Accounts page header
123
95
  .flex.items-center.justify-between.pt-5.pb-2 {
124
96
  padding-top: 3.5rem !important;
125
97
  }
126
98
 
127
- // Console page header
128
99
  h4.mb-2.flex.items-center.gap-2.pt-5 {
129
100
  padding-top: 3.5rem !important;
130
101
  }
@@ -134,117 +105,51 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
134
105
  COMPONENT UTILITIES
135
106
  ========================================================================== */
136
107
 
137
- .smooth-hover {
138
- @apply transition-all duration-200;
139
- }
140
-
141
- .status-indicator {
142
- @apply h-2 w-2 flex-shrink-0 rounded-full;
143
- min-width: 4px;
144
- min-height: 4px;
145
- }
146
-
147
108
  .mobile-icons {
148
109
  @apply ml-auto flex items-center gap-x-2 lg:hidden;
149
110
 
150
111
  button {
151
- @apply flex h-8 w-8 items-center justify-center rounded transition-all duration-150;
152
- background-color: oklch(0.2046 0 0);
153
- border: 2px solid oklch(0.2809 0 0);
154
- color: oklch(0.82 0 0);
112
+ @apply flex h-8 w-8 items-center justify-center rounded transition-all duration-150 bg-dark-400;
113
+ border: 2px solid var(--color-border-light);
114
+ color: var(--color-text-secondary);
155
115
 
156
116
  &:hover,
157
117
  &:active {
158
- border-color: oklch(0.72 0.15 145);
159
- outline: 1px solid oklch(0.72 0.15 145);
118
+ border-color: var(--color-primary);
119
+ outline: 1px solid var(--color-primary);
160
120
  outline-offset: 0;
161
- color: oklch(0.9 0 0);
121
+ color: var(--color-text-primary);
162
122
  }
163
123
  }
164
124
  }
165
125
 
166
- .loading-spinner {
167
- @apply h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent;
168
- }
169
-
170
- /* ==========================================================================
171
- LABEL & ICON STYLING
172
- ========================================================================== */
173
-
174
- .label-override {
175
- @apply mb-2 flex items-center text-xs;
176
- color: oklch(0.65 0 0);
177
-
178
- svg {
179
- @apply ml-2;
180
- color: oklch(0.65 0 0) !important;
181
- width: 16px;
182
- height: 16px;
183
- fill: oklch(0.65 0 0) !important;
184
- }
185
- }
186
-
187
- .task-switches {
188
- h4 {
189
- color: oklch(0.9 0 0);
190
- font-size: 0.8125rem;
191
- font-weight: 500;
192
- @apply mx-auto mb-2 flex items-center gap-x-2 text-center;
193
- }
194
-
195
- .switch-wrapper {
196
- @apply gap-y-2;
197
- }
198
-
199
- svg {
200
- width: 15px !important;
201
- height: 15px !important;
202
- color: oklch(0.9 0 0) !important;
203
- margin-left: 0.25rem !important;
204
- }
126
+ .smooth-hover {
127
+ @apply transition-all duration-200;
128
+ @include scale-hover;
205
129
  }
206
130
 
207
- /* ==========================================================================
208
- DYNAMIC HEIGHTS & RESPONSIVE DESIGN
209
- ========================================================================== */
210
-
211
- .max-h-big {
212
- max-height: calc(100vh - 12rem);
213
- min-height: 8rem;
214
- overflow: hidden;
131
+ .status-indicator {
132
+ @apply h-2 w-2 flex-shrink-0 rounded-full;
133
+ min-width: 4px;
134
+ min-height: 4px;
215
135
  }
216
136
 
217
- @screen xl {
218
- .max-h-big {
219
- max-height: calc(100vh - 11rem);
220
- }
137
+ .loading-spinner {
138
+ @apply h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent;
221
139
  }
222
140
 
223
- @screen h-sm {
224
- .max-h-big {
225
- max-height: calc(100vh - 12rem);
226
- min-height: 8rem;
141
+ /* Page button focus states - used in view files */
142
+ button.bg-dark-400,
143
+ button.bg-green-400,
144
+ button.bg-red-400 {
145
+ &:active,
146
+ &:focus {
147
+ @apply outline outline-1 outline-accent-green;
148
+ outline-offset: 0;
149
+ @apply border-accent-green !important;
227
150
  }
228
151
  }
229
152
 
230
- /* ==========================================================================
231
- TRANSITIONS & ANIMATIONS
232
- ========================================================================== */
233
-
234
- .fade-enter-active,
235
- .fade-leave-active {
236
- transition: opacity 0.15s ease;
237
- }
238
-
239
- .fade-enter-from,
240
- .fade-leave-to {
241
- opacity: 0;
242
- }
243
-
244
- .will-change-auto {
245
- will-change: auto;
246
- }
247
-
248
153
  /* ==========================================================================
249
154
  iOS OPTIMIZATIONS
250
155
  ========================================================================== */
@@ -282,3 +187,14 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
282
187
  min-height: 5px;
283
188
  }
284
189
  }
190
+
191
+ /* Fade transition for modals and components */
192
+ .fade-enter-active,
193
+ .fade-leave-active {
194
+ transition: opacity 0.15s ease;
195
+ }
196
+
197
+ .fade-enter-from,
198
+ .fade-leave-to {
199
+ opacity: 0;
200
+ }