git-watchtower 2.2.2 → 2.3.0
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 +1 -1
- package/src/cli/args.js +13 -0
- package/src/git/branch.js +0 -77
- package/src/index.js +0 -3
- package/src/polling/engine.js +7 -153
- package/src/server/process.js +5 -356
- package/src/server/web-ui/css.js +207 -199
- package/src/server/web-ui/html.js +28 -18
- package/src/server/web-ui/js.js +79 -87
- package/src/utils/sound.js +39 -12
package/src/server/web-ui/css.js
CHANGED
|
@@ -63,9 +63,11 @@ function getDashboardCss() {
|
|
|
63
63
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
64
64
|
user-select: none;
|
|
65
65
|
box-shadow: 0 1px 8px rgba(0,0,0,0.3);
|
|
66
|
+
/* position:relative so .casino-reels-header (absolute) anchors here. */
|
|
66
67
|
position: relative;
|
|
67
68
|
z-index: 10;
|
|
68
69
|
}
|
|
70
|
+
.header-icon { display: inline-block; }
|
|
69
71
|
.header-left {
|
|
70
72
|
display: flex;
|
|
71
73
|
align-items: center;
|
|
@@ -113,7 +115,10 @@ function getDashboardCss() {
|
|
|
113
115
|
.layout {
|
|
114
116
|
display: grid;
|
|
115
117
|
grid-template-columns: 1fr 320px;
|
|
116
|
-
|
|
118
|
+
/* Row 1: branch panel + sidebar.
|
|
119
|
+
Row 2: dashboard-stats (full-width).
|
|
120
|
+
Row 3: keyboard-shortcut footer (full-width). */
|
|
121
|
+
grid-template-rows: 1fr auto auto;
|
|
117
122
|
height: calc(100vh - 49px);
|
|
118
123
|
min-height: 0;
|
|
119
124
|
gap: 0;
|
|
@@ -759,24 +764,6 @@ function getDashboardCss() {
|
|
|
759
764
|
.info-label { color: var(--text-muted); font-weight: 500; }
|
|
760
765
|
.info-value { color: var(--text); font-family: var(--font-mono); }
|
|
761
766
|
|
|
762
|
-
/* ── Session Stats (footer) ──────────────────────────────────── */
|
|
763
|
-
.stats-bar {
|
|
764
|
-
display: flex;
|
|
765
|
-
gap: 16px;
|
|
766
|
-
align-items: center;
|
|
767
|
-
font-size: 11px;
|
|
768
|
-
color: var(--text-muted);
|
|
769
|
-
font-family: var(--font-mono);
|
|
770
|
-
flex-wrap: wrap;
|
|
771
|
-
}
|
|
772
|
-
.stats-bar .stat-item {
|
|
773
|
-
display: flex;
|
|
774
|
-
align-items: center;
|
|
775
|
-
gap: 4px;
|
|
776
|
-
}
|
|
777
|
-
.stats-bar .stat-value { color: var(--text-dim); font-weight: 600; }
|
|
778
|
-
.stats-bar .stat-label { font-family: var(--font); }
|
|
779
|
-
|
|
780
767
|
/* ── Cleanup Modal ───────────────────────────────────────────── */
|
|
781
768
|
.cleanup-branch-list {
|
|
782
769
|
display: flex;
|
|
@@ -909,172 +896,238 @@ function getDashboardCss() {
|
|
|
909
896
|
.pref-btn:hover { background: var(--bg-surface-hover); color: var(--text-dim); border-color: var(--text-muted); }
|
|
910
897
|
.pref-btn.active { background: var(--accent-dim); color: #fff; border-color: var(--accent-dim); }
|
|
911
898
|
|
|
912
|
-
/* ──
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
899
|
+
/* ── Dashboard Stats Bar (always-on, above the keyboard footer) ──
|
|
900
|
+
This is the canonical place for live session stats. The same
|
|
901
|
+
element re-skins to "casino winnings" when state.casinoModeEnabled
|
|
902
|
+
flips on, so users get the same row in both modes. */
|
|
903
|
+
.dashboard-stats {
|
|
904
|
+
grid-column: 1 / -1;
|
|
905
|
+
padding: 8px 20px;
|
|
906
|
+
background: var(--bg-surface);
|
|
907
|
+
border-top: 1px solid var(--border);
|
|
908
|
+
display: flex;
|
|
909
|
+
flex-wrap: wrap;
|
|
910
|
+
gap: 8px 24px;
|
|
911
|
+
align-items: center;
|
|
912
|
+
justify-content: space-between;
|
|
916
913
|
font-size: 11px;
|
|
917
914
|
color: var(--text-dim);
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
915
|
+
transition: background 0.25s, border-color 0.25s, box-shadow 0.25s;
|
|
916
|
+
}
|
|
917
|
+
.dashboard-stats .stats-group {
|
|
918
|
+
display: flex;
|
|
919
|
+
flex-wrap: wrap;
|
|
920
|
+
align-items: center;
|
|
921
|
+
gap: 14px;
|
|
922
|
+
}
|
|
923
|
+
/* Title pill anchors the bar — makes it obvious these are global
|
|
924
|
+
session metrics, not row-specific. */
|
|
925
|
+
.dashboard-stats .stats-title {
|
|
926
|
+
font-size: 10px;
|
|
927
|
+
font-weight: 800;
|
|
928
|
+
letter-spacing: 1.2px;
|
|
929
|
+
text-transform: uppercase;
|
|
930
|
+
color: var(--text-muted);
|
|
931
|
+
padding: 3px 10px;
|
|
932
|
+
border-radius: 999px;
|
|
921
933
|
background: var(--bg);
|
|
934
|
+
border: 1px solid var(--border);
|
|
935
|
+
display: inline-flex;
|
|
936
|
+
align-items: center;
|
|
937
|
+
gap: 6px;
|
|
938
|
+
}
|
|
939
|
+
.dashboard-stats .stat {
|
|
940
|
+
display: inline-flex;
|
|
941
|
+
align-items: baseline;
|
|
942
|
+
gap: 6px;
|
|
943
|
+
white-space: nowrap;
|
|
922
944
|
}
|
|
923
|
-
.
|
|
945
|
+
.dashboard-stats .stat-k {
|
|
924
946
|
color: var(--text-muted);
|
|
925
947
|
text-transform: uppercase;
|
|
926
948
|
letter-spacing: 0.6px;
|
|
927
949
|
font-size: 10px;
|
|
928
950
|
font-weight: 600;
|
|
929
|
-
align-self: center;
|
|
930
951
|
}
|
|
931
|
-
.
|
|
952
|
+
.dashboard-stats .stat-v {
|
|
932
953
|
color: var(--text);
|
|
933
954
|
font-family: var(--font-mono);
|
|
934
955
|
font-size: 12px;
|
|
935
|
-
|
|
956
|
+
font-weight: 600;
|
|
936
957
|
}
|
|
937
|
-
.
|
|
938
|
-
.
|
|
939
|
-
.
|
|
940
|
-
.
|
|
958
|
+
.dashboard-stats .stat-v .added { color: var(--green); }
|
|
959
|
+
.dashboard-stats .stat-v .deleted { color: var(--red); }
|
|
960
|
+
.dashboard-stats .stat-v .sep { color: var(--text-muted); }
|
|
961
|
+
.dashboard-stats .stat-v .accent { color: var(--accent); }
|
|
962
|
+
/* Casino skin: same row, neon-pulsed, brighter title. */
|
|
963
|
+
.dashboard-stats.casino-mode {
|
|
964
|
+
background: linear-gradient(90deg, #1a0a24 0%, #2a0a36 50%, #1a0a24 100%);
|
|
965
|
+
border-top: 2px solid #ff2d7a;
|
|
966
|
+
box-shadow: inset 0 0 24px rgba(255, 45, 122, 0.25);
|
|
967
|
+
}
|
|
968
|
+
.dashboard-stats.casino-mode .stats-title {
|
|
969
|
+
color: #ffd400;
|
|
970
|
+
background: rgba(177, 0, 150, 0.4);
|
|
971
|
+
border-color: #ff2d7a;
|
|
972
|
+
text-shadow: 0 0 6px rgba(255, 220, 64, 0.6);
|
|
973
|
+
}
|
|
974
|
+
.dashboard-stats.casino-mode .stat-k { color: #ffd400; }
|
|
975
|
+
.dashboard-stats.casino-mode .stat-v { color: var(--text); }
|
|
976
|
+
.dashboard-stats.casino-mode .stat-v .pos { color: #3fb950; }
|
|
977
|
+
.dashboard-stats.casino-mode .stat-v .neg { color: #f85149; }
|
|
978
|
+
.dashboard-stats.casino-mode .stat-v .gold { color: #ffd400; }
|
|
979
|
+
.dashboard-stats.casino-mode .stat-v .neon { color: #29d4ff; }
|
|
980
|
+
|
|
981
|
+
/* ── Casino Mode ────────────────────────────────────────────────
|
|
982
|
+
Edge strips, header reskin, header reels, win/loss overlays. The
|
|
983
|
+
stats live in .dashboard-stats above; nothing floats over the
|
|
984
|
+
dashboard content anymore. */
|
|
941
985
|
|
|
942
|
-
/* ── Casino Mode ──────────────────────────────────────────────── */
|
|
943
986
|
.casino-layer {
|
|
944
987
|
position: fixed;
|
|
945
988
|
inset: 0;
|
|
946
989
|
pointer-events: none;
|
|
947
990
|
z-index: 90;
|
|
948
991
|
opacity: 0;
|
|
949
|
-
|
|
992
|
+
visibility: hidden;
|
|
993
|
+
transition: opacity 0.25s;
|
|
994
|
+
}
|
|
995
|
+
body.casino-active .casino-layer {
|
|
996
|
+
opacity: 1;
|
|
997
|
+
visibility: visible;
|
|
950
998
|
}
|
|
951
|
-
body.casino-active .casino-layer { opacity: 1; }
|
|
952
999
|
|
|
953
|
-
/* Marquee:
|
|
954
|
-
|
|
955
|
-
.casino-
|
|
1000
|
+
/* Marquee: four solid neon strips at the viewport edges. Each strip
|
|
1001
|
+
pulses its own hue so the whole frame chases colours together. */
|
|
1002
|
+
.casino-edge {
|
|
956
1003
|
position: absolute;
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
/*
|
|
975
|
-
|
|
976
|
-
|
|
1004
|
+
background: #ff2d7a;
|
|
1005
|
+
box-shadow: 0 0 18px rgba(255, 45, 122, 0.7);
|
|
1006
|
+
animation: casino-edge-pulse 0.9s ease-in-out infinite;
|
|
1007
|
+
overflow: hidden;
|
|
1008
|
+
}
|
|
1009
|
+
.casino-edge.top { top: 0; left: 0; right: 0; height: 8px; }
|
|
1010
|
+
.casino-edge.bottom { bottom: 0; left: 0; right: 0; height: 8px; animation-delay: 0.45s; }
|
|
1011
|
+
.casino-edge.left { top: 0; bottom: 0; left: 0; width: 8px; animation-delay: 0.225s; }
|
|
1012
|
+
.casino-edge.right { top: 0; bottom: 0; right: 0; width: 8px; animation-delay: 0.675s; }
|
|
1013
|
+
@keyframes casino-edge-pulse {
|
|
1014
|
+
0% { background: #ff2d7a; box-shadow: 0 0 18px rgba(255, 45, 122, 0.7); }
|
|
1015
|
+
25% { background: #ffd400; box-shadow: 0 0 18px rgba(255, 220, 64, 0.7); }
|
|
1016
|
+
50% { background: #29d4ff; box-shadow: 0 0 18px rgba(41, 212, 255, 0.7); }
|
|
1017
|
+
75% { background: #b070ff; box-shadow: 0 0 18px rgba(176, 112, 255, 0.7); }
|
|
1018
|
+
100% { background: #ff2d7a; box-shadow: 0 0 18px rgba(255, 45, 122, 0.7); }
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/* Chase-light stripes — horizontal pattern on top/bottom, vertical
|
|
1022
|
+
pattern on left/right, all flowing in opposite directions so the
|
|
1023
|
+
marquee reads as a closed loop. */
|
|
1024
|
+
.casino-edge::after {
|
|
977
1025
|
content: '';
|
|
978
1026
|
position: absolute;
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1027
|
+
inset: 0;
|
|
1028
|
+
}
|
|
1029
|
+
.casino-edge.top::after,
|
|
1030
|
+
.casino-edge.bottom::after {
|
|
982
1031
|
background-image: repeating-linear-gradient(
|
|
983
1032
|
90deg,
|
|
984
|
-
|
|
985
|
-
transparent
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1033
|
+
rgba(255, 255, 255, 0.85) 0 8px,
|
|
1034
|
+
transparent 8px 24px
|
|
1035
|
+
);
|
|
1036
|
+
background-size: 24px 100%;
|
|
1037
|
+
animation: casino-chase-x 0.9s linear infinite;
|
|
1038
|
+
}
|
|
1039
|
+
.casino-edge.bottom::after { animation-direction: reverse; }
|
|
1040
|
+
.casino-edge.left::after,
|
|
1041
|
+
.casino-edge.right::after {
|
|
1042
|
+
background-image: repeating-linear-gradient(
|
|
1043
|
+
0deg,
|
|
1044
|
+
rgba(255, 255, 255, 0.85) 0 8px,
|
|
1045
|
+
transparent 8px 24px
|
|
990
1046
|
);
|
|
991
|
-
background-size:
|
|
992
|
-
|
|
1047
|
+
background-size: 100% 24px;
|
|
1048
|
+
animation: casino-chase-y 0.9s linear infinite;
|
|
993
1049
|
}
|
|
994
|
-
.casino-
|
|
995
|
-
|
|
996
|
-
@keyframes casino-chase-
|
|
997
|
-
@keyframes casino-chase-left { to { background-position: -60px 0; } }
|
|
1050
|
+
.casino-edge.right::after { animation-direction: reverse; }
|
|
1051
|
+
@keyframes casino-chase-x { to { background-position: 24px 0; } }
|
|
1052
|
+
@keyframes casino-chase-y { to { background-position: 0 24px; } }
|
|
998
1053
|
|
|
999
|
-
/*
|
|
1000
|
-
.casino-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
}
|
|
1054
|
+
/* Header reskin: rainbow text + animated icon + slot reels in-place. */
|
|
1055
|
+
body.casino-active .header-text {
|
|
1056
|
+
background: linear-gradient(
|
|
1057
|
+
90deg,
|
|
1058
|
+
#ff2d7a, #ffd400, #30ff9c, #29d4ff, #b070ff, #ff2d7a
|
|
1059
|
+
);
|
|
1060
|
+
background-size: 200% 100%;
|
|
1061
|
+
-webkit-background-clip: text;
|
|
1062
|
+
background-clip: text;
|
|
1063
|
+
-webkit-text-fill-color: transparent;
|
|
1064
|
+
color: transparent;
|
|
1065
|
+
animation: casino-rainbow-slide 3s linear infinite;
|
|
1066
|
+
/* Drop shadow with a coloured tint compensates for transparent fill. */
|
|
1067
|
+
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
|
|
1068
|
+
}
|
|
1069
|
+
@keyframes casino-rainbow-slide {
|
|
1070
|
+
to { background-position: 200% 0; }
|
|
1071
|
+
}
|
|
1072
|
+
body.casino-active .header-icon {
|
|
1073
|
+
display: inline-block;
|
|
1074
|
+
animation: casino-icon-spin 2.4s linear infinite;
|
|
1075
|
+
}
|
|
1076
|
+
@keyframes casino-icon-spin {
|
|
1077
|
+
0%, 100% { filter: hue-rotate(0deg) drop-shadow(0 0 4px rgba(255, 220, 64, 0.6)); }
|
|
1078
|
+
50% { filter: hue-rotate(180deg) drop-shadow(0 0 6px rgba(255, 45, 122, 0.8)); }
|
|
1025
1079
|
}
|
|
1026
1080
|
|
|
1027
|
-
/* Slot reels —
|
|
1028
|
-
|
|
1081
|
+
/* Slot reels — sit centred inside the header banner, hidden until
|
|
1082
|
+
casino mode is on. Sized small enough to fit in the existing
|
|
1083
|
+
header height without disturbing surrounding controls. */
|
|
1084
|
+
.casino-reels-header {
|
|
1029
1085
|
position: absolute;
|
|
1030
|
-
top:
|
|
1086
|
+
top: 50%;
|
|
1031
1087
|
left: 50%;
|
|
1032
|
-
transform:
|
|
1088
|
+
transform: translate(-50%, -50%);
|
|
1033
1089
|
display: flex;
|
|
1034
|
-
gap:
|
|
1035
|
-
padding: 8px
|
|
1036
|
-
background:
|
|
1037
|
-
border: 1px solid
|
|
1038
|
-
border-radius:
|
|
1039
|
-
box-shadow:
|
|
1040
|
-
0 10px 24px rgba(0, 0, 0, 0.45),
|
|
1041
|
-
0 0 18px rgba(255, 45, 122, 0.35);
|
|
1090
|
+
gap: 4px;
|
|
1091
|
+
padding: 4px 8px;
|
|
1092
|
+
background: rgba(20, 8, 30, 0.9);
|
|
1093
|
+
border: 1px solid #ff2d7a;
|
|
1094
|
+
border-radius: 8px;
|
|
1095
|
+
box-shadow: 0 0 14px rgba(255, 45, 122, 0.55);
|
|
1042
1096
|
opacity: 0;
|
|
1043
1097
|
visibility: hidden;
|
|
1044
|
-
|
|
1098
|
+
pointer-events: none;
|
|
1099
|
+
transition: opacity 0.25s;
|
|
1100
|
+
z-index: 1;
|
|
1045
1101
|
}
|
|
1046
|
-
.casino-
|
|
1102
|
+
body.casino-active .casino-reels-header {
|
|
1047
1103
|
opacity: 1;
|
|
1048
1104
|
visibility: visible;
|
|
1049
|
-
transform: translateX(-50%) translateY(0);
|
|
1050
1105
|
}
|
|
1051
1106
|
.casino-reel {
|
|
1052
|
-
width:
|
|
1053
|
-
height:
|
|
1107
|
+
width: 26px;
|
|
1108
|
+
height: 26px;
|
|
1054
1109
|
display: flex;
|
|
1055
1110
|
align-items: center;
|
|
1056
1111
|
justify-content: center;
|
|
1057
|
-
font-size:
|
|
1112
|
+
font-size: 16px;
|
|
1058
1113
|
line-height: 1;
|
|
1059
1114
|
background: #fff;
|
|
1060
|
-
border-radius:
|
|
1061
|
-
box-shadow:
|
|
1062
|
-
inset 0 -6px 10px rgba(0, 0, 0, 0.1),
|
|
1063
|
-
inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
1115
|
+
border-radius: 4px;
|
|
1116
|
+
box-shadow: inset 0 -3px 6px rgba(0, 0, 0, 0.12), inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
1064
1117
|
}
|
|
1065
|
-
.casino-reels.spinning .casino-reel {
|
|
1118
|
+
.casino-reels-header.spinning .casino-reel {
|
|
1066
1119
|
animation: casino-reel-blur 0.1s linear infinite;
|
|
1067
1120
|
}
|
|
1068
|
-
.casino-reels.spinning .casino-reel[data-reel="1"] { animation-delay: 0.03s; }
|
|
1069
|
-
.casino-reels.spinning .casino-reel[data-reel="2"] { animation-delay: 0.06s; }
|
|
1070
|
-
.casino-reels.spinning .casino-reel[data-reel="3"] { animation-delay: 0.09s; }
|
|
1071
|
-
.casino-reels.spinning .casino-reel[data-reel="4"] { animation-delay: 0.12s; }
|
|
1121
|
+
.casino-reels-header.spinning .casino-reel[data-reel="1"] { animation-delay: 0.03s; }
|
|
1122
|
+
.casino-reels-header.spinning .casino-reel[data-reel="2"] { animation-delay: 0.06s; }
|
|
1123
|
+
.casino-reels-header.spinning .casino-reel[data-reel="3"] { animation-delay: 0.09s; }
|
|
1124
|
+
.casino-reels-header.spinning .casino-reel[data-reel="4"] { animation-delay: 0.12s; }
|
|
1072
1125
|
@keyframes casino-reel-blur {
|
|
1073
|
-
0% { transform: translateY(-
|
|
1074
|
-
50% { transform: translateY(
|
|
1075
|
-
100% { transform: translateY(-
|
|
1126
|
+
0% { transform: translateY(-1.5px); filter: blur(0.6px); }
|
|
1127
|
+
50% { transform: translateY(1.5px); filter: blur(0.6px); }
|
|
1128
|
+
100% { transform: translateY(-1.5px); filter: blur(0.6px); }
|
|
1076
1129
|
}
|
|
1077
|
-
.casino-reels.win .casino-reel {
|
|
1130
|
+
.casino-reels-header.win .casino-reel {
|
|
1078
1131
|
animation: casino-reel-winflash 0.24s steps(2, end) infinite;
|
|
1079
1132
|
}
|
|
1080
1133
|
@keyframes casino-reel-winflash {
|
|
@@ -1083,22 +1136,22 @@ function getDashboardCss() {
|
|
|
1083
1136
|
}
|
|
1084
1137
|
.casino-reel-label {
|
|
1085
1138
|
position: absolute;
|
|
1086
|
-
top: calc(100% +
|
|
1139
|
+
top: calc(100% + 4px);
|
|
1087
1140
|
left: 50%;
|
|
1088
1141
|
transform: translateX(-50%);
|
|
1089
|
-
font-size:
|
|
1142
|
+
font-size: 10px;
|
|
1090
1143
|
font-weight: 800;
|
|
1091
1144
|
letter-spacing: 1.2px;
|
|
1092
1145
|
text-transform: uppercase;
|
|
1093
|
-
color:
|
|
1146
|
+
color: #ffd400;
|
|
1094
1147
|
white-space: nowrap;
|
|
1095
|
-
text-shadow: 0 0
|
|
1148
|
+
text-shadow: 0 0 8px currentColor;
|
|
1096
1149
|
opacity: 0;
|
|
1097
1150
|
transition: opacity 0.2s;
|
|
1098
1151
|
}
|
|
1099
|
-
.casino-reels.result .casino-reel-label { opacity: 1; }
|
|
1152
|
+
.casino-reels-header.result .casino-reel-label { opacity: 1; }
|
|
1100
1153
|
|
|
1101
|
-
/*
|
|
1154
|
+
/* Centred win / loss overlay banner — solid, opaque, hard to miss. */
|
|
1102
1155
|
.casino-overlay {
|
|
1103
1156
|
position: absolute;
|
|
1104
1157
|
top: 45%;
|
|
@@ -1110,17 +1163,18 @@ function getDashboardCss() {
|
|
|
1110
1163
|
letter-spacing: 2px;
|
|
1111
1164
|
text-transform: uppercase;
|
|
1112
1165
|
color: #fff200;
|
|
1113
|
-
background:
|
|
1114
|
-
border: 3px solid
|
|
1166
|
+
background: #b10096;
|
|
1167
|
+
border: 3px solid #ffd400;
|
|
1115
1168
|
border-radius: 14px;
|
|
1116
1169
|
box-shadow:
|
|
1117
1170
|
0 0 40px rgba(255, 45, 122, 0.7),
|
|
1118
1171
|
0 0 80px rgba(255, 220, 64, 0.4);
|
|
1119
|
-
text-shadow: 0 2px 0 rgba(0,0,0,0.3);
|
|
1172
|
+
text-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
|
|
1120
1173
|
opacity: 0;
|
|
1121
1174
|
visibility: hidden;
|
|
1122
1175
|
pointer-events: none;
|
|
1123
1176
|
transition: opacity 0.15s, transform 0.2s;
|
|
1177
|
+
z-index: 3;
|
|
1124
1178
|
}
|
|
1125
1179
|
.casino-overlay.active {
|
|
1126
1180
|
opacity: 1;
|
|
@@ -1132,76 +1186,30 @@ function getDashboardCss() {
|
|
|
1132
1186
|
0%, 100% { filter: brightness(1); }
|
|
1133
1187
|
50% { filter: brightness(1.35) saturate(1.3); }
|
|
1134
1188
|
}
|
|
1135
|
-
.casino-overlay.level-small { background:
|
|
1136
|
-
.casino-overlay.level-medium { background:
|
|
1137
|
-
.casino-overlay.level-large { background:
|
|
1138
|
-
.casino-overlay.level-huge { background:
|
|
1189
|
+
.casino-overlay.level-small { background: #238636; border-color: #3fb950; }
|
|
1190
|
+
.casino-overlay.level-medium { background: #ffd400; color: #2a1200; border-color: #ff9a00; }
|
|
1191
|
+
.casino-overlay.level-large { background: #ff9a00; color: #2a1200; border-color: #ffd400; }
|
|
1192
|
+
.casino-overlay.level-huge { background: #7a00ba; color: #fff; border-color: #bc8cff; }
|
|
1139
1193
|
.casino-overlay.level-jackpot {
|
|
1140
|
-
background:
|
|
1141
|
-
color: #
|
|
1194
|
+
background: #29d4ff;
|
|
1195
|
+
color: #04293a;
|
|
1196
|
+
border-color: #fff;
|
|
1142
1197
|
animation-duration: 0.12s;
|
|
1143
1198
|
}
|
|
1144
1199
|
.casino-overlay.level-mega {
|
|
1145
|
-
background:
|
|
1200
|
+
background: #b10000;
|
|
1201
|
+
color: #fff200;
|
|
1202
|
+
border-color: #ffd400;
|
|
1146
1203
|
animation-duration: 0.08s;
|
|
1147
1204
|
font-size: 40px;
|
|
1148
1205
|
}
|
|
1149
1206
|
.casino-overlay.loss {
|
|
1150
|
-
background:
|
|
1207
|
+
background: #b10000;
|
|
1151
1208
|
color: #fff;
|
|
1152
1209
|
font-size: 26px;
|
|
1210
|
+
border-color: #ff2d2d;
|
|
1153
1211
|
}
|
|
1154
1212
|
|
|
1155
|
-
/* Floating stats panel. Slides in from the right when casino is on. */
|
|
1156
|
-
.casino-stats-panel {
|
|
1157
|
-
position: absolute;
|
|
1158
|
-
right: 16px;
|
|
1159
|
-
bottom: 56px;
|
|
1160
|
-
width: 340px;
|
|
1161
|
-
padding: 12px 14px;
|
|
1162
|
-
background: linear-gradient(160deg, #1a0a24, #0f0616);
|
|
1163
|
-
border: 2px solid #ff2d7a;
|
|
1164
|
-
border-radius: 10px;
|
|
1165
|
-
box-shadow:
|
|
1166
|
-
0 0 20px rgba(255, 45, 122, 0.45),
|
|
1167
|
-
0 8px 28px rgba(0, 0, 0, 0.6);
|
|
1168
|
-
color: var(--text);
|
|
1169
|
-
font-size: 12px;
|
|
1170
|
-
transform: translateX(calc(100% + 32px));
|
|
1171
|
-
transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.1);
|
|
1172
|
-
pointer-events: auto;
|
|
1173
|
-
}
|
|
1174
|
-
body.casino-active .casino-stats-panel { transform: translateX(0); }
|
|
1175
|
-
.casino-stats-panel .cstats-title {
|
|
1176
|
-
font-weight: 800;
|
|
1177
|
-
letter-spacing: 1px;
|
|
1178
|
-
text-transform: uppercase;
|
|
1179
|
-
font-size: 11px;
|
|
1180
|
-
color: #ffd400;
|
|
1181
|
-
margin-bottom: 8px;
|
|
1182
|
-
text-align: center;
|
|
1183
|
-
text-shadow: 0 0 8px rgba(255, 220, 64, 0.6);
|
|
1184
|
-
}
|
|
1185
|
-
.casino-stats-panel .cstats-row {
|
|
1186
|
-
display: flex;
|
|
1187
|
-
justify-content: space-between;
|
|
1188
|
-
align-items: center;
|
|
1189
|
-
padding: 3px 0;
|
|
1190
|
-
border-bottom: 1px dashed rgba(255, 255, 255, 0.08);
|
|
1191
|
-
font-family: var(--font-mono);
|
|
1192
|
-
}
|
|
1193
|
-
.casino-stats-panel .cstats-row:last-child { border-bottom: none; }
|
|
1194
|
-
.casino-stats-panel .cstats-k {
|
|
1195
|
-
color: var(--text-dim);
|
|
1196
|
-
font-family: var(--font);
|
|
1197
|
-
font-size: 11px;
|
|
1198
|
-
}
|
|
1199
|
-
.casino-stats-panel .cstats-v { font-weight: 700; }
|
|
1200
|
-
.casino-stats-panel .cstats-v.pos { color: #3fb950; }
|
|
1201
|
-
.casino-stats-panel .cstats-v.neg { color: #f85149; }
|
|
1202
|
-
.casino-stats-panel .cstats-v.gold { color: #ffd400; }
|
|
1203
|
-
.casino-stats-panel .cstats-v.neon { color: #29d4ff; }
|
|
1204
|
-
|
|
1205
1213
|
@media (max-width: 900px) {
|
|
1206
1214
|
}
|
|
1207
1215
|
`;
|
|
@@ -12,10 +12,23 @@ function getDashboardHtml() {
|
|
|
12
12
|
return `
|
|
13
13
|
<div class="header">
|
|
14
14
|
<div class="header-left">
|
|
15
|
-
<span class="header-title"
|
|
15
|
+
<span class="header-title">
|
|
16
|
+
<span class="header-icon" id="header-icon">🏰</span>
|
|
17
|
+
<span class="header-text">Git Watchtower</span>
|
|
18
|
+
</span>
|
|
16
19
|
<span class="header-version" id="version"></span>
|
|
17
20
|
<span class="header-project" id="project-name">-</span>
|
|
18
21
|
</div>
|
|
22
|
+
<!-- Slot reels live in the header so they fit inside the blue banner
|
|
23
|
+
without dropping over the branch list. Hidden until casino-active. -->
|
|
24
|
+
<div class="casino-reels-header" id="casino-reels">
|
|
25
|
+
<div class="casino-reel" data-reel="0">🍒</div>
|
|
26
|
+
<div class="casino-reel" data-reel="1">🍋</div>
|
|
27
|
+
<div class="casino-reel" data-reel="2">🍊</div>
|
|
28
|
+
<div class="casino-reel" data-reel="3">🍇</div>
|
|
29
|
+
<div class="casino-reel" data-reel="4">🎰</div>
|
|
30
|
+
<div class="casino-reel-label" id="casino-reel-label"></div>
|
|
31
|
+
</div>
|
|
19
32
|
<div class="header-right">
|
|
20
33
|
<button class="notif-btn" id="notif-btn" title="Enable desktop notifications">notifications</button>
|
|
21
34
|
<span class="badge" id="status-badge">connecting</span>
|
|
@@ -39,10 +52,14 @@ function getDashboardHtml() {
|
|
|
39
52
|
|
|
40
53
|
<div class="side-panel" id="side-panel">
|
|
41
54
|
<div class="panel-header">Activity Log <button class="sidebar-toggle" id="sidebar-toggle" title="Toggle sidebar">▶</button></div>
|
|
42
|
-
<div class="session-stats-card" id="session-stats-card"></div>
|
|
43
55
|
<div class="activity-log" id="activity-log"></div>
|
|
44
56
|
</div>
|
|
45
57
|
|
|
58
|
+
<!-- Permanent stats row, sits above the keyboard-shortcut footer.
|
|
59
|
+
Hosts grounded session stats by default; the same element re-skins
|
|
60
|
+
to casino-style winnings when state.casinoModeEnabled flips on. -->
|
|
61
|
+
<div class="dashboard-stats" id="dashboard-stats"></div>
|
|
62
|
+
|
|
46
63
|
<div class="footer" id="footer">
|
|
47
64
|
<span><kbd>j</kbd><kbd>k</kbd> navigate</span>
|
|
48
65
|
<span><kbd>Enter</kbd> switch</span>
|
|
@@ -55,29 +72,22 @@ function getDashboardHtml() {
|
|
|
55
72
|
<span><kbd>S</kbd> stash</span>
|
|
56
73
|
<span><kbd>d</kbd> cleanup</span>
|
|
57
74
|
<span><kbd>h</kbd> history</span>
|
|
75
|
+
<span><kbd>c</kbd> casino</span>
|
|
58
76
|
<span><kbd>Esc</kbd> close</span>
|
|
59
|
-
<span class="stats-bar" id="stats-bar"></span>
|
|
60
77
|
</div>
|
|
61
78
|
</div>
|
|
62
79
|
|
|
63
|
-
<!-- Casino Mode overlay layer
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
<!-- Casino Mode overlay layer — viewport-edge effects only. The reels
|
|
81
|
+
and stats live inline in the dashboard now (header / bottom bar);
|
|
82
|
+
this layer is just the marquee strips and the centred win/loss
|
|
83
|
+
banners. Pointer-events stay off so it never blocks clicks. -->
|
|
67
84
|
<div class="casino-layer" id="casino-layer">
|
|
68
|
-
<div class="casino-
|
|
69
|
-
<div class="casino-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<div class="casino-reel" data-reel="2">🎰</div>
|
|
73
|
-
<div class="casino-reel" data-reel="3">🎰</div>
|
|
74
|
-
<div class="casino-reel" data-reel="4">🎰</div>
|
|
75
|
-
<div class="casino-reel-label" id="casino-reel-label"></div>
|
|
76
|
-
</div>
|
|
85
|
+
<div class="casino-edge top"></div>
|
|
86
|
+
<div class="casino-edge bottom"></div>
|
|
87
|
+
<div class="casino-edge left"></div>
|
|
88
|
+
<div class="casino-edge right"></div>
|
|
77
89
|
<div class="casino-overlay" id="casino-win-overlay"></div>
|
|
78
90
|
<div class="casino-overlay loss" id="casino-loss-overlay"></div>
|
|
79
|
-
<div class="casino-badge" id="casino-badge">🎰 MAX ADDICTION 🎰</div>
|
|
80
|
-
<div class="casino-stats-panel" id="casino-stats-panel"></div>
|
|
81
91
|
</div>
|
|
82
92
|
|
|
83
93
|
<div class="flash" id="flash"></div>
|