@javierfrancoleal/dsh-supervisor 1.0.37 → 1.0.39
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/dashboard.css +171 -0
- package/dashboard.html +4 -542
- package/dashboard.js +361 -0
- package/i18n.js +14 -0
- package/package.json +5 -2
- package/server.js +2 -1
package/dashboard.css
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/* Le Veilleux dashboard — stage 1 of the structural refactor.
|
|
2
|
+
Extracted from dashboard.html. One design language per EL FUEGO. */
|
|
3
|
+
:root{--blue:#4D6BFE;--violet:#7c5cff;--green:#22c55e;--amber:#facc15;--red:#ef4444;--ink:#101828;--muted:#667085;--bg:#eef2ff;--card:rgba(255,255,255,.78);--card2:rgba(255,255,255,.62);--line:rgba(15,23,42,.10);--line2:rgba(15,23,42,.06)}
|
|
4
|
+
body.dark{background:linear-gradient(165deg,#0b1220 0%,#141f31 50%,#1e1b4b 100%);background-attachment:fixed;--ink:#e6ecf7;--muted:#94a3b8;--bg:#0b1220;--card:rgba(20,31,49,.8);--card2:rgba(24,37,58,.62);--line:rgba(148,163,184,.16);--line2:rgba(148,163,184,.10)}
|
|
5
|
+
.anim{animation:slidein .28s ease}
|
|
6
|
+
@keyframes slidein{from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}}
|
|
7
|
+
.empty{text-align:center;padding:26px 12px;color:var(--muted);font-size:14px;border:1px dashed var(--line);border-radius:14px}
|
|
8
|
+
.empty .ico{font-size:30px;display:block;margin-bottom:6px}
|
|
9
|
+
.skel{background:linear-gradient(90deg,var(--line) 25%,var(--line2) 50%,var(--line) 75%);background-size:200% 100%;animation:shimmer 1.2s infinite;border-radius:10px;min-height:16px}
|
|
10
|
+
@keyframes shimmer{to{background-position:-200% 0}}
|
|
11
|
+
.toast{position:fixed;bottom:90px;left:50%;transform:translateX(-50%);background:#111827;color:#fff;padding:10px 18px;border-radius:999px;font-size:14px;font-weight:600;z-index:60;opacity:0;transition:opacity .25s;pointer-events:none;max-width:86%;text-align:center}
|
|
12
|
+
.toast.show{opacity:1}
|
|
13
|
+
body.dark .toast{background:#e6ecf7;color:#0b1220}
|
|
14
|
+
.bnav{position:fixed;bottom:0;left:0;right:0;background:var(--card);border-top:1px solid var(--line);display:none;justify-content:space-around;padding:6px 0 8px;z-index:50}
|
|
15
|
+
.bnav button{background:none;border:none;color:var(--muted);font-size:11px;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 12px;border-radius:12px;min-height:44px;font-family:inherit}
|
|
16
|
+
.bnav button.active{color:var(--blue);font-weight:700}
|
|
17
|
+
.checkpop{animation:pop .3s ease}
|
|
18
|
+
@keyframes pop{0%{transform:scale(.6);opacity:0}70%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
|
|
19
|
+
@keyframes flick{0%,100%{opacity:1}42%{opacity:.82}50%{opacity:1}58%{opacity:.9}}
|
|
20
|
+
@keyframes drawStroke{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
|
|
21
|
+
/* Visible by default; the self-draw runs only when motion is allowed */
|
|
22
|
+
.mark svg path{stroke-dasharray:100}
|
|
23
|
+
@media (prefers-reduced-motion: no-preference){.mark svg path{stroke-dashoffset:100;animation:drawStroke 1.6s cubic-bezier(.4,0,.2,1) forwards}}
|
|
24
|
+
|
|
25
|
+
.person{animation:rise .3s ease backwards}
|
|
26
|
+
.person:nth-child(1){animation-delay:.03s}
|
|
27
|
+
.person:nth-child(2){animation-delay:.09s}
|
|
28
|
+
.person:nth-child(3){animation-delay:.15s}
|
|
29
|
+
.person:nth-child(4){animation-delay:.21s}
|
|
30
|
+
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
|
|
31
|
+
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
|
|
32
|
+
body.loginpage{background:linear-gradient(135deg,#4D6BFE 0%,#7c5cff 55%,#a78bfa 100%);min-height:100vh}
|
|
33
|
+
body.loginpage.dark{background:linear-gradient(135deg,#0b1220 0%,#1e1b4b 100%)}
|
|
34
|
+
body.loginpage header{background:transparent;box-shadow:none}
|
|
35
|
+
#loginView{backdrop-filter:blur(14px);background:rgba(255,255,255,.93);border:1px solid rgba(255,255,255,.55);box-shadow:0 24px 60px rgba(15,23,42,.28);max-width:420px;margin:6vh auto 0;padding:26px 22px;animation:rise .5s ease backwards;animation-delay:.12s}
|
|
36
|
+
body.dark #loginView{background:rgba(20,31,49,.93)}
|
|
37
|
+
.loginbrand{text-align:center;margin-bottom:16px;animation:rise .5s ease backwards;animation-delay:.02s}
|
|
38
|
+
.loginbrand .mark{width:64px;height:64px;border-radius:18px;background:linear-gradient(135deg,#4D6BFE,#7c5cff);display:inline-flex;align-items:center;justify-content:center;font-size:30px;box-shadow:0 10px 24px rgba(77,107,254,.45)}
|
|
39
|
+
.loginbrand h2{margin:10px 0 2px;font-size:20px;font-weight:800}
|
|
40
|
+
.loginbrand p{color:var(--muted);font-size:13px;margin:0}
|
|
41
|
+
.spin{display:inline-block;width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:rot .7s linear infinite;vertical-align:-3px;margin-right:8px}
|
|
42
|
+
@keyframes rot{to{transform:rotate(360deg)}}
|
|
43
|
+
.shake{animation:shake .4s ease}
|
|
44
|
+
@keyframes shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-6px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(4px)}}
|
|
45
|
+
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(77,107,254,.18)}
|
|
46
|
+
@media(max-width:560px){.bnav{display:flex}.tabs{display:none}body{padding-bottom:70px}button,.btn,.pill,.confirmBtn{min-height:44px}}
|
|
47
|
+
*{box-sizing:border-box}
|
|
48
|
+
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:linear-gradient(165deg,#e8edff 0%,#f6f7fb 45%,#fdf1f8 100%);background-attachment:fixed;color:var(--ink);-webkit-tap-highlight-color:transparent}
|
|
49
|
+
header{background:linear-gradient(135deg,#4D6BFE,#7c5cff);box-shadow:0 4px 18px rgba(77,107,254,.28);color:#fff;padding:12px 16px;display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
|
|
50
|
+
header h1{margin:0;font-size:18px}
|
|
51
|
+
header .who{font-size:13px;opacity:.9}
|
|
52
|
+
button{font-family:inherit;cursor:pointer}
|
|
53
|
+
.btn{border:none;border-radius:12px;padding:12px 16px;font-size:15px;font-weight:600;color:#fff;background:linear-gradient(135deg,#4D6BFE,#7c5cff);box-shadow:0 4px 12px rgba(77,107,254,.22)}
|
|
54
|
+
.btn.gray{background:var(--line2);color:var(--ink)}
|
|
55
|
+
.btn.small{padding:8px 12px;font-size:13px}
|
|
56
|
+
main{max-width:960px;margin:0 auto;padding:14px}
|
|
57
|
+
.card{background:var(--card);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--line);border-radius:20px;box-shadow:0 8px 24px rgba(15,23,42,.06);padding:16px;margin:12px 0}
|
|
58
|
+
.card h2{margin:0 0 10px;font-size:16px}
|
|
59
|
+
input,select,textarea{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;font-size:16px;margin-bottom:8px;font-family:inherit;background:var(--card)}
|
|
60
|
+
textarea{resize:vertical;min-height:80px}
|
|
61
|
+
pre{background:#0f172a;color:#d7e3f4;border-radius:12px;padding:12px;font-size:12.5px;overflow:auto;max-height:320px;white-space:pre-wrap;margin:0}
|
|
62
|
+
.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px}
|
|
63
|
+
.metric{background:var(--card);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--line);border-radius:16px;box-shadow:0 4px 14px rgba(15,23,42,.05);padding:12px;text-align:center}
|
|
64
|
+
.metric .v{font-size:26px;font-weight:700;color:var(--blue)}
|
|
65
|
+
.metric .l{font-size:12px;color:var(--muted);margin-top:2px}
|
|
66
|
+
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
|
|
67
|
+
.tabs button{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:10px 16px;font-size:15px;font-weight:600}
|
|
68
|
+
.tabs button.active{background:var(--blue);color:#fff;border-color:var(--blue)}
|
|
69
|
+
table{width:100%;border-collapse:collapse;font-size:14px}
|
|
70
|
+
td,th{border-bottom:1px solid var(--line);padding:9px 6px;text-align:left}
|
|
71
|
+
#splash{position:fixed;inset:0;background:linear-gradient(135deg,#4D6BFE,#7c5cff);display:flex;align-items:center;justify-content:center;z-index:100;transition:opacity .5s,visibility .5s}
|
|
72
|
+
#splash.done{opacity:0;visibility:hidden}
|
|
73
|
+
.splash-inner{text-align:center;color:#fff;padding:20px}
|
|
74
|
+
.splash-inner b{display:block;font-size:22px;margin-top:14px;letter-spacing:.02em}
|
|
75
|
+
.splash-inner span{font-size:12.5px;opacity:.85}
|
|
76
|
+
@media (prefers-reduced-motion: no-preference){.splash-inner svg path{stroke-dasharray:100;stroke-dashoffset:100;animation:drawStroke 1.2s cubic-bezier(.4,0,.2,1) forwards}}
|
|
77
|
+
@media (prefers-reduced-motion: reduce){#splash{display:none}}
|
|
78
|
+
.hidden{display:none}
|
|
79
|
+
.kban{background:#fef3c7;border:1px solid #f59e0b;color:#92400e;border-radius:12px;padding:12px 14px;margin:10px 0;font-weight:700;font-size:15px}
|
|
80
|
+
.chip{background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.35);border-radius:999px;padding:5px 12px;font-size:13px;font-weight:600}
|
|
81
|
+
.foot{text-align:center;padding:6px 16px 16px}
|
|
82
|
+
.foot .copyr{font-size:12px;color:var(--muted)}
|
|
83
|
+
.eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;font-size:18px;cursor:pointer;padding:4px}
|
|
84
|
+
.passwrap{position:relative}
|
|
85
|
+
.loginerr{background:#fee2e2;color:#b91c1c;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
|
|
86
|
+
.loginok{background:#dcfce7;color:#15803d;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:14px;display:block}
|
|
87
|
+
.note{color:var(--muted);font-size:13px}
|
|
88
|
+
.hint{font-size:12.5px;color:var(--muted);margin-top:4px}
|
|
89
|
+
.listen{display:block;width:100%;border:none;border-radius:24px;padding:34px 16px;font-size:28px;font-weight:800;color:#fff;background:var(--green);box-shadow:0 6px 20px rgba(34,197,94,.4);margin:14px 0}
|
|
90
|
+
.listen:active{transform:scale(.98)}
|
|
91
|
+
.listen.pulse{animation:pulse 1.6s infinite}
|
|
92
|
+
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(34,197,94,.55)}70%{box-shadow:0 0 0 26px rgba(34,197,94,0)}100%{box-shadow:0 0 0 0 rgba(34,197,94,0)}}
|
|
93
|
+
.stopbtn{background:var(--red)!important;box-shadow:0 6px 20px rgba(239,68,68,.35)!important}
|
|
94
|
+
.row{display:flex;gap:8px;flex-wrap:wrap}
|
|
95
|
+
.row .btn{flex:1;min-width:110px}
|
|
96
|
+
.switchuser{margin-top:26px;text-align:center}
|
|
97
|
+
.langs{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0 14px}
|
|
98
|
+
.langov{position:fixed;inset:0;background:linear-gradient(160deg,#4D6BFE,#7c5cff 60%,#a78bfa);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:110;animation:rise .3s ease}
|
|
99
|
+
.langov .top{position:absolute;top:22px;right:26px}
|
|
100
|
+
.langov .close{background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.3);color:#fff;border-radius:999px;width:44px;height:44px;font-size:18px;cursor:pointer}
|
|
101
|
+
.orow{width:min(520px,92vw);display:flex;justify-content:space-between;align-items:center;padding:15px 22px;border-radius:14px;font-size:19px;color:#fff;cursor:pointer;transition:background .15s,transform .1s}
|
|
102
|
+
.orow:hover{background:rgba(255,255,255,.12)}
|
|
103
|
+
.orow:active{transform:scale(.98)}
|
|
104
|
+
.orow .sub{font-size:13px;opacity:.7}
|
|
105
|
+
.orow.center{background:rgba(255,255,255,.30);font-size:23px;font-weight:800;border:1px solid rgba(255,255,255,.45)}
|
|
106
|
+
.orow.center .sub{opacity:.9}
|
|
107
|
+
#langStep{position:fixed;inset:0;background:linear-gradient(160deg,#4D6BFE,#7c5cff 60%,#a78bfa);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:95;transition:opacity .45s,visibility .45s;animation:stepin .55s ease}
|
|
108
|
+
@keyframes stepin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
|
|
109
|
+
#langStep.done{opacity:0;visibility:hidden}
|
|
110
|
+
.langstep-inner{text-align:center}
|
|
111
|
+
.langstep-hint{color:rgba(255,255,255,.9);font-size:14px;margin:18px 0 4px}
|
|
112
|
+
.langstep-inner .langreel{width:min(340px,86vw);background:rgba(167,139,250,.55)!important;border:1px solid rgba(255,255,255,.6)!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
|
|
113
|
+
.langstep-inner svg{width:150px;height:150px}
|
|
114
|
+
.langstep-inner svg path.draw{stroke-dasharray:100;animation:drawStroke 1.2s cubic-bezier(.4,0,.2,1) forwards}
|
|
115
|
+
@media (prefers-reduced-motion: reduce){.langstep-inner svg path.draw{animation:none}}
|
|
116
|
+
#loginView{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;box-shadow:none;text-align:center}
|
|
117
|
+
#loginView h2,#loginView .loginbrand h2{color:#fff}
|
|
118
|
+
#loginView .loginbrand p,#loginView .hint,#loginView .note{color:rgba(255,255,255,.82)}
|
|
119
|
+
#loginView input,#loginView select{background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.35);color:#fff}
|
|
120
|
+
#loginView input::placeholder{color:rgba(255,255,255,.7)}
|
|
121
|
+
#loginView .loginerr{background:rgba(239,68,68,.25);color:#fff;border:1px solid rgba(255,255,255,.3)}
|
|
122
|
+
#loginView .eye{color:#fff}
|
|
123
|
+
#loginView .btn.gray{background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.3)}
|
|
124
|
+
.langreel{width:min(340px,86vw);height:58px;margin:10px auto;background:rgba(167,139,250,.45);border:1px solid rgba(255,255,255,.55);border-radius:10px;backdrop-filter:blur(14px);overflow:hidden;cursor:pointer;position:relative;box-shadow:0 10px 30px rgba(76,29,149,.20)}
|
|
125
|
+
body.dark .langreel{background:rgba(124,92,255,.35)}
|
|
126
|
+
.ticks{display:flex;flex-direction:column;will-change:transform}
|
|
127
|
+
.tick{height:58px;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;opacity:.85;color:#fff}
|
|
128
|
+
.pill{background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 13px;font-size:13px;cursor:pointer}
|
|
129
|
+
.pill.active{background:var(--blue);color:#fff;border-color:var(--blue)}
|
|
130
|
+
.person{background:var(--card2);border:1px solid var(--line);border-radius:16px;padding:14px;margin:10px 0}
|
|
131
|
+
.person .pname{font-size:17px;font-weight:700;margin-bottom:8px}
|
|
132
|
+
.req{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card);border:1px solid var(--line2);margin:6px 0}
|
|
133
|
+
.req .txt{flex:1;font-size:15px}
|
|
134
|
+
.req .tier{font-size:12px;font-weight:700;padding:4px 8px;border-radius:999px}
|
|
135
|
+
.sentline{font-size:12px;color:#16a34a;margin-top:4px;font-weight:600}
|
|
136
|
+
.pcnt{font-size:12.5px;color:var(--muted);font-weight:600;margin-left:6px}
|
|
137
|
+
.tier-GREEN{background:#dcfce7;color:#15803d}
|
|
138
|
+
.tier-SEMI{background:#fef9c3;color:#a16207}
|
|
139
|
+
.tier-YELLOW{background:#fef9c3;color:#a16207}
|
|
140
|
+
.tier-RED{background:#fee2e2;color:#b91c1c}
|
|
141
|
+
.confirmBtn{background:var(--blue);color:#fff;border:none;border-radius:12px;padding:10px 14px;font-size:14px;font-weight:700;white-space:nowrap}
|
|
142
|
+
.confirmBtn.done{background:#dcfce7;color:#15803d}
|
|
143
|
+
.order{display:flex;align-items:center;gap:10px;padding:10px;border-radius:12px;background:var(--card2);border:1px solid var(--line);margin:6px 0;font-size:14px}
|
|
144
|
+
.order .stat{font-size:12px;font-weight:700;padding:4px 10px;border-radius:999px;background:#e0e7ff;color:#3730a3}
|
|
145
|
+
#wallView{max-width:1100px}
|
|
146
|
+
.wall-head{font-size:34px;font-weight:800;color:#fff;text-align:center;margin:10px 0}
|
|
147
|
+
.wall-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
|
|
148
|
+
.wall-card{background:#1b2436;color:#fff;border-radius:16px;padding:20px;text-align:center}
|
|
149
|
+
.wall-card .v{font-size:44px;font-weight:800}
|
|
150
|
+
.wall-card .l{font-size:15px;opacity:.85}
|
|
151
|
+
.wall-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:6px 0 16px;flex-wrap:wrap}
|
|
152
|
+
.wall-brand{display:flex;align-items:center;gap:10px;color:#fff}
|
|
153
|
+
.wall-brand b{font-size:20px;display:block}
|
|
154
|
+
.wall-brand span{font-size:12px;opacity:.75;text-transform:uppercase;letter-spacing:.06em}
|
|
155
|
+
.wall-clock{text-align:right;color:#fff}
|
|
156
|
+
.wall-clock b{font-size:20px;display:block}
|
|
157
|
+
.wall-clock span{font-size:12px;opacity:.75}
|
|
158
|
+
.live-dot{display:flex;align-items:center;gap:7px;color:#4ade80;font-weight:800;font-size:13px;letter-spacing:.08em}
|
|
159
|
+
.live-dot::before{content:"";width:9px;height:9px;border-radius:50%;background:#4ade80;animation:pulse 1.6s infinite}
|
|
160
|
+
.wtick{background:#1b2436;color:#d7e3f4;border-radius:10px;padding:8px 12px;font-size:13.5px;margin:6px 0}
|
|
161
|
+
.wtick.dim{color:#64748b;background:none;border:1px dashed #334155}
|
|
162
|
+
.wall-note{color:#64748b;font-size:12px;text-align:center;margin-top:10px}
|
|
163
|
+
.welcome{position:relative;border-left:4px solid var(--blue);animation:rise .4s ease}
|
|
164
|
+
.welcome .wclose{position:absolute;top:10px;right:10px;background:none;border:none;font-size:16px;color:var(--muted);cursor:pointer}
|
|
165
|
+
button{transition:transform .12s ease}
|
|
166
|
+
button:active{transform:scale(.97)}
|
|
167
|
+
button:focus-visible,.pill:focus-visible,input:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
|
|
168
|
+
body.wall{background:linear-gradient(165deg,#0b1220 0%,#131c30 60%,#1e1b4b 100%);background-attachment:fixed}
|
|
169
|
+
body.firstboot header,body.firstboot main,body.firstboot footer{display:none}
|
|
170
|
+
body.wall pre{max-height:40vh}
|
|
171
|
+
@media (max-width:560px){header h1{font-size:15px}.listen{font-size:24px;padding:26px 12px}input,select,textarea,button{font-size:16px}}
|