@necrolab/dashboard 0.5.1 → 0.5.2

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/index.html CHANGED
@@ -8,6 +8,8 @@
8
8
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
9
9
  />
10
10
  <meta name="description" content="Necro Lab - dashboard" />
11
+ <meta name="darkreader-lock" />
12
+ <meta name="color-scheme" content="dark" />
11
13
  <title>Necro Lab - Dashboard</title>
12
14
  <!-- DNS prefetch for external resources -->
13
15
  <link rel="dns-prefetch" href="https://fonts.googleapis.com" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@necrolab/dashboard",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "rm -rf dist && npx workbox-cli generateSW workbox-config.cjs && vite build",
Binary file
@@ -1,5 +1,5 @@
1
1
  /* ==========================================================================
2
- NECRO DASHBOARD - MAIN STYLES
2
+ NECRO DASHBOARD
3
3
  Modular SCSS architecture with @use imports
4
4
  ========================================================================== */
5
5
 
@@ -47,14 +47,14 @@ img {
47
47
 
48
48
  /* Global icon color consistency */
49
49
  svg {
50
- color: oklch(0.90 0 0) !important;
50
+ color: oklch(0.9 0 0) !important;
51
51
  }
52
52
 
53
53
  /* For stroke icons (Eye, etc) - stroke on svg element */
54
54
  svg[stroke] path,
55
55
  svg[stroke] circle,
56
56
  svg[stroke] line {
57
- stroke: oklch(0.90 0 0) !important;
57
+ stroke: oklch(0.9 0 0) !important;
58
58
  }
59
59
 
60
60
  /* For filled icons with explicit fill */
@@ -62,7 +62,7 @@ svg path[fill]:not([fill="none"]),
62
62
  svg circle[fill]:not([fill="none"]),
63
63
  svg rect[fill]:not([fill="none"]),
64
64
  svg polygon[fill]:not([fill="none"]) {
65
- fill: oklch(0.90 0 0) !important;
65
+ fill: oklch(0.9 0 0) !important;
66
66
  }
67
67
 
68
68
  /* For filled icons without explicit fill attribute */
@@ -70,7 +70,7 @@ svg:not([stroke]):not([fill="none"]) path:not([fill]),
70
70
  svg:not([stroke]):not([fill="none"]) circle:not([fill]),
71
71
  svg:not([stroke]):not([fill="none"]) rect:not([fill]),
72
72
  svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
73
- fill: oklch(0.90 0 0) !important;
73
+ fill: oklch(0.9 0 0) !important;
74
74
  }
75
75
 
76
76
  /* ==========================================================================
@@ -82,31 +82,32 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
82
82
  }
83
83
 
84
84
  .status-indicator {
85
- @apply w-2 h-2 rounded-full flex-shrink-0;
85
+ @apply h-2 w-2 flex-shrink-0 rounded-full;
86
86
  min-width: 4px;
87
87
  min-height: 4px;
88
88
  }
89
89
 
90
90
  .mobile-icons {
91
- @apply flex lg:hidden ml-auto items-center gap-x-2;
91
+ @apply ml-auto flex items-center gap-x-2 lg:hidden;
92
92
 
93
93
  button {
94
- @apply w-8 h-8 flex items-center justify-center rounded transition-all duration-150;
94
+ @apply flex h-8 w-8 items-center justify-center rounded transition-all duration-150;
95
95
  background-color: oklch(0.2046 0 0);
96
96
  border: 2px solid oklch(0.2809 0 0);
97
97
  color: oklch(0.82 0 0);
98
98
 
99
- &:hover, &:active {
99
+ &:hover,
100
+ &:active {
100
101
  border-color: oklch(0.72 0.15 145);
101
102
  outline: 1px solid oklch(0.72 0.15 145);
102
103
  outline-offset: 0;
103
- color: oklch(0.90 0 0);
104
+ color: oklch(0.9 0 0);
104
105
  }
105
106
  }
106
107
  }
107
108
 
108
109
  .loading-spinner {
109
- @apply animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full;
110
+ @apply h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent;
110
111
  }
111
112
 
112
113
  /* ==========================================================================
@@ -114,7 +115,7 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
114
115
  ========================================================================== */
