✨ Features: - Complete light theme with improved color palette - Theme switcher in header with sun/moon icons - Theme persistence using localStorage - Smooth transitions between themes 🎨 Theme Improvements: - Softer, easier-on-eyes light theme colors - Fixed text contrast issues across all components - Enhanced member card and tab text readability - Fixed hover effects that made text disappear - Improved member overlay header and body styling 🔧 Technical Implementation: - CSS variables system for easy theme management - JavaScript ThemeManager class for theme switching - Responsive design for mobile devices - Comprehensive hover state fixes - Z-index solutions for text visibility 📱 Components Fixed: - Member cards (hostname, IP, latency, details) - Navigation tabs and content - Task summaries and progress items - Capability forms and API endpoints - Member overlay popup - Form inputs and dropdowns - Status indicators and label chips 🎯 Accessibility: - WCAG AA contrast compliance - Proper color hierarchy - Clear visual feedback - Mobile-responsive design Files added: - public/styles/theme.css - Theme system and variables - public/scripts/theme-manager.js - Theme management logic - THEME_README.md - Comprehensive documentation - THEME_IMPROVEMENTS.md - Improvement details Files modified: - public/index.html - Added theme switcher and script includes - public/styles/main.css - Updated to use CSS variables
171 lines
7.9 KiB
HTML
171 lines
7.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Member Card & Tab Contrast Test</title>
|
|
<link rel="stylesheet" href="public/styles/main.css">
|
|
<link rel="stylesheet" href="public/styles/theme.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="main-navigation">
|
|
<div class="nav-left">
|
|
<button class="nav-tab active">🌐 Test</button>
|
|
</div>
|
|
<div class="nav-right">
|
|
<div class="theme-switcher">
|
|
<span class="theme-label">Theme:</span>
|
|
<button class="theme-toggle" id="theme-toggle" title="Toggle theme">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<circle cx="12" cy="12" r="5"/>
|
|
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div class="cluster-status">🚀 Test Online</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="cluster-section">
|
|
<h2>Member Card & Tab Contrast Test</h2>
|
|
<p>Testing text readability in member cards and tabs for both themes.</p>
|
|
|
|
<!-- Member Cards Test -->
|
|
<div class="members-grid">
|
|
<div class="member-card">
|
|
<div class="member-header">
|
|
<div class="member-info">
|
|
<div class="member-row-1">
|
|
<div class="status-hostname-group">
|
|
<span class="member-status status-online">●</span>
|
|
<span class="member-hostname">Primary Node</span>
|
|
</div>
|
|
<span class="member-ip">192.168.1.100</span>
|
|
<div class="member-latency">
|
|
<span class="latency-label">Latency:</span>
|
|
<span class="latency-value">5ms</span>
|
|
</div>
|
|
</div>
|
|
<div class="member-row-2">
|
|
<div class="member-labels">
|
|
<span class="label-chip">primary</span>
|
|
<span class="label-chip">controller</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="member-details">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Status:</span>
|
|
<span class="detail-value">Online</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Uptime:</span>
|
|
<span class="detail-value">2d 14h 32m</span>
|
|
</div>
|
|
<div class="api-endpoints">
|
|
<h4>API Endpoints</h4>
|
|
<div class="endpoint-item">GET /api/status</div>
|
|
<div class="endpoint-item">POST /api/commands</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="member-card">
|
|
<div class="member-header">
|
|
<div class="member-info">
|
|
<div class="member-row-1">
|
|
<div class="status-hostname-group">
|
|
<span class="member-status status-offline">●</span>
|
|
<span class="member-hostname">Secondary Node</span>
|
|
</div>
|
|
<span class="member-ip">192.168.1.101</span>
|
|
<div class="member-latency">
|
|
<span class="latency-label">Latency:</span>
|
|
<span class="latency-value">N/A</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabs Test -->
|
|
<div class="tabs-container">
|
|
<div class="tabs-header">
|
|
<button class="tab-button active">Cluster Members</button>
|
|
<button class="tab-button">Tasks</button>
|
|
<button class="tab-button">Capabilities</button>
|
|
</div>
|
|
<div class="tab-content active">
|
|
<h3>Cluster Members Tab</h3>
|
|
<p>This tab shows all cluster members with their status and details.</p>
|
|
<div class="task-item">
|
|
<div class="task-header">
|
|
<span class="task-name">Health Check Task</span>
|
|
<span class="task-status running">Running</span>
|
|
</div>
|
|
<div class="task-details">
|
|
<span class="task-interval">Interval: 30s</span>
|
|
<span class="task-enabled">Enabled: Yes</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tab-content">
|
|
<h3>Tasks Tab</h3>
|
|
<p>This tab shows background tasks and their status.</p>
|
|
</div>
|
|
<div class="tab-content">
|
|
<h3>Capabilities Tab</h3>
|
|
<p>This tab shows available API capabilities.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Capabilities Test -->
|
|
<div class="capabilities-list">
|
|
<div class="capability-item">
|
|
<div class="capability-header">
|
|
<span class="cap-method">GET</span>
|
|
<span class="cap-uri">/api/cluster/status</span>
|
|
<button class="cap-call-btn">Call</button>
|
|
</div>
|
|
<div class="capability-form">
|
|
<div class="capability-param">
|
|
<span class="param-name">Node ID</span>
|
|
<input type="text" class="param-input" placeholder="Enter node ID">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="public/scripts/theme-manager.js"></script>
|
|
<script>
|
|
// Simple tab switching for demo
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const tabButtons = document.querySelectorAll('.tab-button');
|
|
const tabContents = document.querySelectorAll('.tab-content');
|
|
|
|
tabButtons.forEach(button => {
|
|
button.addEventListener('click', () => {
|
|
// Remove active class from all buttons and contents
|
|
tabButtons.forEach(btn => btn.classList.remove('active'));
|
|
tabContents.forEach(content => content.classList.remove('active'));
|
|
|
|
// Add active class to clicked button
|
|
button.classList.add('active');
|
|
|
|
// Show corresponding content
|
|
const tabIndex = Array.from(tabButtons).indexOf(button);
|
|
if (tabContents[tabIndex]) {
|
|
tabContents[tabIndex].classList.add('active');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|