@necrolab/dashboard 0.5.14 → 0.5.16

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 (120) 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 +140 -170
  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 +58 -15
  13. package/src/assets/css/components/forms.scss +31 -32
  14. package/src/assets/css/components/headers.scss +119 -0
  15. package/src/assets/css/components/modals.scss +2 -2
  16. package/src/assets/css/components/search-groups.scss +28 -19
  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 +220 -0
  20. package/src/assets/css/main.scss +72 -75
  21. package/src/components/Auth/LoginForm.vue +5 -84
  22. package/src/components/Editors/Account/Account.vue +8 -10
  23. package/src/components/Editors/Account/AccountCreator.vue +28 -59
  24. package/src/components/Editors/Account/AccountView.vue +38 -86
  25. package/src/components/Editors/Account/CreateAccount.vue +8 -50
  26. package/src/components/Editors/Profile/CreateProfile.vue +74 -131
  27. package/src/components/Editors/Profile/Profile.vue +15 -17
  28. package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
  29. package/src/components/Editors/Profile/ProfileView.vue +46 -96
  30. package/src/components/Editors/TagLabel.vue +16 -55
  31. package/src/components/Editors/TagToggle.vue +20 -8
  32. package/src/components/Filter/Filter.vue +62 -75
  33. package/src/components/Filter/FilterPreview.vue +161 -135
  34. package/src/components/Filter/PriceSortToggle.vue +36 -43
  35. package/src/components/Table/Header.vue +1 -1
  36. package/src/components/Table/Table.vue +61 -12
  37. package/src/components/Tasks/CheckStock.vue +7 -16
  38. package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
  39. package/src/components/Tasks/Controls/MobileControls.vue +5 -20
  40. package/src/components/Tasks/CreateTaskAXS.vue +20 -118
  41. package/src/components/Tasks/CreateTaskTM.vue +33 -189
  42. package/src/components/Tasks/EventDetailRow.vue +21 -0
  43. package/src/components/Tasks/MassEdit.vue +6 -16
  44. package/src/components/Tasks/QuickSettings.vue +140 -216
  45. package/src/components/Tasks/ScrapeVenue.vue +4 -13
  46. package/src/components/Tasks/Stats.vue +19 -38
  47. package/src/components/Tasks/Task.vue +65 -268
  48. package/src/components/Tasks/TaskLabel.vue +9 -3
  49. package/src/components/Tasks/TaskView.vue +43 -63
  50. package/src/components/Tasks/Utilities.vue +10 -42
  51. package/src/components/Tasks/ViewTask.vue +23 -107
  52. package/src/components/icons/Close.vue +2 -8
  53. package/src/components/icons/Gear.vue +8 -8
  54. package/src/components/icons/Hash.vue +5 -0
  55. package/src/components/icons/Key.vue +2 -8
  56. package/src/components/icons/Pencil.vue +2 -8
  57. package/src/components/icons/Profile.vue +2 -8
  58. package/src/components/icons/Sell.vue +2 -8
  59. package/src/components/icons/Spinner.vue +4 -7
  60. package/src/components/icons/SquareCheck.vue +2 -8
  61. package/src/components/icons/SquareUncheck.vue +2 -8
  62. package/src/components/icons/Wildcard.vue +2 -8
  63. package/src/components/icons/index.js +3 -1
  64. package/src/components/ui/ActionButtonGroup.vue +113 -52
  65. package/src/components/ui/BalanceIndicator.vue +60 -0
  66. package/src/components/ui/EmptyState.vue +24 -0
  67. package/src/components/ui/EnableDisableToggle.vue +23 -0
  68. package/src/components/ui/FormField.vue +48 -48
  69. package/src/components/ui/IconLabel.vue +23 -0
  70. package/src/components/ui/InfoRow.vue +21 -54
  71. package/src/components/ui/Modal.vue +78 -37
  72. package/src/components/ui/Navbar.vue +60 -41
  73. package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
  74. package/src/components/ui/ReconnectIndicator.vue +111 -124
  75. package/src/components/ui/SectionCard.vue +6 -14
  76. package/src/components/ui/Splash.vue +2 -10
  77. package/src/components/ui/StatusBadge.vue +26 -28
  78. package/src/components/ui/TaskToggle.vue +54 -0
  79. package/src/components/ui/controls/CountryChooser.vue +27 -64
  80. package/src/components/ui/controls/EyeToggle.vue +1 -1
  81. package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
  82. package/src/components/ui/controls/atomic/Dropdown.vue +102 -95
  83. package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -94
  84. package/src/components/ui/controls/atomic/Switch.vue +21 -84
  85. package/src/composables/useColorMapping.js +15 -0
  86. package/src/composables/useCopyToClipboard.js +1 -1
  87. package/src/composables/useDateFormatting.js +21 -0
  88. package/src/composables/useDeviceDetection.js +14 -0
  89. package/src/composables/useDropdownPosition.js +5 -6
  90. package/src/composables/useDynamicTableHeight.js +31 -0
  91. package/src/composables/useRowSelection.js +0 -3
  92. package/src/composables/useTicketPricing.js +16 -0
  93. package/src/composables/useWindowDimensions.js +21 -0
  94. package/src/libs/Filter.js +14 -20
  95. package/src/libs/panzoom.js +1 -5
  96. package/src/libs/utils/array.js +60 -0
  97. package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
  98. package/src/libs/utils/eventUrl.js +40 -0
  99. package/src/libs/utils/string.js +28 -0
  100. package/src/libs/utils/time.js +20 -0
  101. package/src/libs/utils/validation.js +88 -0
  102. package/src/main.js +0 -2
  103. package/src/stores/connection.js +1 -4
  104. package/src/stores/logger.js +6 -12
  105. package/src/stores/sampleData.js +1 -2
  106. package/src/stores/ui.js +59 -36
  107. package/src/views/Accounts.vue +17 -31
  108. package/src/views/Console.vue +76 -176
  109. package/src/views/Editor.vue +217 -383
  110. package/src/views/FilterBuilder.vue +190 -373
  111. package/src/views/Login.vue +3 -28
  112. package/src/views/Profiles.vue +12 -22
  113. package/src/views/Tasks.vue +51 -38
  114. package/tailwind.config.js +82 -71
  115. package/workbox-config.cjs +47 -5
  116. package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2416
  117. package/exit +0 -209
  118. package/run +0 -177
  119. package/switch-branch.sh +0 -41
  120. /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
