secubox-openwrt/secubox-tools/webui/static/css/site.css
CyberMind-FR 0d6aaa1111 feat(webui): add Project Hub workspace and remove Command Center glow effects
- Add complete Project Hub & Workspace Interface implementation
  - New data models: Project, ModuleKit, Workspace
  - 3 fixture projects (cybermind.fr, cybermood.eu, secubox-c3)
  - 4 module kits (Security, Network, Automation, Media)
  - Workspace routes with project switching and kit installation
  - 4 workspace tabs: Overview, Module Kits, Devices, Composer
  - New navigation item: Workspace (7th section)

- Remove all glowing effects from UI
  - Remove Command Center widget glow and backdrop blur
  - Remove device status indicator glow
  - Remove toggle button glow effects

- Extend DataStore with 13 new methods for workspace management
- Add 270+ lines of workspace-specific CSS with responsive layouts
- Create workspace templates and result partials

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-03 08:10:22 +01:00

978 lines
17 KiB
CSS

:root {
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 0.75rem;
--space-lg: 1rem;
--space-xl: 1.5rem;
--radius-sm: 0.5rem;
--radius-md: 0.75rem;
--radius-lg: 1rem;
--shadow-card: 0 10px 25px rgba(20, 21, 47, 0.12);
--secubox-bg: #f5f6fb;
--secubox-panel: #ffffff;
--secubox-text: #1f2333;
--luci-bg: #11131a;
--luci-panel: #1c1f2b;
--luci-text: #f5f6fb;
--accent: #4b6bfb;
--accent-soft: rgba(75, 107, 251, 0.15);
--border: rgba(31, 35, 51, 0.1);
}
body.theme-secubox {
background: var(--secubox-bg);
color: var(--secubox-text);
}
body.theme-luci {
background: var(--luci-bg);
color: var(--luci-text);
}
.app-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 2rem;
}
.theme-luci .app-header {
background: #0d0f16;
}
.app-main {
padding: 0 2rem 2rem;
}
.panel {
background: var(--secubox-panel);
border-radius: 1rem;
padding: 1.5rem;
margin-bottom: 1.5rem;
border: 1px solid var(--border);
}
.theme-luci .panel {
background: var(--luci-panel);
border-color: rgba(255, 255, 255, 0.08);
}
.panel-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.module-grid, .preset-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 1rem;
}
.module-card, .preset-card {
border: 1px solid var(--border);
border-radius: 0.75rem;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
background: rgba(255, 255, 255, 0.6);
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.theme-luci .module-card, .theme-luci .preset-card {
background: rgba(255, 255, 255, 0.02);
border-color: rgba(255, 255, 255, 0.08);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25);
}
.module-card:hover,
.preset-card:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-card);
}
.btn {
background: var(--accent);
color: white;
border: none;
border-radius: 999px;
padding: 0.5rem 1rem;
cursor: pointer;
font-weight: 600;
}
.btn.ghost {
background: transparent;
color: inherit;
border: 1px solid var(--border);
}
.chip {
display: inline-flex;
align-items: center;
padding: 0.2rem 0.6rem;
border-radius: 999px;
background: var(--accent-soft);
color: var(--accent);
font-size: 0.85rem;
}
.chip.small {
font-size: 0.75rem;
}
.chip-active {
background: var(--accent);
color: white;
}
.pill {
padding: 0.2rem 0.6rem;
border-radius: 0.4rem;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.pill-stable {
background: rgba(76, 175, 80, 0.2);
color: #2e7d32;
}
.pill-beta {
background: rgba(255, 193, 7, 0.2);
color: #f57f17;
}
.pill-ok { background: rgba(76, 175, 80, 0.2); color: #2e7d32; }
.pill-warn { background: rgba(255, 152, 0, 0.2); color: #e65100; }
.tag-row {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.emoji-badge {
font-size: 1.4rem;
margin-right: var(--space-sm);
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
}
.card-meta {
display: flex;
align-items: center;
gap: var(--space-sm);
}
.card-actions {
display: flex;
gap: var(--space-sm);
flex-wrap: wrap;
}
.action {
font-size: 0.85rem;
color: rgba(31, 35, 51, 0.7);
}
.theme-luci .action {
color: rgba(255, 255, 255, 0.7);
}
.preset-result {
margin-top: 1rem;
padding: 1rem;
border-radius: 0.75rem;
border: 1px dashed var(--border);
}
.custom-run {
margin-top: 1.5rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
}
.custom-run-form {
display: flex;
flex-direction: column;
gap: 0.8rem;
margin-top: 0.5rem;
}
.custom-run-form select,
.custom-run-form textarea {
width: 100%;
padding: 0.5rem;
border-radius: 0.5rem;
border: 1px solid var(--border);
background: rgba(255, 255, 255, 0.7);
}
.theme-luci .custom-run-form select,
.theme-luci .custom-run-form textarea {
background: rgba(0, 0, 0, 0.2);
color: inherit;
border-color: rgba(255, 255, 255, 0.08);
}
.run-result pre {
background: rgba(0, 0, 0, 0.05);
padding: 0.75rem;
border-radius: 0.5rem;
overflow-x: auto;
}
.theme-luci .run-result pre {
background: rgba(0, 0, 0, 0.4);
}
.empty-state {
grid-column: 1 / -1;
padding: var(--space-xl);
text-align: center;
border: 1px dashed var(--border);
border-radius: var(--radius-lg);
}
.alert.warning {
border-left: 4px solid #ff9800;
padding-left: 0.5rem;
margin-bottom: 0.5rem;
}
.badge {
padding: 0.2rem 0.6rem;
border-radius: 999px;
background: var(--accent-soft);
color: var(--accent);
font-weight: 600;
margin-right: 0.5rem;
}
.theme-switcher {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* =================================================================
PHASE 1: New Interactive Components
================================================================= */
/* App Layout with Sidebar */
.app-layout {
display: flex;
min-height: calc(100vh - 80px);
}
/* Navigation Sidebar */
.app-sidebar {
width: 220px;
background: var(--secubox-panel);
border-right: 1px solid var(--border);
padding: 1.5rem 0;
flex-shrink: 0;
}
.theme-luci .app-sidebar {
background: var(--luci-panel);
border-right-color: rgba(255, 255, 255, 0.08);
}
.nav-menu {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.nav-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1.5rem;
text-decoration: none;
color: var(--secubox-text);
transition: all 0.2s ease;
position: relative;
}
.theme-luci .nav-link {
color: var(--luci-text);
}
.nav-link:hover {
background: rgba(75, 107, 251, 0.1);
}
.nav-link.nav-active {
background: var(--accent-soft);
color: var(--accent);
font-weight: 600;
}
.nav-link.nav-active::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: var(--accent);
}
.nav-emoji {
font-size: 1.25rem;
line-height: 1;
}
.nav-label {
font-size: 0.9375rem;
}
/* Update main content area for sidebar layout */
.app-layout .app-main {
flex: 1;
padding: 2rem;
overflow-y: auto;
}
/* Toast Notifications */
.toast {
position: fixed;
top: 2rem;
right: 2rem;
min-width: 300px;
padding: 1rem 1.5rem;
border-radius: var(--radius-md);
background: white;
border-left: 4px solid var(--accent);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
z-index: 1000;
display: flex;
align-items: center;
gap: 0.75rem;
}
.theme-luci .toast {
background: var(--luci-panel);
color: var(--luci-text);
}
.toast-info {
border-left-color: #4b6bfb;
}
.toast-success {
border-left-color: #22c55e;
}
.toast-warning {
border-left-color: #f59e0b;
}
.toast-error {
border-left-color: #ef4444;
}
/* Dropdown Menus */
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
margin-top: 0.5rem;
background: white;
border: 1px solid var(--border);
border-radius: var(--radius-md);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12);
min-width: 200px;
z-index: 100;
padding: 0.5rem;
}
.theme-luci .dropdown-menu {
background: var(--luci-panel);
border-color: rgba(255, 255, 255, 0.1);
}
.dropdown-item {
width: 100%;
text-align: left;
padding: 0.625rem 0.75rem;
border: none;
background: transparent;
cursor: pointer;
border-radius: 0.375rem;
transition: background 0.15s ease;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
}
.dropdown-item:hover {
background: rgba(75, 107, 251, 0.1);
}
.dropdown-item-icon {
font-size: 1rem;
opacity: 0.7;
}
.dropdown-item-label {
flex: 1;
}
.dropdown-item-shortcut {
font-size: 0.75rem;
opacity: 0.5;
font-family: monospace;
}
.dropdown-divider {
height: 1px;
background: var(--border);
margin: 0.5rem 0;
}
.dropdown-header {
padding: 0.5rem 0.75rem;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
opacity: 0.6;
letter-spacing: 0.05em;
}
/* Modal Overlay */
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
.modal-content {
background: white;
border-radius: 1rem;
max-width: 600px;
width: 100%;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.theme-luci .modal-content {
background: var(--luci-panel);
}
.modal-header {
padding: 1.5rem;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-body {
padding: 1.5rem;
}
.modal-footer {
padding: 1.5rem;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
gap: 0.75rem;
}
/* Enhanced Card Components */
.card {
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 1rem;
background: rgba(255, 255, 255, 0.6);
display: flex;
flex-direction: column;
gap: 0.75rem;
transition: all 0.2s ease;
position: relative;
}
.theme-luci .card {
background: rgba(28, 31, 43, 0.8);
border-color: rgba(255, 255, 255, 0.08);
}
.card:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-card);
}
.card-header {
display: flex;
align-items: flex-start;
gap: 0.75rem;
}
.card-icon {
flex-shrink: 0;
}
.card-emoji {
font-size: 1.5rem;
line-height: 1;
}
.card-title-group {
flex: 1;
min-width: 0;
}
.card-title {
margin: 0;
font-size: 1rem;
font-weight: 600;
line-height: 1.4;
}
.card-subtitle {
font-size: 0.8125rem;
opacity: 0.7;
}
.card-body {
display: flex;
flex-direction: column;
gap: 0.75rem;
flex: 1;
}
.card-description {
margin: 0;
font-size: 0.875rem;
line-height: 1.5;
opacity: 0.85;
}
.card-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 0.5rem;
border-top: 1px solid var(--border);
}
.card-actions {
display: flex;
gap: 0.5rem;
align-items: center;
}
/* Drag-Drop States */
.card-dragging {
opacity: 0.5;
transform: scale(0.95);
cursor: grabbing;
}
.card-drag-over {
border: 2px dashed var(--accent);
background: var(--accent-soft);
}
.drag-handle {
cursor: grab;
padding: 0.25rem 0.5rem;
opacity: 0.5;
user-select: none;
font-size: 0.875rem;
line-height: 1;
}
.drag-handle:hover {
opacity: 1;
}
.drag-handle:active {
cursor: grabbing;
}
/* Sortable zones */
.sortable-ghost {
opacity: 0.4;
}
.sortable-chosen {
cursor: grabbing;
}
/* Profile boards (Kanban-style) */
.profile-board {
background: var(--secubox-panel);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 1rem;
min-height: 300px;
}
.theme-luci .profile-board {
background: var(--luci-panel);
border-color: rgba(255, 255, 255, 0.08);
}
.profile-modules {
display: flex;
flex-direction: column;
gap: 0.75rem;
min-height: 200px;
padding: 0.5rem;
}
/* Template builder canvas */
.template-canvas {
background: rgba(75, 107, 251, 0.05);
border: 2px dashed var(--border);
border-radius: var(--radius-lg);
min-height: 400px;
padding: 1.5rem;
}
.canvas-dropzone {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
/* ===== Workspace Styles ===== */
.workspace-container {
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: 0;
}
.workspace-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.25rem;
background: var(--card-bg);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
margin-bottom: 1rem;
}
.project-selector {
display: flex;
gap: 1rem;
align-items: center;
}
.project-dropdown {
padding: 0.625rem 1rem;
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: white;
font-size: 1rem;
min-width: 250px;
font-family: inherit;
}
.project-info {
display: flex;
gap: 1rem;
align-items: center;
font-size: 0.875rem;
color: var(--text-muted);
}
.project-url {
font-weight: 500;
}
.device-count {
padding-left: 1rem;
border-left: 1px solid var(--border);
}
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-weight: 500;
text-transform: uppercase;
font-size: 0.75rem;
background: var(--accent-bg, #f3f4f6);
color: var(--accent, #6b7280);
}
.status-badge.production {
background: #10b981;
color: white;
}
.status-badge.staging {
background: #f59e0b;
color: white;
}
.status-badge.development {
background: #3b82f6;
color: white;
}
.status-badge.personal {
background: #8b5cf6;
color: white;
}
.workspace-tabs {
display: flex;
gap: 0.5rem;
border-bottom: 2px solid var(--border);
padding: 0;
margin-bottom: 1.5rem;
}
.workspace-tabs button {
padding: 0.75rem 1.5rem;
border: none;
background: none;
cursor: pointer;
border-bottom: 3px solid transparent;
transition: all 0.2s;
font-weight: 500;
color: var(--text-muted);
font-size: 0.95rem;
font-family: inherit;
}
.workspace-tabs button.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.workspace-tabs button:hover:not(:disabled) {
color: var(--accent);
background: var(--hover-bg, rgba(75, 107, 251, 0.05));
}
.workspace-tabs button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.workspace-content {
min-height: 500px;
}
.tab-panel {
animation: fadeIn 0.2s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Module Kit Cards */
.kit-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1.5rem;
padding: 0;
}
.kit-card {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 1.5rem;
transition: all 0.2s;
}
.kit-card:hover {
box-shadow: var(--shadow-md);
transform: translateY(-2px);
border-color: var(--accent);
}
.kit-header {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin-bottom: 1rem;
}
.kit-emoji {
font-size: 2rem;
line-height: 1;
}
.kit-stats {
display: flex;
gap: 1rem;
font-size: 0.85rem;
color: var(--text-muted);
}
.kit-modules-count {
font-size: 0.875rem;
}
.kit-actions {
display: flex;
gap: 0.5rem;
margin-top: 1rem;
}
/* Device Grid */
.device-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
padding: 0;
}
.device-card {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--radius-md);
transition: all 0.2s;
}
.device-card:hover {
box-shadow: var(--shadow-sm);
}
.device-status {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 0.5rem;
}
.device-status.online {
background: #10b981;
}
.device-status.offline {
background: #ef4444;
}
/* Composer Canvas */
.composer-container {
display: grid;
grid-template-columns: 250px 1fr;
gap: 1.5rem;
height: 600px;
}
.module-palette {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 1rem;
overflow-y: auto;
}
.composer-canvas {
background: var(--bg-secondary, #f9fafb);
border: 2px dashed var(--border);
border-radius: var(--radius-lg);
position: relative;
overflow: hidden;
}
/* Stat Cards */
.stat-card {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 1rem;
text-align: center;
}
.stat-value {
font-size: 1.75rem;
font-weight: 600;
color: var(--accent);
margin-bottom: 0.25rem;
}
.stat-label {
font-size: 0.875rem;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
/* Category chips in workspace */
.chip-active {
background: var(--accent);
color: white;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.app-layout {
flex-direction: column;
}
.app-sidebar {
width: 100%;
border-right: none;
border-bottom: 1px solid var(--border);
}
.nav-menu {
flex-direction: row;
overflow-x: auto;
padding: 0 1rem;
}
.nav-link {
flex-direction: column;
gap: 0.25rem;
padding: 0.75rem 1rem;
white-space: nowrap;
}
.nav-label {
font-size: 0.75rem;
}
.toast {
left: 1rem;
right: 1rem;
top: 1rem;
min-width: 0;
}
}