feat: replace Watchtower theme with OIDC professional design
- Remove Watchtower theme CSS files (tokens_watchtower.css, theme_watchtower.css) - Add OIDC styles.css (professional IT asset management design) - Add dark mode toggle button (moon/sun icon) - Remove custom CSS in favor of OIDC styles.css - Add dark mode persistence with localStorage - Remove bg-noise div (Watchtower-specific) - Wrap content in .container div for OIDC layout Benefits: - Professional gradient header - Light/Dark mode toggle - Better color palette for readability - Consistent with homelab-service-oidc design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -4,99 +4,21 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Safe Kiddo Control</title>
|
||||
<link rel="stylesheet" href="/static/tokens_watchtower.css" />
|
||||
<link rel="stylesheet" href="/static/theme_watchtower.css" />
|
||||
<link rel="stylesheet" href="/static/styles.css" />
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { max-width: 1400px; margin: auto; padding: 2rem; font-family: var(--font-ui); }
|
||||
|
||||
/* Header */
|
||||
header { background: var(--color-surface); padding: 2rem; border-radius: var(--radius-md); margin-bottom: 2rem; border: 1px solid var(--color-border); border-left: 4px solid var(--color-accent); display: flex; justify-content: space-between; align-items: center; }
|
||||
header h1 { color: var(--color-accent); margin: 0; font-size: 1.75rem; text-transform: uppercase; letter-spacing: 0.05em; display: flex; align-items: center; gap: 0.75rem; }
|
||||
header .user-info { color: var(--color-text-muted); font-size: 0.875rem; }
|
||||
|
||||
/* Metrics Dashboard */
|
||||
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; }
|
||||
.metric-card { background: var(--color-surface); padding: 1.5rem; border-radius: var(--radius-md); border: 1px solid var(--color-border); border-left: 3px solid var(--color-accent); transition: all 0.2s; }
|
||||
.metric-card:hover { transform: translateY(-2px); box-shadow: 0 0 20px rgba(0, 224, 143, 0.15); }
|
||||
.metric-card .label { color: var(--color-text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 0.5rem; display: flex; align-items: center; gap: 0.5rem; }
|
||||
.metric-card .value { color: var(--color-accent); font-size: 2rem; font-weight: 700; }
|
||||
.metric-card.warning { border-left-color: var(--color-warning); }
|
||||
.metric-card.warning .value { color: var(--color-warning); }
|
||||
.metric-card.error { border-left-color: var(--color-error); }
|
||||
.metric-card.error .value { color: var(--color-error); }
|
||||
|
||||
/* Sections */
|
||||
section { background: var(--color-surface); padding: 1.5rem; border-radius: var(--radius-md); margin-bottom: 1.5rem; border: 1px solid var(--color-border); }
|
||||
section h3 { color: var(--color-accent); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.875rem; margin-bottom: 1rem; border-bottom: 1px solid var(--color-border); padding-bottom: 0.5rem; display: flex; align-items: center; gap: 0.5rem; }
|
||||
|
||||
/* User Table */
|
||||
.user-table { width: 100%; border-collapse: separate; border-spacing: 0 0.5rem; }
|
||||
.user-table thead th { text-align: left; color: var(--color-text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; padding: 0.5rem 1rem; border-bottom: 1px solid var(--color-border); }
|
||||
.user-table tbody tr { background: rgba(10, 14, 20, 0.4); transition: all 0.2s; }
|
||||
.user-table tbody tr:hover { background: rgba(10, 14, 20, 0.6); transform: scale(1.01); }
|
||||
.user-table tbody td { padding: 1rem; border-top: 1px solid rgba(255, 255, 255, 0.05); }
|
||||
.user-table tbody td:first-child { border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
|
||||
.user-table tbody td:last-child { border-top-right-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
|
||||
|
||||
/* Status Badges */
|
||||
.badge { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.35rem 0.75rem; border-radius: 999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||
.badge.success { background: rgba(0, 224, 143, 0.15); color: var(--color-success); border: 1px solid var(--color-success); }
|
||||
.badge.warning { background: rgba(255, 180, 84, 0.15); color: var(--color-warning); border: 1px solid var(--color-warning); }
|
||||
.badge.error { background: rgba(255, 94, 94, 0.15); color: var(--color-error); border: 1px solid var(--color-error); }
|
||||
.badge.neutral { background: rgba(255, 255, 255, 0.05); color: var(--color-text-muted); border: 1px solid rgba(255, 255, 255, 0.1); }
|
||||
|
||||
/* Buttons */
|
||||
button { padding: 0.75rem 1.5rem; background: var(--color-accent); color: #081015; border: none; border-radius: 999px; cursor: pointer; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; transition: all 0.2s; display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }
|
||||
button:hover:not(:disabled) { box-shadow: 0 0 20px var(--wt-glow); transform: translateY(-2px); }
|
||||
button:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
button.secondary { background: transparent; border: 1px solid var(--color-accent); color: var(--color-accent); }
|
||||
button.secondary:hover:not(:disabled) { background: rgba(0, 224, 143, 0.1); }
|
||||
button.danger { background: var(--color-error); color: #1b0d0d; }
|
||||
button.small { padding: 0.5rem 1rem; font-size: 0.75rem; }
|
||||
|
||||
/* Forms */
|
||||
.form-group { margin-bottom: 1rem; }
|
||||
label { display: block; margin-bottom: 0.5rem; color: var(--color-text-muted); font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||
input, select, textarea { background: rgba(10, 14, 20, 0.6); border: 1px solid rgba(255, 255, 255, 0.15); color: var(--color-text); padding: 0.75rem; border-radius: var(--radius-sm); width: 100%; font-family: inherit; transition: all 0.2s; }
|
||||
input:focus, select:focus, textarea:focus { border-color: var(--color-accent); box-shadow: 0 0 15px var(--wt-glow); outline: none; }
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
|
||||
|
||||
/* Toast Notifications */
|
||||
.toast-container { position: fixed; top: 2rem; right: 2rem; z-index: 1000; display: flex; flex-direction: column; gap: 1rem; max-width: 400px; }
|
||||
.toast { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: 1rem 1.5rem; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); animation: slideIn 0.3s ease; display: flex; align-items: center; gap: 1rem; }
|
||||
.toast.success { border-left: 4px solid var(--color-success); }
|
||||
.toast.error { border-left: 4px solid var(--color-error); }
|
||||
.toast.warning { border-left: 4px solid var(--color-warning); }
|
||||
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
|
||||
|
||||
/* Loading Spinner */
|
||||
.spinner { border: 3px solid rgba(255, 255, 255, 0.1); border-top-color: var(--color-accent); border-radius: 50%; width: 20px; height: 20px; animation: spin 0.8s linear infinite; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
|
||||
/* Modal */
|
||||
.modal { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(4px); align-items: center; justify-content: center; z-index: 999; }
|
||||
.modal.active { display: flex; }
|
||||
.modal-content { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: 2rem; max-width: 500px; width: 90%; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.7); }
|
||||
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; }
|
||||
.modal-header h3 { color: var(--color-accent); margin: 0; }
|
||||
.modal-actions { display: flex; gap: 1rem; justify-content: flex-end; margin-top: 1.5rem; }
|
||||
|
||||
/* Details/Accordion */
|
||||
details { margin-top: 1rem; background: rgba(10, 14, 20, 0.3); padding: 1rem; border-radius: var(--radius-sm); border: 1px solid rgba(255, 255, 255, 0.05); }
|
||||
summary { cursor: pointer; color: var(--color-accent); font-weight: 600; user-select: none; display: flex; align-items: center; gap: 0.5rem; }
|
||||
|
||||
/* Utility */
|
||||
.hidden { display: none; }
|
||||
.text-muted { color: var(--color-text-muted); }
|
||||
.text-center { text-align: center; }
|
||||
.mt-1 { margin-top: 1rem; }
|
||||
.mb-1 { margin-bottom: 1rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="bg-noise"></div>
|
||||
<!-- Dark Mode Toggle -->
|
||||
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle dark mode">
|
||||
<svg class="moon-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
|
||||
</svg>
|
||||
<svg class="sun-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Header -->
|
||||
<header>
|
||||
@ -678,6 +600,18 @@
|
||||
// Initialize
|
||||
checkSession();
|
||||
checkOidcStatus();
|
||||
|
||||
// Dark Mode Toggle
|
||||
function toggleTheme() {
|
||||
document.body.classList.toggle('dark-mode');
|
||||
localStorage.setItem('darkMode', document.body.classList.contains('dark-mode'));
|
||||
}
|
||||
|
||||
// Load dark mode preference
|
||||
if (localStorage.getItem('darkMode') === 'true') {
|
||||
document.body.classList.add('dark-mode');
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user