@@ -2,12 +2,13 @@
2
2
  SCROLL BEHAVIOR & TOUCH HANDLING
3
3
  ========================================================================== */
4
4
 
5
+ @use "mixins" as *;
6
+
5
7
  html {
6
8
  overflow: hidden !important;
7
9
  overscroll-behavior: none !important;
8
10
  height: 100% !important;
9
11
  width: 100% !important;
10
- /* Additional zoom prevention at CSS level */
11
12
  -webkit-text-size-adjust: 100%;
12
13
  -moz-text-size-adjust: 100%;
13
14
  -ms-text-size-adjust: 100%;
@@ -16,22 +17,15 @@ html {
16
17
 
17
18
  * {
18
19
  @apply hidden-scrollbars;
19
- -webkit-user-select: none;
20
- -moz-user-select: none;
21
- -ms-user-select: none;
22
- user-select: none;
20
+ @include user-select(none);
23
21
  overscroll-behavior: none !important;
24
22
  }
25
23
 
26
24
  textarea,
27
25
  .code-editor,
28
26
  .proxy-editor {
29
- -webkit-user-select: text !important;
30
- -moz-user-select: text !important;
31
- -ms-user-select: text !important;
32
- user-select: text !important;
33
- overscroll-behavior: auto !important;
34
- touch-action: pan-y !important;
27
+ @include user-select(text);
28
+ @include touch-scroll-reset;
35
29
  }
36
30
 
37
31
  .dropdown-menu,
@@ -42,60 +36,42 @@ textarea,
42
36
  .option-list *,
43
37
  .console,
44
38
  .console * {
45
- overscroll-behavior: auto !important;
46
- touch-action: pan-y !important;
47
- -webkit-overflow-scrolling: touch !important;
39
+ @include touch-scroll-reset;
48
40
  }
49
41
 
50
- /* Specific overrides for dropdown content portals */
51
42
  .dropdown-content-portal {
52
43
  overflow: auto !important;
53
44
  overflow-y: auto !important;
54
- overscroll-behavior: auto !important;
55
- touch-action: pan-y !important;
56
- -webkit-overflow-scrolling: touch !important;
45
+ @include touch-scroll-reset;
57
46
  scroll-behavior: smooth !important;
58
47
  }
59
48
 
60
49
  .dropdown-content-portal * {
61
50
  overflow: auto !important;
62
- overscroll-behavior: auto !important;
63
- touch-action: pan-y !important;
64
- -webkit-overflow-scrolling: touch !important;
65
- user-select: auto !important;
66
- -webkit-user-select: auto !important;
67
- -moz-user-select: auto !important;
68
- -ms-user-select: auto !important;
51
+ @include touch-scroll-reset;
52
+ @include user-select(auto);
69
53
  }
70
54
 
71
- /* Ultra-specific overrides to beat the global * selector */
72
55
  body .dropdown-content-portal,
73
56
  html .dropdown-content-portal,
74
57
  div .dropdown-content-portal {
75
58
  overflow: auto !important;
76
59
  overflow-y: auto !important;
77
- overscroll-behavior: auto !important;
78
- touch-action: pan-y !important;
79
- -webkit-overflow-scrolling: touch !important;
60
+ @include touch-scroll-reset;
80
61
  }
81
62
 
82
- /* Force scrolling on teleported dropdown content */
83
63
  body > .dropdown-content-portal,
84
64
  [data-v-app] .dropdown-content-portal {
85
65
  overflow: auto !important;
86
66
  overflow-y: auto !important;
87
- overscroll-behavior: auto !important;
88
- touch-action: pan-y !important;
89
- -webkit-overflow-scrolling: touch !important;
67
+ @include touch-scroll-reset;
90
68
  }
91
69
 
92
70
  .code-editor,
93
71
  .proxy-editor,
94
72
  .editor-container,
95
73
  .proxy-editor-container {
96
- overscroll-behavior: auto !important;
97
- touch-action: pan-y !important;
98
- -webkit-overflow-scrolling: touch !important;
74
+ @include touch-scroll-reset;
99
75
  }
100
76
 
101
77
  /* ==========================================================================
@@ -117,3 +93,34 @@ body > .dropdown-content-portal,
117
93
  touch-action: auto !important;
118
94
  overscroll-behavior: auto !important;
119
95
  }
96
+
97
+ /* ==========================================================================
98
+ CUSTOM SCROLLBAR CLASSES - DRY Principle
99
+ Base properties for smooth scrolling with hidden scrollbars
100
+ ========================================================================== */
101
+
102
+ .custom-scrollbar {
103
+ overscroll-behavior: contain;
104
+ -webkit-overflow-scrolling: touch;
105
+ scrollbar-width: none;
106
+ -ms-overflow-style: none;
107
+
108
+ &::-webkit-scrollbar {
109
+ display: none;
110
+ }
111
+ }
112
+
113
+ .custom-scrollbar-y {
114
+ @extend .custom-scrollbar;
115
+ touch-action: pan-y;
116
+ }
117
+
118
+ .custom-scrollbar-x {
119
+ @extend .custom-scrollbar;
120
+ touch-action: pan-x;
121
+ }
122
+
123
+ .custom-scrollbar-xy {
124
+ @extend .custom-scrollbar;
125
+ touch-action: pan-x pan-y;
126
+ }
@@ -13,16 +13,15 @@ body {
13
13
  height: 100%;
14
14
  --toastify-toast-width: 520px;
15
15
 
16
- /* OKLCH Color System - Supabase-inspired */
17
- --bg-base: oklch(0.1822 0 0);
18
- --bg-elevated: oklch(0.2046 0 0);
19
- --bg-input: oklch(0.2603 0 0);
20
- --bg-hover: oklch(0.2809 0 0);
21
- --accent-green: oklch(0.72 0.15 145);
22
- --border-base: oklch(0.2809 0 0);
23
- --text-primary: oklch(0.9851 0 0);
24
- --text-secondary: oklch(0.7122 0 0);
25
- --text-muted: oklch(0.55 0 0);
16
+ --bg-base: var(--color-bg-base);
17
+ --bg-elevated: var(--color-bg-card);
18
+ --bg-input: var(--color-bg-input);
19
+ --bg-hover: var(--color-border);
20
+ --accent-green: var(--color-primary);
21
+ --border-base: var(--color-border);
22
+ --text-primary: var(--color-text-primary);
23
+ --text-secondary: var(--color-text-secondary);
24
+ --text-muted: var(--color-text-muted);
26
25
  }
27
26
 
28
27
  .editor-base {
@@ -0,0 +1,43 @@
1
+ /* ==========================================================================
2
+ CSS VARIABLES
3
+ Shared color tokens to reduce duplication across SCSS files
4
+ ========================================================================== */
5
+
6
+ :root {
7
+ // Color scheme
8
+ color-scheme: dark;
9
+
10
+ // Most common colors (for use in SCSS files)
11
+ --color-primary: oklch(0.72 0.15 145); // accent green - appears 60+ times
12
+ --color-border: oklch(0.26 0 0); // default border - appears 16+ times
13
+ --color-bg-base: oklch(0.1822 0 0); // dark-300 base background
14
+ --color-bg-card: oklch(0.2046 0 0); // dark-400 card backgrounds
15
+ --color-bg-input: oklch(0.2603 0 0); // dark-500 input backgrounds
16
+ --color-text-primary: oklch(0.9 0 0); // primary white text
17
+ --color-bg-darker: oklch(0.19 0 0); // appears 11× (dark-350)
18
+ --color-border-light: oklch(0.28 0 0); // appears 12× (dark-550)
19
+ --color-text-muted: oklch(0.65 0 0); // appears 7× (light-500)
20
+ --color-disabled: oklch(0.60 0.20 25); // appears 5× (disabled orange)
21
+ --color-text-secondary: oklch(0.82 0 0); // secondary text - light-400
22
+ --color-text-bright: oklch(0.85 0 0); // bright icon color
23
+ --color-text-dim: oklch(0.70 0 0); // dimmed text
24
+ --color-text-vivid: oklch(0.95 0 0); // very bright text
25
+ --color-text-almost-white: oklch(0.98 0 0); // almost white text
26
+ --color-bg-darker-alt: oklch(0.20 0 0); // slightly lighter than dark-350
27
+ --color-bg-modal: oklch(0.15 0 0); // modal/dropdown backgrounds
28
+
29
+ // Gradient colors
30
+ --color-gradient-start: oklch(0.22 0 0); // header card gradient start
31
+ --color-gradient-mid: oklch(0.23 0 0); // button hover gradient
32
+ --color-gradient-end: oklch(0.24 0 0); // header card gradient end
33
+ --color-gradient-blue-tint: oklch(0.19 0.02 264); // button active state blue tint
34
+
35
+ // Z-index scale (matches tailwind.config.js)
36
+ // dropdown: 100, dropdown-high: 200, tooltip: 2000, modal: 1000, modal-mask: 25000, max: 9999
37
+ --z-dropdown: 100;
38
+ --z-dropdown-high: 200;
39
+ --z-tooltip: 2000;
40
+ --z-modal: 1000;
41
+ --z-modal-mask: 25000;
42
+ --z-max: 9999;
43
+ }
@@ -0,0 +1,37 @@
1
+ /* ==========================================================================
2
+ ACCESSIBILITY - Focus Visible & Keyboard Navigation
3
+ ========================================================================== */
4
+
5
+ /* Global focus-visible styles for keyboard navigation */
6
+ *:focus-visible {
7
+ @apply outline outline-2 outline-primary outline-offset-2;
8
+ }
9
+
10
+ /* Remove default focus outline for mouse users */
11
+ *:focus:not(:focus-visible) {
12
+ outline: none;
13
+ }
14
+
15
+ /* Input-like elements need inline outline (offset-0) */
16
+ input:focus-visible,
17
+ textarea:focus-visible,
18
+ select:focus-visible,
19
+ .dropdown:focus-visible {
20
+ @apply border-primary outline outline-1 outline-primary;
21
+ outline-offset: 0;
22
+ }
23
+
24
+ /* Modal content focus trap */
25
+ [role="dialog"]:focus {
26
+ outline: none;
27
+ }
28
+
29
+ /* Skip to main content link (for screen readers) */
30
+ .skip-to-main {
31
+ @apply absolute -top-full left-0 bg-primary text-white px-4 py-2 rounded z-max;
32
+ transition: top 0.2s;
33
+
34
+ &:focus {
35
+ @apply top-0;
36
+ }
37
+ }
@@ -2,7 +2,8 @@
2
2
  BUTTON COMPONENTS - Shadcn-Inspired Design
3
3
  ========================================================================== */
4
4
 
5
- /* Primary Button - Solid green with clean shadow */
5
+ @use "../base/mixins" as *;
6
+
6
7
  .btn-primary {
7
8
  @apply font-medium transition-all duration-150;
8
9
  @apply bg-accent-green text-white;
@@ -15,11 +16,10 @@
15
16
 
16
17
  &:active {
17
18
  @apply bg-green-500 border-accent-green;
18
- @apply outline outline-1 outline-accent-green outline-offset-0;
19
+ @include focus-ring-accent;
19
20
  }
20
21
  }
21
22
 
22
- /* Secondary Button - Transparent with green border, fills on hover */
23
23
  .btn-secondary {
24
24
  @apply font-medium transition-all duration-150;
25
25
  @apply bg-transparent text-accent-green;
@@ -32,11 +32,10 @@
32
32
 
33
33
  &:active {
34
34
  @apply bg-green-400 border-accent-green;
35
- @apply outline outline-1 outline-accent-green outline-offset-0;
35
+ @include focus-ring-accent;
36
36
  }
37
37
  }
38
38
 
39
- /* Ghost Button - No border, muted text, subtle hover */
40
39
  .btn-ghost {
41
40
  @apply font-medium transition-all duration-150;
42
41
  @apply bg-transparent text-light-400;
@@ -52,7 +51,6 @@
52
51
  }
53
52
  }
54
53
 
55
- /* Destructive Button - Red with clean shadow */
56
54
  .btn-danger,
57
55
  .btn-destructive {
58
56
  @apply font-medium transition-all duration-150;
@@ -69,7 +67,6 @@
69
67
  }
70
68
  }
71
69
 
72
- /* Icon Button - Clean hover states */
73
70
  .btn-icon {
74
71
  @apply flex items-center justify-center transition-all duration-150;
75
72
  @apply p-1 rounded-md;
@@ -85,7 +82,6 @@
85
82
  }
86
83
  }