115
116
 
116
117
  .label-override {
117
- @apply flex items-center text-xs mb-2;
118
+ @apply mb-2 flex items-center text-xs;
118
119
  color: oklch(0.65 0 0);
119
120
 
120
121
  svg {
@@ -128,10 +129,10 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
128
129
 
129
130
  .task-switches {
130
131
  h4 {
131
- color: oklch(0.90 0 0);
132
+ color: oklch(0.9 0 0);
132
133
  font-size: 0.8125rem;
133
134
  font-weight: 500;
134
- @apply text-center flex items-center gap-x-2 mx-auto mb-2;
135
+ @apply mx-auto mb-2 flex items-center gap-x-2 text-center;
135
136
  }
136
137
 
137
138
  .switch-wrapper {
@@ -141,7 +142,7 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
141
142
  svg {
142
143
  width: 15px !important;
143
144
  height: 15px !important;
144
- color: oklch(0.90 0 0) !important;
145
+ color: oklch(0.9 0 0) !important;
145
146
  margin-left: 0.25rem !important;
146
147
  }
147
148
  }
@@ -223,11 +224,11 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
223
224
  @screen md {
224
225
  .btn-primary,
225
226
  .btn-secondary {
226
- @apply text-sm px-3 py-1.5;
227
+ @apply px-3 py-1.5 text-sm;
227
228
  }
228
229
 
229
230
  .btn-action {
230
- @apply text-sm px-6 h-12;
231
+ @apply h-12 px-6 text-sm;
231
232
  min-height: 48px;
232
233
  }
233
234
 
@@ -241,7 +242,7 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
241
242
 
242
243
  @screen mobile-portrait {
243
244
  .btn-action {
244
- @apply text-base px-8 h-14;
245
+ @apply h-14 px-8 text-base;
245
246
  min-height: 56px;
246
247
  font-weight: 600;
247
248
  border-radius: 8px;
@@ -257,7 +258,7 @@ svg:not([stroke]):not([fill="none"]) polygon:not([fill]) {
257
258
 
258
259
  @screen mobile-landscape {
259
260
  .btn-action {
260
- @apply text-base px-8 h-14;
261
+ @apply h-14 px-8 text-base;
261
262
  min-height: 56px;
262
263
  font-weight: 600;
263
264
  }
@@ -1,31 +1,42 @@
1
1
  <template>
2
2
  <div class="form-section">
3
3
  <!-- Username -->
4
- <div class="input-wrapper mb-4">
5
- <label class="label-override">
6
- <span>Username</span>
7
- <ProfileIcon class="ml-2" />
8
- </label>
9
- <div class="input-default">
10
- <input v-model="user" placeholder="Username" />
4
+ <div class="input-container mb-3">
5
+ <div class="flex items-center gap-2">
6
+ <ProfileIcon class="w-4 h-4" />
7
+ <span class="text-light-300 font-medium text-sm">Username</span>
8
+ </div>
9
+ <div class="flex-1 flex items-center">
10
+ <input
11
+ type="text"
12
+ class="login-input"
13
+ v-model="user"
14
+ />
11
15
  </div>
12
16
  </div>
13
17
  <!-- Password -->
14
- <div class="input-wrapper">
15
- <label class="label-override">
16
- <span>Password</span>
17
- <KeyIcon class="ml-2" />
18
- </label>
19
- <div class="input-default">
20
- <input v-model="password" type="password" placeholder="Password" />
18
+ <div class="input-container mb-4">
19
+ <div class="flex items-center gap-2">
20
+ <KeyIcon class="w-4 h-4" />
21
+ <span class="text-light-300 font-medium text-sm">Password</span>
22
+ </div>
23
+ <div class="flex-1 flex items-center">
24
+ <input
25
+ type="password"
26
+ class="login-input"
27
+ v-model="password"
28
+ />
21
29
  </div>
22
30
  </div>
23
31
  <button
24
- class="bg-green-400 hover:bg-green-500 smooth-hover text-white font-medium px-4 py-2 rounded transition-all duration-150 w-full mt-4 h-10 flex items-center justify-center"
32
+ class="login-btn mt-6 mx-auto"
25
33
  @click="login()"
26
34
  :disabled="buttonDisabled"
27
35
  >
28
36
  <span v-if="!buttonDisabled">Login</span>
37
+ <svg v-if="!buttonDisabled" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="w-5 h-5">
38
+ <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l5-5-5-5M13.8 12H3"/>
39
+ </svg>
29
40
  <div v-else class="loading-spinner"></div>
30
41
  </button>
31
42
  </div>
@@ -56,43 +67,65 @@ async function login() {
56
67
  </script>
57
68
 
58
69
  <style lang="scss" scoped>
59
- .label-override {
60
- @apply flex items-center text-sm mb-2;
61
- color: #e1e1e4 !important;
70
+ .login-btn {
71
+ @apply flex items-center justify-center gap-2 rounded-lg transition-all duration-150;
72
+ background: oklch(0.72 0.15 145);
73
+ border: 2px solid oklch(0.72 0.15 145);
74
+ color: oklch(1 0 0);
75
+ height: 3rem;
76
+ width: 12rem;
77
+ font-size: 0.9375rem;
78
+ font-weight: 600;
79
+ letter-spacing: 0.05em;
80
+ text-transform: uppercase;
81
+
82
+ &:hover:not(:disabled) {
83
+ background: oklch(0.68 0.15 145);
84
+ border-color: oklch(0.68 0.15 145);
85
+ transform: translateY(-1px);
86
+ box-shadow: 0 4px 12px oklch(0.72 0.15 145 / 0.3);
87
+ }
88
+
89
+ &:active:not(:disabled) {
90
+ transform: translateY(0);
91
+ box-shadow: 0 2px 4px oklch(0.72 0.15 145 / 0.2);
92
+ }
62
93
 
63
- svg {
64
- width: 16px;
65
- height: 16px;
66
- path {
67
- fill: #e1e1e4 !important;
68
- }
94
+ &:disabled {
95
+ opacity: 0.7;
96
+ cursor: not-allowed;
69
97
  }
70
98
  }
71
99
 
72
- .input-default {
73
- @apply bg-dark-400 border border-dark-650 rounded-lg px-4 py-2 flex items-center;
74
- min-height: 40px;
100
+ .input-container {
101
+ @apply text-white bg-dark-500 px-3 rounded-lg border-2 border-dark-550 flex items-center justify-between h-11;
102
+ overflow: visible;
103
+ transition: border-color 0.15s ease;
75
104
 
76
- input {
77
- @apply bg-transparent border-none outline-none w-full text-white;
78
- &::placeholder {
79
- color: oklch(0.65 0 0);
80
- }
105
+ &:hover {
106
+ border-color: oklch(0.30 0 0);
107
+ }
108
+
109
+ &:focus-within {
110
+ border-color: oklch(0.72 0.15 145) !important;
111
+ outline: 1px solid oklch(0.72 0.15 145);
112
+ outline-offset: 0;
81
113
  }
82
114
  }
83
115
 
84
- @media (max-height: 500px) and (orientation: landscape) {
85
- .label-override {
86
- @apply text-xs mb-1;
87
-
88
- svg {
89
- width: 14px;
90
- height: 14px;
91
- }
116
+ .login-input {
117
+ @apply w-full h-full text-sm text-white bg-transparent border-0 outline-none px-2 py-1;
118
+
119
+ &:focus {
120
+ @apply outline-none border-0 shadow-none bg-transparent;
121
+ }
122
+
123
+ &:hover:not(:focus) {
124
+ background: transparent;
92
125
  }
93
126
 
94
- .input-default {
95
- min-height: 36px;
127
+ &::placeholder {
128
+ color: oklch(0.50 0 0);
96
129
  }
97
130
  }
98
131
  </style>
@@ -37,7 +37,7 @@
37
37
 
38
38
  <script setup>
39
39
  import { ref, onMounted, onUnmounted } from "vue";
40
- import logoIcon from "/android-chrome-192x192.png";
40
+ import logoIcon from "/reconnect-logo.png";
41
41
 
42
42
  const dotIndex = ref(0);
43
43
  const progressWidth = ref(0);
@@ -119,7 +119,7 @@ const props = defineProps({
119
119
  left: 0;
120
120
  right: 0;
121
121
  bottom: 0;
122
- background: rgba(26, 27, 30, 0.98);
122
+ background: oklch(0.1822 0 0 / 0.98);
123
123
  backdrop-filter: blur(12px);
124
124
  -webkit-backdrop-filter: blur(12px);
125
125
  }
@@ -269,7 +269,7 @@ const props = defineProps({
269
269
  left: -100%;
270
270
  width: 100%;
271
271
  height: 100%;
272
- background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
272
+ background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.2), transparent);
273
273
  animation: shimmer 2s ease-in-out infinite;
274
274
  }
275
275
 
@@ -1,10 +1,9 @@
1
1
  <template>
2
2
  <div class="login-container" v-once>
3
3
  <div class="login-card">
4
- <div class="flex justify-center mb-8">
5
- <img src="@/assets/img/logo_trans.png" class="h-16 object-cover" alt="Logo: Necro" />
4
+ <div class="mb-10 flex justify-center">
5
+ <img src="@/assets/img/logo_trans.png" class="mb-3 h-16 object-cover" alt="Logo: NecroLab" />
6
6
  </div>
7
- <h2 class="text-l text-white text-center font-bold mb-6">Please login to proceed</h2>
8
7
 
9
8
  <LoginForm />
10
9
  </div>
@@ -15,7 +14,7 @@ import LoginForm from "@/components/Auth/LoginForm.vue";
15
14
  </script>
16
15
  <style lang="scss" scoped>
17
16
  .login-container {
18
- @apply flex flex-col items-center min-h-screen px-4;
17
+ @apply flex min-h-screen flex-col items-center px-4;
19
18
  margin-top: 3vh;
20
19
 
21
20
  // Mobile devices
@@ -33,7 +32,7 @@ import LoginForm from "@/components/Auth/LoginForm.vue";
33
32
  }
34
33
 
35
34
  .login-card {
36
- @apply bg-dark-400 border border-dark-650 rounded-lg shadow-xl;
35
+ @apply rounded-lg border border-dark-650 bg-dark-400 shadow-xl;
37
36
  backdrop-filter: blur(10px);
38
37
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
39
38
  width: 100%;
@@ -52,7 +51,7 @@ import LoginForm from "@/components/Auth/LoginForm.vue";
52
51
  margin: 0.25rem 0;
53
52
 
54
53
  h2 {
55
- @apply text-lg mb-2;
54
+ @apply mb-2 text-lg;
56
55
  }
57
56
 
58
57
  .flex.justify-center {
@@ -79,11 +78,11 @@ import LoginForm from "@/components/Auth/LoginForm.vue";
79
78
  // Title responsive sizing
80
79
  .login-card h2 {
81
80
  @media (max-width: 480px) {
82
- @apply text-lg mb-3;
81
+ @apply mb-3 text-lg;
83
82
  }
84
83
 
85
84
  @media (orientation: landscape) {
86
- @apply text-base mb-2;
85
+ @apply mb-2 text-base;
87
86
  }
88
87
  }
89
88
  </style>