@necrolab/dashboard 0.5.13 → 0.5.15

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@necrolab/dashboard",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "rm -rf dist && npx workbox-cli generateSW workbox-config.cjs && vite build",
@@ -0,0 +1,10 @@
1
+ /* ==========================================================================
2
+ OKLCH COLOR FALLBACKS FOR CROSS-DEVICE CONSISTENCY
3
+ Note: iOS 26 Safari renders OKLCH in Display P3, causing color shifts
4
+ Currently no perfect fix - OKLCH support varies by device/gamut
5
+ ========================================================================== */
6
+
7
+ /* Placeholder for future color space fixes */
8
+ :root {
9
+ color-scheme: dark;
10
+ }
@@ -0,0 +1,127 @@
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
+ /* Header card container */
12
+ .page-header-card {
13
+ @apply flex items-center gap-2.5 rounded-lg;
14
+ padding: 0.375rem 0.75rem;
15
+ background: linear-gradient(135deg, oklch(0.22 0 0) 0%, oklch(0.24 0 0) 100%);
16
+ border: 1px solid oklch(0.28 0 0);
17
+
18
+ /* Icon - static by default */
19
+ svg, img {
20
+ width: 17px;
21
+ height: 17px;
22
+ color: oklch(0.85 0 0);
23
+ flex-shrink: 0;
24
+ }
25
+
26
+ /* Clickable icon wrapper - only for Tasks page */
27
+ .icon-button {
28
+ @apply flex items-center justify-center rounded;
29
+ cursor: pointer;
30
+ margin: -0.125rem 0;
31
+ padding: 0.125rem;
32
+ transition: background 0.2s ease;
33
+
34
+ svg, img {
35
+ width: 17px;
36
+ height: 17px;
37
+ color: oklch(0.85 0 0);
38
+ transition: transform 0.4s ease, color 0.2s ease;
39
+ }
40
+
41
+ &:hover {
42
+ background: oklch(0.26 0 0);
43
+
44
+ svg, img {
45
+ color: oklch(0.95 0 0);
46
+ transform: rotate(90deg);
47
+ }
48
+ }
49
+
50
+ &:active {
51
+ background: oklch(0.20 0 0);
52
+
53
+ svg, img {
54
+ transform: rotate(180deg);
55
+ }
56
+ }
57
+ }
58
+
59
+ /* Title text */
60
+ h4 {
61
+ @apply font-semibold;
62
+ font-size: 1rem;
63
+ line-height: 1.2;
64
+ color: oklch(0.95 0 0);
65
+ letter-spacing: -0.01em;
66
+ }
67
+
68
+ /* Count badge - only for Tasks page */
69
+ .page-header-count {
70
+ @apply inline-flex items-center justify-center rounded px-1.5 py-0.5 ml-1.5;
71
+ font-size: 0.6875rem;
72
+ font-weight: 600;
73
+ min-width: 20px;
74
+ background: oklch(0.20 0 0);
75
+ border: 1px solid oklch(0.26 0 0);
76
+ color: oklch(0.70 0 0);
77
+ letter-spacing: 0.01em;
78
+ }
79
+ }
80
+
81
+ /* Mobile responsive */
82
+ @media (max-width: 640px) {
83
+ padding-top: 1rem;
84
+
85
+ .page-header-card {
86
+ gap: 2.5;
87
+ padding: 0.5rem 0.875rem;
88
+
89
+ svg, img {
90
+ width: 18px;
91
+ height: 18px;
92
+ }
93
+
94
+ h4 {
95
+ font-size: 1rem;
96
+ }
97
+
98
+ .page-header-count {
99
+ font-size: 0.6875rem;
100
+ padding: 0.125rem 0.375rem;
101
+ min-width: 20px;
102
+ margin-left: 0.375rem;
103
+ }
104
+ }
105
+ }
106
+
107
+ /* Tablet responsive */
108
+ @media (min-width: 641px) and (max-width: 1024px) {
109
+ .page-header-card {
110
+ svg, img {
111
+ width: 19px;
112
+ height: 19px;
113
+ }
114
+
115
+ h4 {
116
+ font-size: 1.0625rem;
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ /* PWA mode adjustments */
123
+ @media (display-mode: standalone) {
124
+ .page-header {
125
+ padding-top: 3.5rem !important;
126
+ }
127
+ }
@@ -22,6 +22,9 @@
22
22
  background: transparent !important;
23
23
  box-shadow: none !important;
24
24
  min-width: fit-content !important;
25
+ outline: none !important;
26
+ outline-width: 0 !important;
27
+ outline-offset: 0 !important;
25
28
  }
26
29
 
27
30
  .tag-toggle {
@@ -7,17 +7,25 @@
7
7
  @use "base/reset";
8
8
  @use "base/scroll";
9
9
  @use "base/typography";
10
+ @use "base/color-fallbacks";
10
11
  @use "components/buttons";
11
12
  @use "components/forms";
12
13
  @use "components/toasts";
13
14
  @use "components/modals";
14
15
  @use "components/tables";
15
16
  @use "components/search-groups";
17
+ @use "components/headers";
16
18
 
17
19
  /* ==========================================================================
18
20
  BODY LAYOUT & BACKGROUND
19
21
  ========================================================================== */
20
22
 
23
+ html {
24
+ background-color: oklch(0.1822 0 0);
25
+ min-height: 100vh;
26
+ min-height: 100dvh;
27
+ }
28
+
21
29
  body {
22
30
  background-color: oklch(0.1822 0 0);
23
31
  position: relative;
@@ -5,20 +5,75 @@
5
5
  </template>
6
6
  <style lang="scss">
7
7
  .table-component {
8
- @apply flex-col bg-clip-padding rounded relative box-border border border-dark-600 bg-dark-500;
9
- @apply overflow-x-auto overflow-y-auto touch-pan-x touch-pan-y;
8
+ @apply relative box-border flex flex-col rounded-lg border border-dark-600 bg-dark-500 bg-clip-padding;
9
+ @apply overflow-x-auto overflow-y-auto;
10
10
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
11
11
  overscroll-behavior: auto;
12
- max-height: calc(100vh - 200px);
12
+ max-height: calc(100vh - 300px);
13
13
  -webkit-overflow-scrolling: touch;
14
+ touch-action: pan-x pan-y;
15
+
16
+ /* iPad Pro and larger tablets - more space for UTILS */
17
+ @media (min-width: 768px) and (max-width: 1440px) {
18
+ max-height: calc(100vh - 400px);
19
+ }
20
+
21
+ /* iPad portrait - even more space needed */
22
+ @media (min-width: 768px) and (max-width: 1100px) and (orientation: portrait) {
23
+ max-height: calc(100vh - 450px);
24
+ }
25
+
26
+ /* PWA mode - account for status bar and home indicator */
27
+ @media (display-mode: standalone) {
28
+ max-height: calc(100vh - 420px);
29
+
30
+ @media (min-width: 768px) and (max-width: 1440px) {
31
+ max-height: calc(100vh - 480px);
32
+ }
33
+
34
+ /* iPad portrait PWA - maximum space for UTILS */
35
+ @media (min-width: 768px) and (max-width: 1100px) and (orientation: portrait) {
36
+ max-height: calc(100vh - 500px);
37
+ }
38
+ }
14
39
  }
15
40
 
16
- .table-component > .grid {
17
- @apply bg-dark-400;
41
+ .table-component > .grid:not(:first-child) {
18
42
  border-bottom: 1px solid oklch(0.26 0 0);
19
43
  // Only enforce min-width on desktop, allow mobile to fit screen
20
44
  @media (min-width: 768px) {
21
45
  min-width: 640px;
22
46
  }
23
47
  }
48
+
49
+ /* Remove border from last row */
50
+ .table-component > .grid:last-child {
51
+ border-bottom: none;
52
+ }
53
+
54
+ /* Odd rows (lighter) */
55
+ .table-component > .grid:nth-child(odd) {
56
+ @apply bg-dark-300;
57
+ }
58
+
59
+ /* Even rows (darker) */
60
+ .table-component > .grid:nth-child(even) {
61
+ @apply bg-dark-400;
62
+ }
63
+
64
+ /* First grid child (header) keeps its own background */
65
+ .table-component > .grid:first-child {
66
+ border-bottom: 1px solid oklch(0.26 0 0);
67
+ @apply rounded-t-lg;
68
+ overflow: hidden;
69
+ @media (min-width: 768px) {
70
+ min-width: 640px;
71
+ }
72
+ }
73
+
74
+ /* Last row rounded bottom corners */
75
+ .table-component > .grid:last-child {
76
+ @apply rounded-b-lg;
77
+ overflow: hidden;
78
+ }
24
79
  </style>
@@ -24,15 +24,17 @@ const ui = useUIStore();
24
24
  </script>
25
25
  <style lang="scss" scoped>
26
26
  .utilities-wrapper {
27
+ margin-bottom: 2rem;
28
+
27
29
  // Add extra margin on mobile to prevent buttons from being cut off
28
30
  @media (max-width: 768px) {
29
31
  margin-top: 1rem;
30
- margin-bottom: 1.5rem;
32
+ margin-bottom: 2.5rem;
31
33
  }
32
34
  }
33
35
 
34
36
  .utility-btn {
35
- height: 50px;
37
+ height: 42px;
36
38
 
37
39
  @media (max-width: 768px) {
38
40
  height: 40px;
@@ -78,7 +78,8 @@ const handleCopy = () => {
78
78
 
79
79
  .info-value {
80
80
  @apply text-sm flex-1 text-light-300;
81
- @apply break-words;
81
+ @apply break-words overflow-hidden;
82
+ min-width: 0; // Allow flex item to shrink below content size
82
83
 
83
84
  @media (max-width: 768px) {
84
85
  @apply text-[13px];
@@ -90,6 +91,7 @@ const handleCopy = () => {
90
91
  @apply w-8 h-8 rounded transition-all duration-150;
91
92
  @apply bg-transparent text-light-500 hover:text-light-300 hover:bg-dark-600;
92
93
  @apply flex-shrink-0;
94
+ @apply ml-2; // Ensure spacing from value
93
95
 
94
96
  &.copied {
95
97
  @apply text-accent-green;
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div class="modal-mask fixed inset-0 z-modal bg-overlay-dark backdrop-blur-xs flex pt-14 scrollable overflow-y-auto" role="dialog" @touchmove.stop>
3
- <div class="component-modal mb-8 mobile-portrait:mb-16" ref="target">
2
+ <div class="modal-mask fixed inset-0 z-modal bg-overlay-dark backdrop-blur-xs flex scrollable overflow-y-auto" role="dialog" @touchmove.stop>
3
+ <div class="component-modal" ref="target">
4
4
  <div class="modal-header">
5
5
  <slot name="header" />
6
6
  <button @click="ui.toggleModal()" class="btn-icon border-none hover:bg-dark-400">
@@ -24,30 +24,16 @@ const target = ref(null);
24
24
 
25
25
  // Store original body styles
26
26
  let originalOverflow = "";
27
- let originalPosition = "";
28
- let originalTop = "";
29
- let scrollY = 0;
30
27
 
31
28
  onMounted(() => {
32
- // Lock body scroll
33
- scrollY = window.scrollY;
29
+ // Lock body scroll - simple overflow approach
34
30
  originalOverflow = document.body.style.overflow;
35
- originalPosition = document.body.style.position;
36
- originalTop = document.body.style.top;
37
-
38
31
  document.body.style.overflow = "hidden";
39
- document.body.style.position = "fixed";
40
- document.body.style.top = `-${scrollY}px`;
41
- document.body.style.width = "100%";
42
32
  });
43
33
 
44
34
  onUnmounted(() => {
45
35
  // Restore body scroll
46
- document.body.style.overflow = originalOverflow;
47
- document.body.style.position = originalPosition;
48
- document.body.style.top = originalTop;
49
- document.body.style.width = "";
50
- window.scrollTo(0, scrollY);
36
+ document.body.style.overflow = originalOverflow || "";
51
37
  });
52
38
 
53
39
  onClickOutside(target, (event) => {
@@ -59,7 +45,7 @@ onClickOutside(target, (event) => {
59
45
  @apply w-screen duration-300 ease-in-out;
60
46
  align-items: flex-start;
61
47
  justify-content: center;
62
- padding: 1rem;
48
+ padding: 2rem 1rem 4rem 1rem !important; /* More bottom padding for scrollable space */
63
49
  height: 100dvh;
64
50
  overflow-y: auto;
65
51
  -webkit-overflow-scrolling: touch;
@@ -89,17 +75,20 @@ onClickOutside(target, (event) => {
89
75
  }
90
76
  }
91
77
 
78
+ /* Desktop - extra bottom padding for scrollable space */
79
+ @media (min-width: 811px) {
80
+ .modal-mask {
81
+ padding: 2rem 1rem 6rem 1rem !important;
82
+ }
83
+ }
84
+
92
85
  @media (max-width: 810px) {
93
86
  .modal-mask {
94
- align-items: flex-start;
95
- justify-content: center;
96
- padding: 1rem;
97
- padding-top: 3rem;
87
+ padding: 3rem 1rem !important; /* Mobile: more padding */
98
88
  }
99
89
 
100
90
  .component-modal {
101
91
  width: calc(100vw - 2rem);
102
- margin-bottom: 3rem;
103
92
  }
104
93
 
105
94
  .modal-body {
@@ -109,10 +98,29 @@ onClickOutside(target, (event) => {
109
98
  }
110
99
  }
111
100
 
112
- /* iPhone portrait mode - extra spacing for create button */
101
+ /* iPhone portrait mode - extra bottom spacing */
113
102
  @media (max-width: 480px) and (orientation: portrait) {
103
+ .modal-mask {
104
+ padding-bottom: 4rem !important;
105
+ }
106
+
114
107
  .component-modal {
115
108
  max-height: none;
116
109
  }
117
110
  }
111
+
112
+ /* PWA mode - extra spacing for iPhone status bar and home indicator */
113
+ @media (display-mode: standalone) {
114
+ .modal-mask {
115
+ padding-top: 3rem !important;
116
+ padding-bottom: 6rem !important;
117
+ }
118
+
119
+ @media (max-width: 810px) {
120
+ .modal-mask {
121
+ padding-top: 4rem !important;
122
+ padding-bottom: 5rem !important;
123
+ }
124
+ }
125
+ }
118
126
  </style>
@@ -13,19 +13,17 @@
13
13
  class="dropdown-menu-portal scrollable"
14
14
  :style="menuStyle"
15
15
  @click.stop
16
- @wheel.stop
17
- @touchmove.stop>
16
+ @wheel.stop>
18
17
  <button
19
18
  v-bind:key="f"
20
19
  class="dropdown-item"
21
20
  :class="i !== 0 ? 'border-t border-dark-650' : ''"
22
21
  v-for="(f, i) in !allowDefault ? props.options : ['', ...props.options]"
23
- @mousedown.prevent.stop="chose(f)"
24
- @touchstart.prevent.stop="chose(f)">
22
+ @click.prevent.stop="chose(f)">
23
+ <CheckmarkIcon v-if="(f || props.default) === currentValue" class="mr-2 flex-shrink-0" />
25
24
  <span class="dropdown-item-text" :class="capitalize ? 'capitalize' : ''">
26
25
  {{ f ? f : props.default }}
27
26
  </span>
28
- <CheckmarkIcon v-if="(f || props.default) === currentValue" class="ml-2" />
29
27
  </button>
30
28
  </div>
31
29
  </transition>
@@ -68,11 +66,11 @@ const id = Math.random();
68
66
  const opened = computed(() => ui.currentDropdown === id);
69
67
 
70
68
  const { menuStyle, updatePosition } = useDropdownPosition(dropdownRef, {
71
- maxHeight: 200,
69
+ maxHeight: Math.floor(window.innerHeight * 0.85), // 85% of viewport
72
70
  includeAdjacentButtons: props.includeAdjacentButtons,
73
71
  estimateHeight: () => {
74
72
  const optionsCount = !props.allowDefault ? props.options?.length || 0 : (props.options?.length || 0) + 1;
75
- return Math.min(optionsCount * 44, 200);
73
+ return Math.min(optionsCount * 44, Math.floor(window.innerHeight * 0.85));
76
74
  }
77
75
  });
78
76
 
@@ -104,6 +102,39 @@ const toggleOpened = () => {
104
102
  } else {
105
103
  ui.setCurrentDropdown(id);
106
104
  updatePosition();
105
+ // Set all items to same width only if horizontal scrolling is needed
106
+ setTimeout(() => {
107
+ const portal = document.querySelector('.dropdown-menu-portal');
108
+ const items = portal?.querySelectorAll('.dropdown-item');
109
+ if (items && items.length > 0) {
110
+ let maxWidth = 0;
111
+ // Reset styles first to get accurate measurements
112
+ items.forEach(item => {
113
+ item.style.width = '';
114
+ item.style.minWidth = '';
115
+ });
116
+ portal.style.overflowX = '';
117
+
118
+ // Measure actual content width
119
+ items.forEach(item => {
120
+ const contentWidth = item.scrollWidth;
121
+ maxWidth = Math.max(maxWidth, contentWidth);
122
+ });
123
+
124
+ // Only enable horizontal scrolling if content is truly wider than the max allowed width
125
+ const maxAllowedWidth = Math.min(400, window.innerWidth * 0.9);
126
+ if (maxWidth > maxAllowedWidth) {
127
+ // Enable horizontal scrolling for long items
128
+ portal.style.overflowX = 'auto';
129
+ items.forEach(item => {
130
+ item.style.minWidth = maxWidth + 'px';
131
+ });
132
+ } else {
133
+ // Normal display - no horizontal scrolling needed
134
+ portal.style.overflowX = 'hidden';
135
+ }
136
+ }
137
+ }, 50);
107
138
  }
108
139
  };
109
140
 
@@ -157,6 +188,7 @@ const chose = (f) => {
157
188
 
158
189
  .dropdown-value {
159
190
  @apply overflow-hidden truncate min-w-0 flex-1 mr-2 text-sm;
191
+ padding-right: 2rem; /* Extra space to prevent collision with arrow */
160
192
  }
161
193
 
162
194
  @media (min-width: 768px) {
@@ -177,17 +209,22 @@ const chose = (f) => {
177
209
  }
178
210
 
179
211
  .dropdown-menu-portal {
180
- @apply rounded-xl shadow-2xl bg-dark-300 border border-dark-600 overflow-x-auto overflow-y-auto touch-pan-x touch-pan-y;
212
+ @apply rounded-xl shadow-2xl bg-dark-300 border border-dark-600;
181
213
  backdrop-filter: blur(12px);
182
214
  box-shadow: 0 20px 25px -5px oklch(0 0 0 / 0.4), 0 10px 10px -5px oklch(0 0 0 / 0.2),
183
215
  0 0 0 1px oklch(1 0 0 / 0.05);
216
+ overflow-x: hidden;
217
+ overflow-y: auto;
184
218
  overscroll-behavior: contain;
185
219
  -webkit-overflow-scrolling: touch;
220
+ touch-action: pan-y;
186
221
  scrollbar-width: thin;
187
222
  scrollbar-color: oklch(0.35 0 0) oklch(0.19 0 0);
188
223
  z-index: 1000;
189
224
  min-width: 200px;
190
- max-width: 90vw;
225
+ max-width: min(400px, 90vw);
226
+ display: flex;
227
+ flex-direction: column;
191
228
  }
192
229
 
193
230
  .dropdown-menu-portal::-webkit-scrollbar {
@@ -209,11 +246,16 @@ const chose = (f) => {
209
246
  }
210
247
 
211
248
  .dropdown-item {
212
- @apply cursor-pointer text-left w-full text-white transition-all duration-200 flex items-center justify-between;
249
+ @apply cursor-pointer text-left text-white transition-all duration-200;
213
250
  padding: 0.75rem 1rem;
214
251
  font-size: 0.875rem;
215
252
  font-weight: 500;
216
253
  border-bottom: 1px solid rgba(61, 62, 68, 0.3);
254
+ display: flex !important;
255
+ align-items: center;
256
+ gap: 1rem;
257
+ width: 100%;
258
+ flex-shrink: 0;
217
259
  }
218
260
 
219
261
  .dropdown-item:last-child {
@@ -221,7 +263,7 @@ const chose = (f) => {
221
263
  }
222
264
 
223
265
  .dropdown-item:hover {
224
- @apply bg-dark-600;
266
+ background: oklch(0.2809 0 0) !important; /* Full width background */
225
267
  color: oklch(1 0 0);
226
268
  }
227
269
 
@@ -244,9 +286,10 @@ const chose = (f) => {
244
286
  }
245
287
 
246
288
  .dropdown-item-text {
247
- @apply pr-2;
289
+ @apply pr-2 flex-1;
248
290
  white-space: nowrap;
249
- overflow: visible;
291
+ overflow: hidden;
292
+ text-overflow: ellipsis;
250
293
  }
251
294
 
252
295
  .dropdown-item svg {
@@ -18,8 +18,7 @@
18
18
  class="dropdown-menu-portal multi scrollable"
19
19
  :style="menuStyle"
20
20
  @click.stop
21
- @wheel.stop
22
- @touchmove.stop>
21
+ @wheel.stop>
23
22
  <div class="option-list scrollable">
24
23
  <button
25
24
  v-for="(option, i) in props.options"
@@ -133,6 +132,33 @@ const toggleOpened = () => {
133
132
  } else {
134
133
  ui.setCurrentDropdown(id);
135
134
  updatePosition();
135
+ // Set all items to same width only if horizontal scrolling is needed
136
+ setTimeout(() => {
137
+ const portal = document.querySelector('.dropdown-menu-portal');
138
+ const items = portal?.querySelectorAll('.dropdown-item');
139
+ if (items && items.length > 0) {
140
+ let maxWidth = 0;
141
+ items.forEach(item => {
142
+ item.style.width = 'max-content';
143
+ maxWidth = Math.max(maxWidth, item.scrollWidth);
144
+ });
145
+
146
+ // Only set explicit widths if content is wider than container
147
+ if (maxWidth > portal.offsetWidth) {
148
+ // Enable horizontal scrolling for long items
149
+ portal.style.overflowX = 'auto';
150
+ items.forEach(item => {
151
+ item.style.width = maxWidth + 'px';
152
+ });
153
+ } else {
154
+ // Disable horizontal scrolling for short items
155
+ portal.style.overflowX = 'hidden';
156
+ items.forEach(item => {
157
+ item.style.width = '100%';
158
+ });
159
+ }
160
+ }
161
+ }, 50);
136
162
  }
137
163
  };
138
164
 
@@ -6,7 +6,7 @@ export function useDropdownPosition(dropdownRef, options = {}) {
6
6
  offset = { x: -1, y: 4 },
7
7
  zIndex = 50000,
8
8
  minWidth = null,
9
- maxHeight = 160,
9
+ maxHeight = window.innerHeight * 0.8, // Use 80% of viewport height
10
10
  estimateHeight = null,
11
11
  includeAdjacentButtons = false,
12
12
  containerSelector = null
@@ -24,7 +24,7 @@ export function useDropdownPosition(dropdownRef, options = {}) {
24
24
  const menuHeight = estimateHeight ? estimateHeight() : maxHeight;
25
25
 
26
26
  // Calculate width including adjacent buttons if specified
27
- let menuWidth = minWidth || rect.width + 2;
27
+ let menuWidth = minWidth || rect.width;
28
28
 
29
29
  if (includeAdjacentButtons) {
30
30
  // Look for parent container with buttons
@@ -1,12 +1,9 @@
1
1
  <template>
2
2
  <div>
3
- <div class="flex items-center justify-between pt-5 pb-2">
4
- <div class="flex items-center justify-center gap-4">
5
- <MailIcon class="cursor-pointer smooth-hover text-white" />
6
- <h4 class="text-base font-semibold text-light-300">
7
- Accounts
8
- <span class="text-sm font-medium text-light-400 pl-1">{{ ui.getSelectedAccounts().length }}</span>
9
- </h4>
3
+ <div class="page-header">
4
+ <div class="page-header-card">
5
+ <MailIcon />
6
+ <h4>Accounts</h4>
10
7
  </div>
11
8
  <ul class="mobile-icons">
12
9
  <li>
@@ -1,9 +1,11 @@
1
1
  <template>
2
2
  <div class="console-page">
3
- <h4 class="mb-2 flex items-center gap-2 pt-5 text-sm font-bold text-white lg:mt-1">
4
- Console
5
- <ConsoleIcon />
6
- </h4>
3
+ <div class="page-header" style="padding-bottom: 0.75rem;">
4
+ <div class="page-header-card">
5
+ <ConsoleIcon />
6
+ <h4>Console</h4>
7
+ </div>
8
+ </div>
7
9
 
8
10
  <div>
9
11
  <div class="mb-3 flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
@@ -1,10 +1,12 @@
1
1
  <template>
2
2
  <div>
3
3
  <!-- Heading -->
4
- <h4 class="text-white text-xl font-bold mb-5 pt-5 flex gap-2 items-center">
5
- Editor
6
- <img src="@/assets/img/pencil.svg" />
7
- </h4>
4
+ <div class="page-header" style="padding-bottom: 1.25rem;">
5
+ <div class="page-header-card">
6
+ <img src="@/assets/img/pencil.svg" />
7
+ <h4>Editor</h4>
8
+ </div>
9
+ </div>
8
10
 
9
11
  <div class="bg-dark-400 border border-dark-650 rounded shadow-sm p-2">
10
12
  <!-- Admin Editor Section - Hidden when proxy editor is open -->