87
84
 
88
- /* Action Button - Similar to secondary but with specific sizing */
89
85
  .btn-action {
90
86
  @apply font-medium flex items-center justify-center gap-x-2 transition-all duration-150;
91
87
  @apply bg-transparent text-accent-green;
@@ -99,20 +95,19 @@
99
95
 
100
96
  &:active {
101
97
  @apply bg-green-400 border-accent-green;
102
- @apply outline outline-1 outline-accent-green outline-offset-0;
98
+ @include focus-ring-accent;
103
99
  }
104
100
  }
105
101
 
106
- /* Default Button - Base styling */
107
102
  .button-default {
108
103
  @apply font-medium transition-all duration-150 flex items-center justify-center gap-x-2;
109
- @apply h-14 rounded-lg text-white border-2 border-dark-600 text-sm px-6 w-48;
104
+ @apply h-14 rounded-lg text-white border-2 border-dark-550 text-sm px-6 w-48;
110
105
 
111
106
  svg {
112
107
  @apply w-4 h-4 flex-shrink-0;
113
108
  }
114
109
 
115
- @media (max-width: 768px) {
110
+ @screen md {
116
111
  @apply h-12 text-sm font-medium w-full max-w-full;
117
112
 
118
113
  svg {
@@ -120,8 +115,8 @@
120
115
  }
121
116
  }
122
117
 
123
- @media (max-width: 480px) {
124
- @apply h-[3.25rem] text-[0.9375rem];
118
+ @screen mobile-portrait {
119
+ @apply h-13;
125
120
 
126
121
  svg {
127
122
  @apply w-4 h-4;
@@ -134,7 +129,42 @@
134
129
 
135
130
  &:active, &:focus {
136
131
  @apply border-accent-green;
137
- @apply outline outline-1 outline-accent-green outline-offset-0;
132
+ @include focus-ring-accent;
133
+ }
134
+ }
135
+
136
+ .btn-focus-ring {
137
+ &:active {
138
+ @apply border-accent-green;
139
+ @include focus-ring-accent;
140
+ }
141
+
142
+ &:focus {
143
+ @apply border-accent-green;
144
+ @include focus-ring-accent;
145
+ }
146
+ }
147
+
148
+ .login-btn {
149
+ @apply flex items-center justify-center gap-2;
150
+ @apply h-12 rounded-lg font-semibold tracking-wider uppercase;
151
+ @apply bg-accent-green border-2 border-accent-green text-white;
152
+ @apply transition-all duration-150;
153
+ font-size: theme('fontSize.base-');
154
+
155
+ &:hover:enabled {
156
+ @apply bg-green-500 border-green-500;
157
+ transform: translateY(-1px);
158
+ box-shadow: 0 4px 12px rgb(from theme('colors.accent.green') r g b / 0.3);
159
+ }
160
+
161
+ &:active:enabled {
162
+ transform: translateY(0);
163
+ box-shadow: 0 2px 4px rgb(from theme('colors.accent.green') r g b / 0.2);
164
+ }
165
+
166
+ &:disabled {
167
+ @apply opacity-70 cursor-not-allowed;
138
168
  }
139
169
  }
140
170
 
@@ -162,3 +192,16 @@
162
192
  border-radius: 8px;
163
193
  }
164
194
  }
195
+
196
+ /* ==========================================================================
197
+ MODAL/ACTION BUTTON UTILITIES
198
+ ========================================================================== */
199
+
200
+ .btn-modal {
201
+ @apply h-10 rounded-md text-xs flex items-center justify-center;
202
+ @apply font-medium px-4;
203
+ @apply hover:border-dark-700 transition-all duration-150 btn-focus-ring;
204
+ @include dark-button-base;
205
+ @include scale-hover;
206
+ }
207
+
@@ -4,33 +4,32 @@
4
4
 
5
5
  .input-default {
6
6
  @apply relative box-border flex h-10 items-center border-2 bg-clip-padding px-3 py-2;
7
- background: oklch(0.19 0 0);
8
- border-color: oklch(0.26 0 0);
7
+ background: var(--color-bg-input);
8
+ border-color: var(--color-border);
9
9
  border-radius: 0.5rem;
10
10
  transition: border-color 0.15s ease;
11
11
 
12
12
  &:hover {
13
- border-color: oklch(0.3 0 0);
13
+ @apply border-dark-650;
14
14
  }
15
15
 
16
16
  &:focus-within {
17
- border-color: oklch(0.72 0.15 145);
17
+ border-color: var(--color-primary);
18
18
  }
19
19
 
20
20
  input {
21
21
  @apply h-full w-full text-sm;
22
22
  background: transparent;
23
- color: oklch(0.95 0 0);
23
+ color: var(--color-text-vivid);
24
24
 
25
25
  &:focus {
26
26
  outline: none;
27
27
  }
28
28
 
29
29
  &::placeholder {
30
- color: oklch(0.5 0 0);
30
+ color: var(--color-text-muted);
31
31
  }
32
32
 
33
- // Hide default number input spinners - use custom .input-incrementer instead
34
33
  &[type="number"]::-webkit-inner-spin-button,
35
34
  &[type="number"]::-webkit-outer-spin-button {
36
35
  -webkit-appearance: none;
@@ -48,21 +47,21 @@
48
47
 
49
48
  button {
50
49
  @apply w-6 h-4 flex items-center justify-center text-white transition-all duration-200 rounded-sm;
51
- background: linear-gradient(135deg, oklch(0.19 0 0) 0%, oklch(0.20 0 0) 100%);
52
- border: 1px solid oklch(0.22 0 0);
53
- box-shadow: 0 1px 2px oklch(0 0 0 / 0.2);
50
+ background: linear-gradient(135deg, var(--color-bg-darker) 0%, var(--color-bg-darker-alt) 100%);
51
+ border: 1px solid var(--color-gradient-start);
52
+ @apply shadow-button;
54
53
 
55
54
  &:hover {
56
- background: linear-gradient(135deg, oklch(0.20 0 0) 0%, oklch(0.23 0 0) 100%);
57
- border-color: oklch(0.28 0 0);
58
- box-shadow: 0 2px 4px oklch(0 0 0 / 0.3);
55
+ background: linear-gradient(135deg, var(--color-bg-darker-alt) 0%, var(--color-gradient-mid) 100%);
56
+ border-color: var(--color-border-light);
57
+ @apply shadow-md;
59
58
  transform: translateY(-0.5px);
60
59
  }
61
60
 
62
61
  &:active {
63
- background: linear-gradient(135deg, oklch(0.15 0 0) 0%, oklch(0.19 0.02 264) 100%);
64
- border-color: oklch(0.26 0 0);
65
- box-shadow: inset 0 1px 2px oklch(0 0 0 / 0.3);
62
+ background: linear-gradient(135deg, var(--color-bg-modal) 0%, var(--color-gradient-blue-tint) 100%);
63
+ border-color: var(--color-border);
64
+ @apply shadow-input-inset;
66
65
  transform: translateY(0);
67
66
  }
68
67
 
@@ -87,27 +86,27 @@
87
86
  ========================================================================== */
88
87
 
89
88
  .ant-select-dropdown {
90
- z-index: 10000 !important;
89
+ z-index: var(--z-modal) !important;
91
90
  position: relative;
92
- background: oklch(0.15 0 0) !important; /* Card backgrounds */
91
+ background: var(--color-bg-modal) !important;
93
92
  border-radius: 0.5rem !important;
94
93
  }
95
94
 
96
95
  .ant-select {
97
96
  @apply relative box-border flex h-10 items-center border-2 bg-clip-padding px-1 py-1 !important;
98
- background: oklch(0.19 0 0); /* Input background */
99
- border-color: oklch(0.26 0 0); /* Default border */
100
- border-radius: 0.375rem; /* Consistent with buttons */
97
+ background: var(--color-bg-input);
98
+ border-color: var(--color-border);
99
+ border-radius: 0.375rem;
101
100
  height: fit-content;
102
101
  transition: border-color 0.15s ease;
103
102
 
104
103
  &:hover {
105
- border-color: oklch(0.3 0 0); /* Hover border */
104
+ @apply border-dark-650;
106
105
  }
107
106
 
108
107
  &.ant-select-focused {
109
- border-color: oklch(0.72 0.15 145) !important; /* Focus border - cyan */
110
- outline: 1px solid oklch(0.72 0.15 145) !important; /* Cyan outline, no offset */
108
+ border-color: var(--color-primary) !important;
109
+ outline: 1px solid var(--color-primary) !important;
111
110
  outline-offset: 0 !important;
112
111
  }
113
112
 
@@ -125,7 +124,7 @@
125
124
  &:before {
126
125
  content: "";
127
126
  position: absolute;
128
- background: oklch(0.82 0 0);
127
+ background: var(--color-text-secondary);
129
128
  height: 0.25rem;
130
129
  width: 0.25rem;
131
130
  right: 0.25rem;
@@ -136,13 +135,13 @@
136
135
 
137
136
  .ant-select-multiple .ant-select-selection-item {
138
137
  @apply items-center gap-x-4 !important;
139
- background: oklch(0.15 0 0); /* Card backgrounds */
138
+ background: var(--color-bg-modal);
140
139
  padding-inline-end: 15px;
141
140
  padding-inline-start: 15px;
142
141
  border-radius: 10px;
143
142
  height: 40px;
144
143
  border: 0;
145
- color: oklch(0.98 0 0); /* White text */
144
+ color: var(--color-text-almost-white);
146
145
 
147
146
  &-remove > .anticon {
148
147
  vertical-align: 0.05rem;
@@ -150,7 +149,7 @@
150
149
  }
151
150
 
152
151
  .ant-select-selection-item-remove > .anticon svg {
153
- color: oklch(0.98 0 0); /* White */
152
+ color: var(--color-text-almost-white);
154
153
 
155
154
  path {
156
155
  fill: currentColor;
@@ -160,10 +159,10 @@
160
159
  .ant-select-item-option {
161
160
  &-selected:not(.ant-select-item-option-disabled) {
162
161
  @apply text-white !important;
163
- background: oklch(0.72 0.15 145 / 0.15) !important; /* Cyan accent with transparency */
162
+ background: oklch(from var(--color-primary) l c h / 0.15) !important;
164
163
 
165
164
  .ant-select-item-option-state {
166
- color: oklch(0.72 0.15 145) !important; /* Cyan accent for checkmark */
165
+ color: var(--color-primary) !important;
167
166
 
168
167
  svg {
169
168
  margin-top: -1.5px;
@@ -172,11 +171,11 @@
172
171
  }
173
172
 
174
173
  &-active:not(.ant-select-item-option-disabled) {
175
- background: oklch(0.19 0 0); /* Input background on hover */
174
+ background: var(--color-bg-input);
176
175
  }
177
176
 
178
177
  &-content {
179
- color: oklch(0.98 0 0) !important; /* White text */
178
+ color: var(--color-text-almost-white) !important;
180
179
  }
181
180
  }
182
181
 
@@ -0,0 +1,119 @@
1
+ /* ==========================================================================
2
+ PAGE HEADERS
3
+ Ultra-clean, consistent styling for all page headers
4
+ ========================================================================== */
5
+
6
+ .page-header {
7
+ @apply flex items-center justify-between;
8
+ padding-top: 1.5rem;
9
+ padding-bottom: 0.5rem;
10
+
11
+ .page-header-card {
12
+ @apply flex items-center gap-2.5 rounded-lg;
13
+ padding: 0.375rem 0.75rem;
14
+ background: linear-gradient(135deg, var(--color-gradient-start) 0%, var(--color-gradient-end) 100%);
15
+ border: 1px solid var(--color-border-light);
16
+
17
+ svg, img {
18
+ width: 17px;
19
+ height: 17px;
20
+ color: var(--color-text-bright);
21
+ flex-shrink: 0;
22
+ }
23
+
24
+ .icon-button {
25
+ @apply flex items-center justify-center rounded;
26
+ cursor: pointer;
27
+ margin: -0.125rem 0;
28
+ padding: 0.125rem;
29
+ transition: background 0.2s ease;
30
+
31
+ svg, img {
32
+ width: 17px;
33
+ height: 17px;
34
+ color: var(--color-text-bright);
35
+ transition: transform 0.4s ease, color 0.2s ease;
36
+ }
37
+
38
+ &:hover {
39
+ background: var(--color-border);
40
+
41
+ svg, img {
42
+ color: var(--color-text-primary);
43
+ transform: rotate(90deg);
44
+ }
45
+ }
46
+
47
+ &:active {
48
+ background: var(--color-bg-darker-alt);
49
+
50
+ svg, img {
51
+ transform: rotate(180deg);
52
+ }
53
+ }
54
+ }
55
+
56
+ h4 {
57
+ @apply font-semibold;
58
+ font-size: 1rem;
59
+ line-height: 1.2;
60
+ color: var(--color-text-primary);
61
+ letter-spacing: -0.01em;
62
+ }
63
+
64
+ .page-header-count {
65
+ @apply inline-flex items-center justify-center rounded px-1.5 py-0.5 ml-1.5;
66
+ font-size: 0.6875rem;
67
+ font-weight: 600;
68
+ min-width: 20px;
69
+ background: var(--color-bg-darker-alt);
70
+ border: 1px solid var(--color-border);
71
+ color: var(--color-text-dim);
72
+ letter-spacing: 0.01em;
73
+ }
74
+ }
75
+
76
+ @screen sm {
77
+ padding-top: 1rem;
78
+
79
+ .page-header-card {
80
+ gap: 2.5;
81
+ padding: 0.5rem 0.875rem;
82
+
83
+ svg, img {
84
+ width: 18px;
85
+ height: 18px;
86
+ }
87
+
88
+ h4 {
89
+ font-size: 1rem;
90
+ }
91
+
92
+ .page-header-count {
93
+ font-size: 0.6875rem;
94
+ padding: 0.125rem 0.375rem;
95
+ min-width: 20px;
96
+ margin-left: 0.375rem;
97
+ }
98
+ }
99
+ }
100
+
101
+ @media (min-width: 641px) and (max-width: 1024px) {
102
+ .page-header-card {
103
+ svg, img {
104
+ width: 19px;
105
+ height: 19px;
106
+ }
107
+
108
+ h4 {
109
+ font-size: 1.0625rem;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ @media (display-mode: standalone) {
116
+ .page-header {
117
+ padding-top: 3.5rem !important;
118
+ }
119
+ }