Complete private Monero miner control stack.

Implement Windows agent with RandomX mining and WebSocket fleet reporting, wire dashboard settings into the builder with saved exe paths, and add project README.
This commit is contained in:
drjones
2026-05-26 22:51:47 -07:00
commit 6c42f2b600
48 changed files with 10001 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
:root {
--bg-primary: #0a0e17;
--bg-secondary: #111827;
--bg-card: #1a2235;
--bg-hover: #243049;
--border-color: #2a3a5c;
--text-primary: #e2e8f0;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--accent-green: #22c55e;
--accent-red: #ef4444;
--accent-yellow: #eab308;
--accent-blue: #3b82f6;
--accent-purple: #8b5cf6;
--accent-cyan: #06b6d4;
--online-color: #22c55e;
--offline-color: #64748b;
--error-color: #ef4444;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
min-height: 100vh;
}
a {
color: var(--accent-blue);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--bg-secondary);
}
::-webkit-scrollbar-thumb {
background: var(--border-color);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--text-muted);
}
/* Utility classes */
.card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
box-shadow: var(--shadow);
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.625rem 1.25rem;
border: none;
border-radius: 8px;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: var(--accent-blue);
color: white;
}
.btn-primary:hover {
background: #2563eb;
}
.btn-success {
background: var(--accent-green);
color: white;
}
.btn-success:hover {
background: #16a34a;
}
.btn-danger {
background: var(--accent-red);
color: white;
}
.btn-danger:hover {
background: #dc2626;
}
.btn-outline {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-primary);
}
.btn-outline:hover {
background: var(--bg-hover);
}
/* Form elements */
.input {
width: 100%;
padding: 0.625rem 0.875rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
font-size: 0.875rem;
transition: border-color 0.2s ease;
}
.input:focus {
outline: none;
border-color: var(--accent-blue);
}
.select {
width: 100%;
padding: 0.625rem 0.875rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
font-size: 0.875rem;
cursor: pointer;
}
.select:focus {
outline: none;
border-color: var(--accent-blue);
}
.checkbox {
width: 1.125rem;
height: 1.125rem;
accent-color: var(--accent-blue);
cursor: pointer;
}
.label {
display: block;
font-size: 0.8125rem;
font-weight: 500;
color: var(--text-secondary);
margin-bottom: 0.375rem;
}
/* Status badges */
.status-badge {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-badge.online {
background: rgba(34, 197, 94, 0.15);
color: var(--online-color);
}
.status-badge.offline {
background: rgba(100, 116, 139, 0.15);
color: var(--offline-color);
}
.status-badge.error {
background: rgba(239, 68, 68, 0.15);
color: var(--error-color);
}
.status-dot {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: inline-block;
}
.status-dot.online {
background: var(--online-color);
box-shadow: 0 0 6px var(--online-color);
}
.status-dot.offline {
background: var(--offline-color);
}
.status-dot.error {
background: var(--error-color);
box-shadow: 0 0 6px var(--error-color);
}
/* Grid layouts */
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.grid-4 {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
@media (max-width: 1200px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}
/* Animations */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.3s ease forwards;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.pulse {
animation: pulse 2s ease-in-out infinite;
}