:root { /* Colors */ --color-background: rgba(252, 252, 249, 1); --color-surface: rgba(255, 255, 253, 1); --color-text: rgba(19, 52, 59, 1); --color-text-secondary: rgba(98, 108, 113, 1); --color-primary: rgba(33, 128, 141, 1); --color-primary-hover: rgba(29, 116, 128, 1); --color-primary-active: rgba(26, 104, 115, 1); --color-secondary: rgba(94, 82, 64, 0.12); --color-secondary-hover: rgba(94, 82, 64, 0.2); --color-secondary-active: rgba(94, 82, 64, 0.25); --color-border: rgba(94, 82, 64, 0.2); --color-btn-primary-text: rgba(252, 252, 249, 1); --color-card-border: rgba(94, 82, 64, 0.12); --color-card-border-inner: rgba(94, 82, 64, 0.12); --color-error: rgba(192, 21, 47, 1); --color-success: rgba(33, 128, 141, 1); --color-warning: rgba(168, 75, 47, 1); --color-info: rgba(98, 108, 113, 1); --color-focus-ring: rgba(33, 128, 141, 0.4); --color-select-caret: rgba(19, 52, 59, 0.8); /* Common style patterns */ --focus-ring: 0 0 0 3px var(--color-focus-ring); --focus-outline: 2px solid var(--color-primary); --status-bg-opacity: 0.15; --status-border-opacity: 0.25; --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); /* RGB versions for opacity control */ --color-success-rgb: 33, 128, 141; --color-error-rgb: 192, 21, 47; --color-warning-rgb: 168, 75, 47; --color-info-rgb: 98, 108, 113; /* Typography */ --font-family-base: "FKGroteskNeue", "Geist", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-family-mono: "Berkeley Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; --font-size-xs: 11px; --font-size-sm: 12px; --font-size-base: 14px; --font-size-md: 14px; --font-size-lg: 16px; --font-size-xl: 18px; --font-size-2xl: 20px; --font-size-3xl: 24px; --font-size-4xl: 30px; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 550; --font-weight-bold: 600; --line-height-tight: 1.2; --line-height-normal: 1.5; --letter-spacing-tight: -0.01em; /* Spacing */ --space-0: 0; --space-1: 1px; --space-2: 2px; --space-4: 4px; --space-6: 6px; --space-8: 8px; --space-10: 10px; --space-12: 12px; --space-16: 16px; --space-20: 20px; --space-24: 24px; --space-32: 32px; /* Border Radius */ --radius-sm: 6px; --radius-base: 8px; --radius-md: 10px; --radius-lg: 12px; --radius-full: 9999px; /* Shadows */ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.02); --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.04), 0 2px 4px -1px rgba(0, 0, 0, 0.02); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.04), 0 4px 6px -2px rgba(0, 0, 0, 0.02); --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.03); /* Animation */ --duration-fast: 150ms; --duration-normal: 250ms; --ease-standard: cubic-bezier(0.16, 1, 0.3, 1); /* Layout */ --container-sm: 640px; --container-md: 768px; --container-lg: 1024px; --container-xl: 1280px; } /* Dark mode colors */ @media (prefers-color-scheme: dark) { :root { --color-background: rgba(31, 33, 33, 1); --color-surface: rgba(38, 40, 40, 1); --color-text: rgba(245, 245, 245, 1); --color-text-secondary: rgba(167, 169, 169, 0.7); --color-primary: rgba(50, 184, 198, 1); --color-primary-hover: rgba(45, 166, 178, 1); --color-primary-active: rgba(41, 150, 161, 1); --color-secondary: rgba(119, 124, 124, 0.15); --color-secondary-hover: rgba(119, 124, 124, 0.25); --color-secondary-active: rgba(119, 124, 124, 0.3); --color-border: rgba(119, 124, 124, 0.3); --color-error: rgba(255, 84, 89, 1); --color-success: rgba(50, 184, 198, 1); --color-warning: rgba(230, 129, 97, 1); --color-info: rgba(167, 169, 169, 1); --color-focus-ring: rgba(50, 184, 198, 0.4); --color-btn-primary-text: rgba(19, 52, 59, 1); --color-card-border: rgba(119, 124, 124, 0.2); --color-card-border-inner: rgba(119, 124, 124, 0.15); --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.15); --button-border-secondary: rgba(119, 124, 124, 0.2); --color-border-secondary: rgba(119, 124, 124, 0.2); --color-select-caret: rgba(245, 245, 245, 0.8); /* Common style patterns - updated for dark mode */ --focus-ring: 0 0 0 3px var(--color-focus-ring); --focus-outline: 2px solid var(--color-primary); --status-bg-opacity: 0.15; --status-border-opacity: 0.25; --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); /* RGB versions for dark mode */ --color-success-rgb: 50, 184, 198; --color-error-rgb: 255, 84, 89; --color-warning-rgb: 230, 129, 97; --color-info-rgb: 167, 169, 169; } } /* Data attribute for manual theme switching */ [data-color-scheme="dark"] { --color-background: rgba(31, 33, 33, 1); --color-surface: rgba(38, 40, 40, 1); --color-text: rgba(245, 245, 245, 1); --color-text-secondary: rgba(167, 169, 169, 0.7); --color-primary: rgba(50, 184, 198, 1); --color-primary-hover: rgba(45, 166, 178, 1); --color-primary-active: rgba(41, 150, 161, 1); --color-secondary: rgba(119, 124, 124, 0.15); --color-secondary-hover: rgba(119, 124, 124, 0.25); --color-secondary-active: rgba(119, 124, 124, 0.3); --color-border: rgba(119, 124, 124, 0.3); --color-error: rgba(255, 84, 89, 1); --color-success: rgba(50, 184, 198, 1); --color-warning: rgba(230, 129, 97, 1); --color-info: rgba(167, 169, 169, 1); --color-focus-ring: rgba(50, 184, 198, 0.4); --color-btn-primary-text: rgba(19, 52, 59, 1); --color-card-border: rgba(119, 124, 124, 0.15); --color-card-border-inner: rgba(119, 124, 124, 0.15); --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.15); --color-border-secondary: rgba(119, 124, 124, 0.2); --color-select-caret: rgba(245, 245, 245, 0.8); /* Common style patterns - updated for dark mode */ --focus-ring: 0 0 0 3px var(--color-focus-ring); --focus-outline: 2px solid var(--color-primary); --status-bg-opacity: 0.15; --status-border-opacity: 0.25; --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); /* RGB versions for dark mode */ --color-success-rgb: 50, 184, 198; --color-error-rgb: 255, 84, 89; --color-warning-rgb: 230, 129, 97; --color-info-rgb: 167, 169, 169; } [data-color-scheme="light"] { --color-background: rgba(252, 252, 249, 1); --color-surface: rgba(255, 255, 253, 1); --color-text: rgba(19, 52, 59, 1); --color-text-secondary: rgba(98, 108, 113, 1); --color-primary: rgba(33, 128, 141, 1); --color-primary-hover: rgba(29, 116, 128, 1); --color-primary-active: rgba(26, 104, 115, 1); --color-secondary: rgba(94, 82, 64, 0.12); --color-secondary-hover: rgba(94, 82, 64, 0.2); --color-secondary-active: rgba(94, 82, 64, 0.25); --color-border: rgba(94, 82, 64, 0.2); --color-btn-primary-text: rgba(252, 252, 249, 1); --color-card-border: rgba(94, 82, 64, 0.12); --color-card-border-inner: rgba(94, 82, 64, 0.12); --color-error: rgba(192, 21, 47, 1); --color-success: rgba(33, 128, 141, 1); --color-warning: rgba(168, 75, 47, 1); --color-info: rgba(98, 108, 113, 1); --color-focus-ring: rgba(33, 128, 141, 0.4); /* RGB versions for light mode */ --color-success-rgb: 33, 128, 141; --color-error-rgb: 192, 21, 47; --color-warning-rgb: 168, 75, 47; --color-info-rgb: 98, 108, 113; } /* Base styles */ html { font-size: var(--font-size-base); font-family: var(--font-family-base); line-height: var(--line-height-normal); color: var(--color-text); background-color: var(--color-background); -webkit-font-smoothing: antialiased; box-sizing: border-box; } body { margin: 0; padding: 0; } *, *::before, *::after { box-sizing: inherit; } /* Typography */ h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); color: var(--color-text); letter-spacing: var(--letter-spacing-tight); } h1 { font-size: var(--font-size-4xl); } h2 { font-size: var(--font-size-3xl); } h3 { font-size: var(--font-size-2xl); } h4 { font-size: var(--font-size-xl); } h5 { font-size: var(--font-size-lg); } h6 { font-size: var(--font-size-md); } p { margin: 0 0 var(--space-16) 0; } a { color: var(--color-primary); text-decoration: none; transition: color var(--duration-fast) var(--ease-standard); } a:hover { color: var(--color-primary-hover); } code, pre { font-family: var(--font-family-mono); font-size: calc(var(--font-size-base) * 0.95); background-color: var(--color-secondary); border-radius: var(--radius-sm); } code { padding: var(--space-1) var(--space-4); } pre { padding: var(--space-16); margin: var(--space-16) 0; overflow: auto; border: 1px solid var(--color-border); } pre code { background: none; padding: 0; } /* Buttons */ .btn { display: inline-flex; align-items: center; justify-content: center; padding: var(--space-8) var(--space-16); border-radius: var(--radius-base); font-size: var(--font-size-base); font-weight: 500; line-height: 1.5; cursor: pointer; transition: all var(--duration-normal) var(--ease-standard); border: none; text-decoration: none; position: relative; } .btn:focus-visible { outline: none; box-shadow: var(--focus-ring); } .btn--primary { background: var(--color-primary); color: var(--color-btn-primary-text); } .btn--primary:hover { background: var(--color-primary-hover); } .btn--primary:active { background: var(--color-primary-active); } .btn--secondary { background: var(--color-secondary); color: var(--color-text); } .btn--secondary:hover { background: var(--color-secondary-hover); } .btn--secondary:active { background: var(--color-secondary-active); } .btn--accent { background: rgba(139, 92, 246, 0.2); color: #a78bfa; border-color: rgba(139, 92, 246, 0.3); } .btn--accent:hover { background: rgba(139, 92, 246, 0.3); border-color: rgba(139, 92, 246, 0.5); } .btn--accent:active { background: rgba(139, 92, 246, 0.15); } .btn--outline { background: transparent; border: 1px solid var(--color-border); color: var(--color-text); } .btn--outline:hover { background: var(--color-secondary); } .btn--sm { padding: var(--space-4) var(--space-12); font-size: var(--font-size-sm); border-radius: var(--radius-sm); } .btn--lg { padding: var(--space-10) var(--space-20); font-size: var(--font-size-lg); border-radius: var(--radius-md); } .btn--full-width { width: 100%; } .btn:disabled { opacity: 0.5; cursor: not-allowed; } /* Form elements */ .form-control { display: block; width: 100%; padding: var(--space-8) var(--space-12); font-size: var(--font-size-md); line-height: 1.5; color: var(--color-text); background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-base); transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); } textarea.form-control { font-family: var(--font-family-base); font-size: var(--font-size-base); } select.form-control { padding: var(--space-8) var(--space-12); -webkit-appearance: none; -moz-appearance: none; appearance: none; background-image: var(--select-caret-light); background-repeat: no-repeat; background-position: right var(--space-12) center; background-size: 16px; padding-right: var(--space-32); } /* Add a dark mode specific caret */ @media (prefers-color-scheme: dark) { select.form-control { background-image: var(--select-caret-dark); } } /* Also handle data-color-scheme */ [data-color-scheme="dark"] select.form-control { background-image: var(--select-caret-dark); } [data-color-scheme="light"] select.form-control { background-image: var(--select-caret-light); } .form-control:focus { border-color: var(--color-primary); outline: var(--focus-outline); } .form-label { display: block; margin-bottom: var(--space-8); font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); } .form-group { margin-bottom: var(--space-16); } /* Card component */ .card { background-color: var(--color-surface); border-radius: var(--radius-lg); border: 1px solid var(--color-card-border); box-shadow: var(--shadow-sm); overflow: hidden; transition: box-shadow var(--duration-normal) var(--ease-standard); } .card:hover { box-shadow: var(--shadow-md); } .card__body { padding: var(--space-16); } .card__header, .card__footer { padding: var(--space-16); border-bottom: 1px solid var(--color-card-border-inner); } /* Status indicators - simplified with CSS variables */ .status { display: inline-flex; align-items: center; padding: var(--space-6) var(--space-12); border-radius: var(--radius-full); font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); } .status--success { background-color: rgba( var(--color-success-rgb, 33, 128, 141), var(--status-bg-opacity) ); color: var(--color-success); border: 1px solid rgba(var(--color-success-rgb, 33, 128, 141), var(--status-border-opacity)); } .status--error { background-color: rgba( var(--color-error-rgb, 192, 21, 47), var(--status-bg-opacity) ); color: var(--color-error); border: 1px solid rgba(var(--color-error-rgb, 192, 21, 47), var(--status-border-opacity)); } .status--warning { background-color: rgba( var(--color-warning-rgb, 168, 75, 47), var(--status-bg-opacity) ); color: var(--color-warning); border: 1px solid rgba(var(--color-warning-rgb, 168, 75, 47), var(--status-border-opacity)); } .status--info { background-color: rgba( var(--color-info-rgb, 98, 108, 113), var(--status-bg-opacity) ); color: var(--color-info); border: 1px solid rgba(var(--color-info-rgb, 98, 108, 113), var(--status-border-opacity)); } /* Container layout */ .container { width: 100%; margin-right: auto; margin-left: auto; padding-right: var(--space-16); padding-left: var(--space-16); } @media (min-width: 640px) { .container { max-width: var(--container-sm); } } @media (min-width: 768px) { .container { max-width: var(--container-md); } } @media (min-width: 1024px) { .container { max-width: var(--container-lg); } } @media (min-width: 1280px) { .container { max-width: var(--container-xl); } } /* Utility classes */ .flex { display: flex; } .flex-col { flex-direction: column; } .items-center { align-items: center; } .justify-center { justify-content: center; } .justify-between { justify-content: space-between; } .gap-4 { gap: var(--space-4); } .gap-8 { gap: var(--space-8); } .gap-16 { gap: var(--space-16); } .m-0 { margin: 0; } .mt-8 { margin-top: var(--space-8); } .mb-8 { margin-bottom: var(--space-8); } .mx-8 { margin-left: var(--space-8); margin-right: var(--space-8); } .my-8 { margin-top: var(--space-8); margin-bottom: var(--space-8); } .p-0 { padding: 0; } .py-8 { padding-top: var(--space-8); padding-bottom: var(--space-8); } .px-8 { padding-left: var(--space-8); padding-right: var(--space-8); } .py-16 { padding-top: var(--space-16); padding-bottom: var(--space-16); } .px-16 { padding-left: var(--space-16); padding-right: var(--space-16); } .block { display: block; } .hidden { display: none; } /* Accessibility */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } :focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* Dark mode specifics */ [data-color-scheme="dark"] .btn--outline { border: 1px solid var(--color-border-secondary); } @font-face { font-family: 'FKGroteskNeue'; src: url('https://www.perplexity.ai/fonts/FKGroteskNeue.woff2') format('woff2'); } /* Custom styles for WiFi DensePose application */ /* Base layout and containers */ body { background-color: var(--color-background); color: var(--color-text); overflow-x: hidden; } .container { max-width: var(--container-xl); margin: 0 auto; padding: var(--space-16); } .header { text-align: center; padding: var(--space-32) 0; } .subtitle { color: var(--color-text-secondary); font-size: var(--font-size-lg); margin-top: var(--space-8); } /* Navigation tabs */ .nav-tabs { display: flex; justify-content: center; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--color-border); margin-bottom: var(--space-24); scrollbar-width: none; -ms-overflow-style: none; } .nav-tabs::-webkit-scrollbar { display: none; } .nav-tab { padding: var(--space-12) var(--space-16); background: none; border: none; color: var(--color-text-secondary); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); cursor: pointer; transition: all var(--duration-normal) var(--ease-standard); white-space: nowrap; position: relative; } .nav-tab::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background-color: var(--color-primary); transform: scaleX(0); transition: transform var(--duration-normal) var(--ease-standard); } .nav-tab:hover { color: var(--color-text); } .nav-tab.active { color: var(--color-primary); } .nav-tab.active::after { transform: scaleX(1); } /* Tab content */ .tab-content { display: none; animation: fadeIn var(--duration-normal) var(--ease-standard); } .tab-content.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Dashboard styles */ .hero-section { text-align: center; max-width: 900px; margin: 0 auto; } .hero-description { color: var(--color-text-secondary); font-size: var(--font-size-lg); line-height: 1.6; margin: var(--space-16) auto var(--space-32); max-width: 800px; } .key-benefits { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-20); margin: var(--space-32) 0; } .benefit-card { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-20); box-shadow: var(--shadow-sm); border: 1px solid var(--color-card-border); transition: transform var(--duration-normal) var(--ease-standard), box-shadow var(--duration-normal) var(--ease-standard); } .benefit-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); } .benefit-icon { font-size: 2.5rem; margin-bottom: var(--space-12); } .benefit-card h3 { margin-bottom: var(--space-8); font-weight: var(--font-weight-semibold); } .benefit-card p { color: var(--color-text-secondary); font-size: var(--font-size-md); margin-bottom: 0; } .system-stats { display: flex; justify-content: space-around; flex-wrap: wrap; margin: var(--space-32) 0; gap: var(--space-16); } .stat { display: flex; flex-direction: column; align-items: center; padding: var(--space-16); } .stat-value { font-size: var(--font-size-4xl); font-weight: var(--font-weight-bold); color: var(--color-primary); margin-bottom: var(--space-4); } .stat-label { color: var(--color-text-secondary); font-size: var(--font-size-sm); } /* Hardware tab styles */ .hardware-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-24); } @media (max-width: 768px) { .hardware-grid { grid-template-columns: 1fr; } } .antenna-array { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-20); border: 1px solid var(--color-card-border); box-shadow: var(--shadow-sm); margin-top: var(--space-16); } .antenna-grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: var(--space-16); margin-bottom: var(--space-16); } .antenna { width: 60px; height: 60px; border-radius: 50%; position: relative; display: flex; align-items: center; justify-content: center; transition: all var(--duration-normal) var(--ease-standard); cursor: pointer; } .antenna::before { content: attr(data-type); font-size: var(--font-size-sm); color: var(--color-surface); font-weight: var(--font-weight-medium); } .antenna.tx { background-color: rgba(33, 128, 141, 0.8); } .antenna.rx { background-color: rgba(168, 75, 47, 0.8); } .antenna.active::after { content: ''; position: absolute; width: 70px; height: 70px; border-radius: 50%; border: 2px solid currentColor; animation: pulse 2s infinite; } .antenna.tx.active::after { color: rgba(33, 128, 141, 0.4); } .antenna.rx.active::after { color: rgba(168, 75, 47, 0.4); } @keyframes pulse { 0% { transform: scale(0.95); opacity: 1; } 70% { transform: scale(1.1); opacity: 0.3; } 100% { transform: scale(0.95); opacity: 1; } } .antenna-legend { display: flex; justify-content: center; gap: var(--space-20); } .legend-item { display: flex; align-items: center; gap: var(--space-8); } .legend-color { width: 16px; height: 16px; border-radius: 50%; } .legend-color.tx { background-color: rgba(33, 128, 141, 0.8); } .legend-color.rx { background-color: rgba(168, 75, 47, 0.8); } .config-section { margin-top: var(--space-16); } .config-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-16); margin-bottom: var(--space-24); } .config-item { background-color: var(--color-surface); border-radius: var(--radius-md); padding: var(--space-16); border: 1px solid var(--color-card-border); } .config-item label { display: block; color: var(--color-text-secondary); font-size: var(--font-size-sm); margin-bottom: var(--space-4); } .config-value { font-size: var(--font-size-lg); font-weight: var(--font-weight-medium); } .csi-data { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-16); border: 1px solid var(--color-card-border); } .csi-display { margin-top: var(--space-12); } .csi-row { display: flex; align-items: center; gap: var(--space-12); margin-bottom: var(--space-8); } .csi-bar { flex: 1; height: 12px; background-color: var(--color-secondary); border-radius: var(--radius-full); overflow: hidden; } .csi-fill { height: 100%; transition: width 0.5s var(--ease-standard); } .csi-fill.amplitude { background: linear-gradient(90deg, #1FB8CD, #32B8C6); } .csi-fill.phase { background: linear-gradient(90deg, #FF9A3D, #E65125); } .csi-value { width: 40px; text-align: right; font-family: var(--font-family-mono); font-size: var(--font-size-sm); } /* Demo tab styles */ .demo-controls { display: flex; align-items: center; gap: var(--space-16); margin-bottom: var(--space-24); } .demo-status { display: flex; align-items: center; gap: 8px; margin-left: auto; } /* Status indicator dot */ .status-indicator { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: #555; } .status-indicator.active { background: #00cc88; box-shadow: 0 0 6px #00cc88; } .status-indicator.sim { background: #ffa500; box-shadow: 0 0 6px #ffa500; animation: pulse 1.5s infinite; } .status-indicator.connecting { background: #f0ad4e; animation: pulse 1s infinite; } .status-indicator.error { background: #ff3c3c; } /* Live Demo data-source banner */ .demo-source-banner { display: block; width: 100%; padding: 10px 16px; margin-bottom: 12px; border-radius: 6px; text-align: center; font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; box-sizing: border-box; } .demo-source-live { background: rgba(0, 204, 136, 0.15); border: 1px solid #00cc88; color: #00cc88; } .demo-source-sim { background: rgba(255, 165, 0, 0.15); border: 1px solid #ffa500; color: #ffa500; } .demo-source-reconnecting { background: rgba(255, 180, 0, 0.12); border: 1px solid #f0ad4e; color: #f0ad4e; animation: pulse 1.5s infinite; } .demo-source-offline { background: rgba(255, 60, 60, 0.12); border: 1px solid #ff3c3c; color: #ff3c3c; } .demo-source-unknown { background: rgba(128, 128, 128, 0.12); border: 1px solid #888; color: #888; } .demo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-24); } @media (max-width: 768px) { .demo-grid { grid-template-columns: 1fr; } } .signal-panel, .pose-panel { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-16); border: 1px solid var(--color-card-border); } .signal-display, .pose-display { background-color: rgba(0, 0, 0, 0.2); border-radius: var(--radius-md); margin: var(--space-12) 0; display: flex; justify-content: center; align-items: center; overflow: hidden; } canvas { max-width: 100%; } .signal-metrics, .detection-info { display: flex; flex-wrap: wrap; gap: var(--space-16); } .metric, .info-item { flex: 1; min-width: 120px; display: flex; justify-content: space-between; font-size: var(--font-size-sm); color: var(--color-text-secondary); } .metric span:last-child, .info-item span:last-child { font-weight: var(--font-weight-medium); color: var(--color-text); font-family: var(--font-family-mono); } /* Architecture tab styles */ .architecture-flow { display: flex; flex-direction: column; align-items: center; gap: var(--space-24); } .architecture-image { max-width: 100%; border-radius: var(--radius-lg); border: 1px solid var(--color-card-border); box-shadow: var(--shadow-md); } .flow-steps { display: flex; justify-content: space-between; width: 100%; flex-wrap: wrap; gap: var(--space-16); } .step-card { flex: 1; min-width: 180px; background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-16); border: 1px solid var(--color-card-border); position: relative; transition: transform var(--duration-normal) var(--ease-standard), box-shadow var(--duration-normal) var(--ease-standard); cursor: pointer; } .step-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); } .step-number { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background-color: var(--color-primary); color: var(--color-surface); border-radius: 50%; font-weight: var(--font-weight-bold); position: absolute; top: -16px; left: var(--space-16); } .step-card h3 { margin-top: var(--space-16); margin-bottom: var(--space-8); } .step-card p { color: var(--color-text-secondary); font-size: var(--font-size-sm); margin-bottom: 0; } /* Performance tab styles */ .performance-chart { text-align: center; margin-bottom: var(--space-24); } .chart-image { max-width: 100%; border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); } .performance-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--space-24); } .performance-card { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-16); border: 1px solid var(--color-card-border); } .metric-list { margin-top: var(--space-16); } .metric-item { display: flex; justify-content: space-between; margin-bottom: var(--space-8); padding: var(--space-8); border-radius: var(--radius-md); background-color: rgba(0, 0, 0, 0.05); } .metric-value { font-weight: var(--font-weight-medium); font-family: var(--font-family-mono); } .metric-value.success { color: var(--color-success); } .limitations-section { grid-column: 1 / -1; margin-top: var(--space-16); } .pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-24); margin-top: var(--space-16); } @media (max-width: 768px) { .pros-cons { grid-template-columns: 1fr; } } .pros h4, .cons h4 { margin-bottom: var(--space-12); padding-bottom: var(--space-8); border-bottom: 1px solid var(--color-border); } .pros ul, .cons ul { padding-left: var(--space-20); } .pros li, .cons li { margin-bottom: var(--space-8); color: var(--color-text-secondary); } /* Applications tab styles */ .applications-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--space-24); margin-bottom: var(--space-32); } .app-card { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-20); border: 1px solid var(--color-card-border); transition: transform var(--duration-normal) var(--ease-standard), box-shadow var(--duration-normal) var(--ease-standard); height: 100%; } .app-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); } .app-icon { font-size: 2.5rem; margin-bottom: var(--space-12); } .app-card h3 { margin-bottom: var(--space-12); } .app-card p { color: var(--color-text-secondary); margin-bottom: var(--space-16); } .app-features { display: flex; flex-wrap: wrap; gap: var(--space-8); } .feature-tag { background-color: var(--color-secondary); color: var(--color-text); padding: var(--space-4) var(--space-8); border-radius: var(--radius-full); font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); } .implementation-note { background-color: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-20); border: 1px solid var(--color-card-border); margin-top: var(--space-32); } .implementation-note h3 { margin-bottom: var(--space-12); } .implementation-note p { color: var(--color-text-secondary); margin-bottom: 0; } /* Additional styles for modular UI components */ /* Header info bar */ .header-info { display: flex; gap: var(--space-16); justify-content: center; margin-top: var(--space-16); font-size: var(--font-size-sm); } .api-version, .api-environment, .overall-health { padding: var(--space-4) var(--space-12); border-radius: var(--radius-full); background: var(--color-secondary); font-weight: var(--font-weight-medium); } .api-environment.env-development { background: rgba(var(--color-info-rgb), 0.1); color: var(--color-info); } .api-environment.env-production { background: rgba(var(--color-success-rgb), 0.1); color: var(--color-success); } .overall-health.status-healthy { background: rgba(var(--color-success-rgb), 0.1); color: var(--color-success); } .overall-health.status-degraded { background: rgba(var(--color-warning-rgb), 0.1); color: var(--color-warning); } .overall-health.status-unhealthy { background: rgba(var(--color-error-rgb), 0.1); color: var(--color-error); } /* Dashboard panels */ .live-status-panel, .system-metrics-panel, .features-panel, .live-stats-panel { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: var(--space-24); margin-bottom: var(--space-24); } .status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-16); margin-top: var(--space-16); } .component-status { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-12); border: 1px solid var(--color-border); border-radius: var(--radius-base); } .component-status.status-healthy { border-color: var(--color-success); background: rgba(var(--color-success-rgb), 0.05); } .component-status.status-degraded { border-color: var(--color-warning); background: rgba(var(--color-warning-rgb), 0.05); } .component-status.status-warning { border-color: #ffa500; background: rgba(255, 165, 0, 0.08); } .component-status.status-warning .status-text { color: #ffa500; } .component-status.status-unhealthy { border-color: var(--color-error); background: rgba(var(--color-error-rgb), 0.05); } .component-name { font-weight: var(--font-weight-semibold); } .status-text { font-size: var(--font-size-sm); text-transform: uppercase; } .status-message { font-size: var(--font-size-xs); color: var(--color-text-secondary); } /* Metrics display */ .metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--space-16); margin-top: var(--space-16); } .metric-item { display: flex; flex-direction: column; gap: var(--space-8); } .metric-label { font-size: var(--font-size-sm); color: var(--color-text-secondary); } .progress-bar { height: 8px; background: var(--color-secondary); border-radius: var(--radius-full); overflow: hidden; } .progress-fill { height: 100%; transition: width 0.3s ease; } .progress-fill.normal { background: var(--color-success); } .progress-fill.warning { background: var(--color-warning); } .progress-fill.critical { background: var(--color-error); } /* Features status */ .features-status { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-12); margin-top: var(--space-16); } .feature-item { display: flex; align-items: center; justify-content: space-between; padding: var(--space-8) var(--space-12); border: 1px solid var(--color-border); border-radius: var(--radius-base); font-size: var(--font-size-sm); } .feature-item.enabled { background: rgba(var(--color-success-rgb), 0.05); border-color: var(--color-success); } .feature-item.disabled { opacity: 0.6; } .feature-status { font-weight: var(--font-weight-semibold); } /* Live statistics */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-16); margin-top: var(--space-16); } .stat-item { text-align: center; } .stat-item .stat-label { display: block; font-size: var(--font-size-sm); color: var(--color-text-secondary); margin-bottom: var(--space-4); } .person-count, .avg-confidence, .detection-count { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); color: var(--color-primary); } /* Zones display */ .zones-panel { margin-top: var(--space-24); } .zones-summary { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--space-8); margin-top: var(--space-12); } .zone-item { display: flex; align-items: center; justify-content: space-between; padding: var(--space-8) var(--space-12); background: var(--color-secondary); border-radius: var(--radius-base); font-size: var(--font-size-sm); } .zone-name { font-weight: var(--font-weight-medium); } .zone-count { background: var(--color-primary); color: white; padding: var(--space-2) var(--space-8); border-radius: var(--radius-full); font-weight: var(--font-weight-semibold); } /* Error container */ .error-container { background: rgba(var(--color-error-rgb), 0.1); border: 1px solid var(--color-error); color: var(--color-error); padding: var(--space-12) var(--space-16); border-radius: var(--radius-base); margin-bottom: var(--space-16); } /* Global error toast */ .error-toast { position: fixed; bottom: var(--space-24); right: var(--space-24); background: var(--color-error); color: white; padding: var(--space-12) var(--space-20); border-radius: var(--radius-base); box-shadow: var(--shadow-lg); transform: translateY(100%); opacity: 0; transition: all 0.3s ease; z-index: 1000; } .error-toast.show { transform: translateY(0); opacity: 1; } /* Backend status toast */ .backend-status-toast { position: fixed; top: var(--space-24); right: var(--space-24); padding: var(--space-12) var(--space-20); border-radius: var(--radius-base); box-shadow: var(--shadow-lg); transform: translateY(-100%); opacity: 0; transition: all 0.3s ease; z-index: 1001; font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); } .backend-status-toast.show { transform: translateY(0); opacity: 1; } .backend-status-toast.success { background: var(--color-success); color: white; } .backend-status-toast.warning { background: var(--color-warning); color: white; } .backend-status-toast.error { background: var(--color-error); color: white; } /* Tab badge */ .tab-badge { display: inline-block; margin-left: var(--space-8); padding: var(--space-2) var(--space-6); background: var(--color-error); color: white; border-radius: var(--radius-full); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); } /* Help text */ .help-text { font-size: var(--font-size-sm); color: var(--color-text-secondary); font-style: italic; margin-bottom: var(--space-16); } /* Array status */ .array-status { display: flex; gap: var(--space-16); margin-top: var(--space-16); padding: var(--space-12); background: var(--color-secondary); border-radius: var(--radius-base); } .array-info { display: flex; align-items: center; gap: var(--space-8); } .info-label { font-size: var(--font-size-sm); color: var(--color-text-secondary); } .info-value { font-weight: var(--font-weight-semibold); color: var(--color-primary); } /* ===== Sensing Tab Styles ===== */ .sensing-layout { display: grid; grid-template-columns: 1fr 320px; gap: var(--space-16); min-height: 550px; } @media (max-width: 900px) { .sensing-layout { grid-template-columns: 1fr; } } .sensing-viewport { background: #0a0a12; border-radius: var(--radius-lg); border: 1px solid var(--color-card-border); overflow: hidden; min-height: 500px; position: relative; } .sensing-viewport canvas { display: block; width: 100% !important; height: 100% !important; } .sensing-loading { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--color-text-secondary); font-size: var(--font-size-lg); } /* Side panel */ .sensing-panel { display: flex; flex-direction: column; gap: var(--space-12); overflow-y: auto; max-height: 600px; } .sensing-card { background: var(--color-surface); border: 1px solid var(--color-card-border); border-radius: var(--radius-md); padding: var(--space-12); } .sensing-card-title { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); margin-bottom: var(--space-8); } /* Connection status */ .sensing-connection { display: flex; align-items: center; gap: var(--space-8); font-size: var(--font-size-sm); } .sensing-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-info); flex-shrink: 0; } .sensing-dot.connected { background: #00cc88; box-shadow: 0 0 6px #00cc88; } .sensing-dot.simulated { background: var(--color-warning); box-shadow: 0 0 6px var(--color-warning); } .sensing-dot.connecting { background: var(--color-info); animation: pulse 1.5s infinite; } .sensing-dot.disconnected { background: var(--color-error); } .sensing-dot.reconnecting { background: var(--color-warning); animation: pulse 1.5s infinite; } .sensing-source { margin-left: auto; font-size: var(--font-size-xs); color: var(--color-text-secondary); font-family: var(--font-family-mono); } .sensing-about-text { margin: 0; font-size: 12px; color: #aaa; line-height: 1.5; } .sensing-about-text strong { color: #ccc; } /* Data-source status banner (live / reconnecting / simulated) */ .sensing-source-banner { display: block; width: 100%; padding: var(--space-8) var(--space-12); margin-bottom: var(--space-12); border-radius: var(--radius-md); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); font-family: var(--font-family-mono); text-align: center; letter-spacing: 0.06em; text-transform: uppercase; box-sizing: border-box; } .sensing-source-live { background: rgba(0, 204, 136, 0.15); border: 1px solid #00cc88; color: #00cc88; } .sensing-source-reconnecting { background: rgba(255, 180, 0, 0.12); border: 1px solid var(--color-warning); color: var(--color-warning); animation: pulse 1.5s infinite; } .sensing-source-server-sim { background: rgba(255, 165, 0, 0.15); border: 1px solid #ffa500; color: #ffa500; } .sensing-source-simulated { background: rgba(255, 60, 60, 0.12); border: 1px solid var(--color-error); color: var(--color-error); } /* Health indicator for server-simulated data */ .health-sim { color: #ffa500; font-weight: 600; } /* Big RSSI value */ .sensing-big-value { font-size: var(--font-size-3xl); font-weight: var(--font-weight-bold); color: var(--color-primary); font-family: var(--font-family-mono); margin-bottom: var(--space-4); } #sensingSparkline { width: 100%; height: 40px; display: block; } /* Meter bars */ .sensing-meters { display: flex; flex-direction: column; gap: var(--space-8); } .sensing-meter { display: grid; grid-template-columns: 90px 1fr 50px; align-items: center; gap: var(--space-8); font-size: var(--font-size-sm); } .sensing-meter label { color: var(--color-text-secondary); white-space: nowrap; } .sensing-bar { height: 6px; background: var(--color-secondary); border-radius: var(--radius-full); overflow: hidden; } .sensing-bar-fill { height: 100%; border-radius: var(--radius-full); transition: width 0.3s ease; background: var(--color-primary); width: 0%; } .sensing-bar-fill.motion { background: linear-gradient(90deg, #ff6633, #ff3333); } .sensing-bar-fill.breath { background: linear-gradient(90deg, #33ccff, #3366ff); } .sensing-bar-fill.spectral { background: linear-gradient(90deg, #aa66ff, #ff66aa); } .sensing-bar-fill.confidence { background: linear-gradient(90deg, #33cc88, #00ff88); } .sensing-meter-val { font-family: var(--font-family-mono); font-size: var(--font-size-xs); text-align: right; color: var(--color-text-secondary); } /* Classification */ .sensing-classification { display: flex; flex-direction: column; gap: var(--space-8); } .sensing-class-label { font-size: var(--font-size-xl); font-weight: var(--font-weight-bold); text-align: center; padding: var(--space-8); border-radius: var(--radius-base); text-transform: uppercase; letter-spacing: 0.05em; } .sensing-class-label.absent { background: rgba(var(--color-info-rgb), 0.15); color: var(--color-info); } .sensing-class-label.present_still { background: rgba(var(--color-success-rgb), 0.15); color: var(--color-success); } .sensing-class-label.active { background: rgba(var(--color-error-rgb), 0.15); color: var(--color-error); } .sensing-confidence { display: grid; grid-template-columns: 70px 1fr 40px; align-items: center; gap: var(--space-8); font-size: var(--font-size-sm); } .sensing-confidence label { color: var(--color-text-secondary); } /* Details */ .sensing-details { display: flex; flex-direction: column; gap: var(--space-4); } .sensing-detail-row { display: flex; justify-content: space-between; font-size: var(--font-size-sm); padding: var(--space-4) 0; border-bottom: 1px solid var(--color-card-border-inner); } .sensing-detail-row:last-child { border-bottom: none; } .sensing-detail-row span:first-child { color: var(--color-text-secondary); } .sensing-detail-row span:last-child { font-family: var(--font-family-mono); font-weight: var(--font-weight-medium); } /* ===== Training Tab Styles ===== */ #training .tab-header { margin-bottom: 20px; } #training .tab-header h2 { color: var(--color-text); margin: 0 0 8px 0; } #training .tab-header p { color: var(--color-text-secondary); margin: 0; font-size: var(--font-size-sm); } /* Training Panel */ .training-panel { background: var(--color-surface); border: 1px solid var(--color-card-border); border-radius: var(--radius-lg); padding: var(--space-16); } .training-panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-16); padding-bottom: var(--space-12); border-bottom: 1px solid var(--color-card-border-inner); } .training-panel-header h3 { color: var(--color-text); margin: 0; font-size: var(--font-size-base); } .training-status-badge { padding: var(--space-2) 10px; border-radius: var(--radius-full); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; } .training-status-idle { background: var(--color-secondary); color: var(--color-text-secondary); border: 1px solid var(--color-border); } .training-status-active { background: rgba(var(--color-error-rgb), 0.15); color: var(--color-error); border: 1px solid rgba(var(--color-error-rgb), var(--status-border-opacity)); animation: pulse-training 2s infinite; } .training-status-completed { background: rgba(var(--color-success-rgb), 0.15); color: var(--color-success); border: 1px solid rgba(var(--color-success-rgb), var(--status-border-opacity)); } @keyframes pulse-training { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Recording list */ .recording-item { display: flex; justify-content: space-between; align-items: center; padding: 10px var(--space-12); background: var(--color-secondary); border: 1px solid var(--color-card-border-inner); border-radius: var(--radius-base); margin-bottom: var(--space-8); } .recording-item-info { flex: 1; } .recording-item-name { color: var(--color-text); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); } .recording-item-meta { color: var(--color-text-secondary); font-size: var(--font-size-xs); margin-top: var(--space-2); } /* Model cards */ .model-card { padding: var(--space-12); background: var(--color-secondary); border: 1px solid var(--color-card-border-inner); border-radius: var(--radius-base); margin-bottom: var(--space-8); transition: border-color 0.2s; } .model-card:hover { border-color: var(--color-border); } .model-card-active { border-left: 3px solid var(--color-success); } .model-card-name { color: var(--color-text); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); } .model-card-meta { color: var(--color-text-secondary); font-size: var(--font-size-xs); margin-top: var(--space-4); } .model-card-stats { display: flex; gap: var(--space-12); margin-top: var(--space-8); } .model-card-stat { font-size: var(--font-size-xs); } .model-card-stat-label { color: var(--color-text-secondary); } .model-card-stat-value { color: var(--color-text); font-weight: var(--font-weight-semibold); } /* Training chart */ .training-chart-container { background: var(--color-secondary); border: 1px solid var(--color-card-border-inner); border-radius: var(--radius-base); padding: var(--space-12); margin: var(--space-12) 0; } .training-chart-label { color: var(--color-text-secondary); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--space-8); } /* Training config form */ .training-config-form { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-12); } .training-form-group { display: flex; flex-direction: column; gap: var(--space-4); } .training-form-label { color: var(--color-text-secondary); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.05em; } .training-form-input { background: var(--color-background); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); padding: var(--space-8) 10px; font-size: var(--font-size-sm); font-family: inherit; } .training-form-input:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--focus-ring); } .training-form-select { background: var(--color-background); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); padding: var(--space-8) 10px; font-size: var(--font-size-sm); } /* Training buttons */ .training-btn { padding: var(--space-8) var(--space-16); border-radius: var(--radius-base); border: 1px solid transparent; font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); cursor: pointer; transition: all 0.2s; } .training-btn-primary { background: rgba(var(--color-success-rgb), 0.15); color: var(--color-success); border-color: rgba(var(--color-success-rgb), var(--status-border-opacity)); } .training-btn-primary:hover { background: rgba(var(--color-success-rgb), 0.25); } .training-btn-danger { background: rgba(var(--color-error-rgb), 0.15); color: var(--color-error); border-color: rgba(var(--color-error-rgb), var(--status-border-opacity)); } .training-btn-danger:hover { background: rgba(var(--color-error-rgb), 0.25); } .training-btn-secondary { background: rgba(var(--color-primary-rgb), 0.15); color: var(--color-primary); border-color: rgba(var(--color-primary-rgb), var(--status-border-opacity)); } .training-btn-secondary:hover { background: rgba(var(--color-primary-rgb), 0.25); } .training-btn-muted { background: var(--color-secondary); color: var(--color-text-secondary); border-color: var(--color-border); } .training-btn-muted:hover { background: var(--color-secondary-hover); } /* Progress bar */ .training-progress-bar { width: 100%; height: 6px; background: var(--color-secondary); border-radius: var(--radius-full); overflow: hidden; margin: var(--space-8) 0; } .training-progress-fill { height: 100%; background: linear-gradient(90deg, var(--color-primary), var(--color-success)); border-radius: var(--radius-full); transition: width 0.3s ease; } /* Metrics grid */ .training-metrics-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-8); margin: var(--space-12) 0; } .training-metric { text-align: center; padding: var(--space-8); background: var(--color-secondary); border-radius: var(--radius-base); } .training-metric-value { color: var(--color-text); font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); font-family: var(--font-family-mono); } .training-metric-label { color: var(--color-text-secondary); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.05em; margin-top: var(--space-2); } /* Collapsible section */ .training-collapsible-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; cursor: pointer; color: var(--color-text); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); border-bottom: 1px solid var(--color-card-border-inner); } .training-collapsible-header:hover { color: var(--color-primary); } .training-collapsible-content { padding: var(--space-12) 0; } /* Pose trail toggle in toolbar */ .pose-trail-btn { padding: var(--space-6) 14px; border-radius: var(--radius-base); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); cursor: pointer; transition: all 0.2s; background: rgba(var(--color-primary-rgb), 0.1); color: var(--color-primary); border: 1px solid rgba(var(--color-primary-rgb), 0.3); } .pose-trail-btn.active { background: rgba(var(--color-primary-rgb), 0.25); border-color: rgba(var(--color-primary-rgb), 0.6); } .pose-trail-btn:hover { background: rgba(var(--color-primary-rgb), 0.2); } /* ========================================================================== ENHANCEMENTS: Keyboard Shortcuts, Performance Monitor, Toast, Theme Toggle ========================================================================== */ /* --- Keyboard Shortcuts Overlay --- */ .shortcuts-overlay { position: fixed; inset: 0; z-index: 10000; background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity var(--duration-normal) var(--ease-standard); } .shortcuts-overlay.visible { opacity: 1; pointer-events: auto; } .shortcuts-panel { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); width: 480px; max-width: 90vw; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; animation: shortcuts-enter var(--duration-normal) var(--ease-standard); } @keyframes shortcuts-enter { from { transform: scale(0.95) translateY(10px); opacity: 0; } to { transform: scale(1) translateY(0); opacity: 1; } } .shortcuts-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-16) var(--space-20); border-bottom: 1px solid var(--color-border); } .shortcuts-header h2 { margin: 0; font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); color: var(--color-text); } .shortcuts-close { background: none; border: none; font-size: 22px; color: var(--color-text-secondary); cursor: pointer; padding: var(--space-4); line-height: 1; border-radius: var(--radius-sm); transition: color var(--duration-fast); } .shortcuts-close:hover { color: var(--color-text); } .shortcuts-close:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } .shortcuts-body { padding: var(--space-16) var(--space-20); overflow-y: auto; } .shortcuts-group { margin-bottom: var(--space-16); } .shortcuts-group:last-child { margin-bottom: 0; } .shortcuts-group h3 { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); margin: 0 0 var(--space-8); } .shortcut-row { display: flex; align-items: center; gap: var(--space-12); padding: var(--space-6) 0; } .shortcut-row kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 26px; padding: 0 var(--space-8); background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-sm); font-family: var(--font-family-mono); font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); color: var(--color-text); box-shadow: 0 1px 0 var(--color-border); } .shortcut-row span { font-size: var(--font-size-sm); color: var(--color-text-secondary); } /* --- Performance Monitor --- */ .perf-monitor { position: fixed; bottom: var(--space-16); right: var(--space-16); z-index: 9999; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-base); box-shadow: var(--shadow-md); font-family: var(--font-family-mono); font-size: var(--font-size-xs); min-width: 200px; opacity: 0; pointer-events: none; transform: translateY(10px); transition: all var(--duration-normal) var(--ease-standard); } .perf-monitor.visible { opacity: 1; pointer-events: auto; transform: translateY(0); } .perf-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-6) var(--space-10); border-bottom: 1px solid var(--color-border); cursor: grab; user-select: none; } .perf-header span { font-weight: var(--font-weight-bold); color: var(--color-primary); letter-spacing: 0.1em; font-size: 10px; } .perf-close { background: none; border: none; color: var(--color-text-secondary); cursor: pointer; font-size: 16px; padding: 0 var(--space-2); line-height: 1; } .perf-close:hover { color: var(--color-text); } .perf-metrics { padding: var(--space-6) var(--space-10); } .perf-row { display: flex; align-items: center; gap: var(--space-8); padding: var(--space-2) 0; } .perf-label { color: var(--color-text-secondary); width: 28px; font-size: 10px; letter-spacing: 0.05em; } .perf-value { color: var(--color-text); min-width: 52px; text-align: right; } .perf-value.perf-warning { color: var(--color-warning); } .perf-value.perf-ok { color: var(--color-success); } .perf-spark { border-radius: 2px; background: rgba(0, 0, 0, 0.05); } [data-color-scheme="dark"] .perf-spark { background: rgba(255, 255, 255, 0.05); } /* --- Toast Notifications --- */ .toast-container { position: fixed; top: var(--space-16); right: var(--space-16); z-index: 10001; display: flex; flex-direction: column; gap: var(--space-8); max-width: 400px; pointer-events: none; } .toast { display: flex; align-items: flex-start; gap: var(--space-10); padding: var(--space-12) var(--space-16); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-base); box-shadow: var(--shadow-md); font-size: var(--font-size-sm); color: var(--color-text); pointer-events: auto; position: relative; overflow: hidden; opacity: 0; transform: translateX(20px); transition: all var(--duration-normal) var(--ease-standard); } .toast.toast-enter { opacity: 1; transform: translateX(0); } .toast.toast-exit { animation: toast-out var(--duration-normal) var(--ease-standard) forwards; } @keyframes toast-out { to { opacity: 0; transform: translateX(20px); height: 0; padding: 0; margin: 0; overflow: hidden; } } .toast-success { border-left: 3px solid var(--color-success); } .toast-error { border-left: 3px solid var(--color-error); } .toast-warning { border-left: 3px solid var(--color-warning); } .toast-info { border-left: 3px solid var(--color-primary); } .toast-icon { flex-shrink: 0; display: flex; align-items: center; margin-top: 1px; } .toast-success .toast-icon { color: var(--color-success); } .toast-error .toast-icon { color: var(--color-error); } .toast-warning .toast-icon { color: var(--color-warning); } .toast-info .toast-icon { color: var(--color-primary); } .toast-content { flex: 1; min-width: 0; } .toast-message { line-height: var(--line-height-normal); } .toast-action { display: inline-block; margin-top: var(--space-4); padding: 0; background: none; border: none; color: var(--color-primary); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); cursor: pointer; text-decoration: underline; } .toast-action:hover { color: var(--color-primary-hover); } .toast-dismiss { background: none; border: none; color: var(--color-text-secondary); cursor: pointer; font-size: 18px; padding: 0 var(--space-2); line-height: 1; flex-shrink: 0; } .toast-dismiss:hover { color: var(--color-text); } .toast-progress { position: absolute; bottom: 0; left: 0; right: 0; height: 2px; background: rgba(0, 0, 0, 0.05); } .toast-progress-bar { height: 100%; width: 100%; transform-origin: left; } .toast-progress-animate { animation: toast-progress-shrink linear forwards; } @keyframes toast-progress-shrink { from { transform: scaleX(1); } to { transform: scaleX(0); } } .toast-success .toast-progress-bar { background: var(--color-success); } .toast-error .toast-progress-bar { background: var(--color-error); } .toast-warning .toast-progress-bar { background: var(--color-warning); } .toast-info .toast-progress-bar { background: var(--color-primary); } /* --- Theme Toggle Button --- */ .theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); cursor: pointer; transition: all var(--duration-fast) var(--ease-standard); } .theme-toggle:hover { background: var(--color-secondary-hover); color: var(--color-primary); } .theme-toggle:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* --- Focus Visible for Accessibility --- */ .nav-tab:focus-visible, button:focus-visible, a:focus-visible, [tabindex]:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* --- Skip to Content Link --- */ .skip-to-content { position: absolute; top: -100px; left: var(--space-16); padding: var(--space-8) var(--space-16); background: var(--color-primary); color: var(--color-btn-primary-text); border-radius: var(--radius-base); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); text-decoration: none; z-index: 10002; transition: top var(--duration-fast); } .skip-to-content:focus { top: var(--space-16); } /* --- Responsive Toasts --- */ @media (max-width: 480px) { .toast-container { left: var(--space-8); right: var(--space-8); max-width: none; } .shortcuts-panel { width: 95vw; } } /* ========================================================================== ENHANCEMENTS V2: Command Palette, Activity Log, Data Export, Fullscreen, Connection Status ========================================================================== */ /* --- Command Palette --- */ .cmd-palette-overlay { position: fixed; inset: 0; z-index: 10010; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); display: flex; align-items: flex-start; justify-content: center; padding-top: 15vh; opacity: 0; pointer-events: none; transition: opacity var(--duration-normal) var(--ease-standard); } .cmd-palette-overlay.visible { opacity: 1; pointer-events: auto; } /* ========================================================================== MOBILE NAVIGATION - Hamburger menu for small screens ========================================================================== */ /* Hamburger button - hidden on desktop */ .mobile-hamburger { display: none; position: absolute; top: 50%; right: var(--space-16); transform: translateY(-50%); width: 40px; height: 40px; padding: var(--space-8); background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-base); cursor: pointer; flex-direction: column; align-items: center; justify-content: center; gap: 5px; z-index: 100; transition: all var(--duration-fast); } .mobile-hamburger:hover { background: var(--color-secondary-hover); } .mobile-hamburger:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } .hamburger-line { display: block; width: 18px; height: 2px; background: var(--color-text); border-radius: 1px; transition: all var(--duration-normal) var(--ease-standard); } .mobile-hamburger.open .hamburger-line:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); } .mobile-hamburger.open .hamburger-line:nth-child(2) { opacity: 0; } .mobile-hamburger.open .hamburger-line:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); } /* Backdrop */ .mobile-nav-backdrop { position: fixed; inset: 0; z-index: 9990; background: rgba(0, 0, 0, 0.5); opacity: 0; pointer-events: none; transition: opacity var(--duration-normal); } .mobile-nav-backdrop.open { opacity: 1; pointer-events: auto; } .cmd-palette { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg), 0 25px 50px -12px rgba(0, 0, 0, 0.15); width: 560px; max-width: 90vw; max-height: 60vh; display: flex; flex-direction: column; overflow: hidden; animation: cmd-palette-enter var(--duration-normal) var(--ease-standard); } @keyframes cmd-palette-enter { from { transform: scale(0.97) translateY(-8px); opacity: 0; } to { transform: scale(1) translateY(0); opacity: 1; } } .cmd-palette-input-wrap { display: flex; align-items: center; gap: var(--space-10); padding: var(--space-12) var(--space-16); border-bottom: 1px solid var(--color-border); } .cmd-palette-search-icon { flex-shrink: 0; color: var(--color-text-secondary); } .cmd-palette-input { flex: 1; border: none; background: none; outline: none; font-size: var(--font-size-base); color: var(--color-text); font-family: var(--font-family-base); } .cmd-palette-input::placeholder { color: var(--color-text-secondary); } .cmd-palette-hint { font-family: var(--font-family-mono); font-size: var(--font-size-xs); padding: 2px 6px; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: 4px; color: var(--color-text-secondary); } .cmd-palette-results { overflow-y: auto; flex: 1; padding: var(--space-4) 0; } .cmd-palette-category { padding: var(--space-8) var(--space-16) var(--space-4); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); } .cmd-palette-item { display: flex; align-items: center; gap: var(--space-10); padding: var(--space-8) var(--space-16); cursor: pointer; transition: background var(--duration-fast); } .cmd-palette-item:hover, .cmd-palette-item-selected { background: var(--color-secondary); } .cmd-palette-item-icon { flex-shrink: 0; color: var(--color-text-secondary); display: flex; align-items: center; } .cmd-palette-item-label { font-size: var(--font-size-sm); color: var(--color-text); } .cmd-palette-empty { padding: var(--space-24) var(--space-16); text-align: center; color: var(--color-text-secondary); font-size: var(--font-size-sm); } .cmd-palette-footer { display: flex; gap: var(--space-16); padding: var(--space-8) var(--space-16); border-top: 1px solid var(--color-border); font-size: var(--font-size-xs); color: var(--color-text-secondary); } .cmd-palette-footer kbd { display: inline-block; padding: 1px 5px; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: 3px; font-family: var(--font-family-mono); font-size: 10px; margin-right: 2px; } /* --- Connection Status Widget --- */ .conn-status { display: inline-flex; align-items: center; gap: var(--space-6); padding: var(--space-4) var(--space-10); border-radius: var(--radius-full); font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); border: 1px solid var(--color-border); background: var(--color-secondary); transition: all var(--duration-normal); } .conn-status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-text-secondary); transition: background var(--duration-normal); } .conn-status-connected .conn-status-dot { background: var(--color-success); box-shadow: 0 0 6px rgba(var(--color-success-rgb), 0.5); } .conn-status-reconnecting .conn-status-dot { background: var(--color-warning); animation: pulse-dot 1.5s ease-in-out infinite; } .conn-status-error .conn-status-dot { background: var(--color-error); } .conn-status-disconnected .conn-status-dot { background: var(--color-text-secondary); } @keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } .conn-status-label { color: var(--color-text); } .conn-status-reconnect { display: flex; align-items: center; background: none; border: none; color: var(--color-primary); cursor: pointer; padding: 2px; border-radius: 3px; transition: color var(--duration-fast); } .conn-status-reconnect:hover { color: var(--color-primary-hover); } /* --- Activity Log --- */ .activity-log { position: fixed; bottom: 0; left: 0; right: 0; z-index: 9998; height: 280px; background: var(--color-surface); border-top: 1px solid var(--color-border); box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08); display: flex; flex-direction: column; transform: translateY(100%); transition: transform var(--duration-normal) var(--ease-standard); cursor: n-resize; } .activity-log.visible { transform: translateY(0); } .activity-log-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-6) var(--space-12); border-bottom: 1px solid var(--color-border); background: var(--color-background); flex-shrink: 0; cursor: default; } .activity-log-title { font-size: var(--font-size-xs); font-weight: var(--font-weight-bold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); } .activity-log-controls { display: flex; align-items: center; gap: var(--space-4); } .activity-log-filter { width: 22px; height: 22px; border: 1px solid var(--color-border); border-radius: 4px; background: none; color: var(--color-text-secondary); font-size: 10px; font-weight: var(--font-weight-bold); font-family: var(--font-family-mono); cursor: pointer; transition: all var(--duration-fast); } .activity-log-filter.active { background: var(--color-primary); color: var(--color-btn-primary-text); border-color: var(--color-primary); } .activity-log-clear, .activity-log-close { background: none; border: 1px solid var(--color-border); border-radius: 4px; color: var(--color-text-secondary); font-size: var(--font-size-xs); padding: var(--space-2) var(--space-6); cursor: pointer; transition: all var(--duration-fast); } .activity-log-close { font-size: 16px; padding: 0 var(--space-4); border: none; line-height: 1; } .activity-log-clear:hover, .activity-log-close:hover { color: var(--color-text); } .activity-log-body { flex: 1; overflow-y: auto; font-family: var(--font-family-mono); font-size: 11px; line-height: 1.6; padding: var(--space-4) 0; } .activity-log-entry { display: flex; gap: var(--space-8); padding: 1px var(--space-12); border-left: 2px solid transparent; } .activity-log-entry:hover { background: var(--color-secondary); } .activity-log-info { border-left-color: var(--color-primary); } .activity-log-warning { border-left-color: var(--color-warning); } .activity-log-error { border-left-color: var(--color-error); } .activity-log-connection { border-left-color: var(--color-success); } .activity-log-time { color: var(--color-text-secondary); flex-shrink: 0; } .activity-log-type { width: 12px; font-weight: var(--font-weight-bold); flex-shrink: 0; } .activity-log-info .activity-log-type { color: var(--color-primary); } .activity-log-warning .activity-log-type { color: var(--color-warning); } .activity-log-error .activity-log-type { color: var(--color-error); } .activity-log-connection .activity-log-type { color: var(--color-success); } .activity-log-msg { color: var(--color-text); word-break: break-all; } /* --- Data Export Dialog --- */ .export-dialog-overlay { position: fixed; inset: 0; z-index: 10005; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; } .export-dialog { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: var(--space-24); width: 400px; max-width: 90vw; } .export-dialog h3 { margin: 0 0 var(--space-4); font-size: var(--font-size-lg); color: var(--color-text); } .export-dialog-info { font-size: var(--font-size-sm); color: var(--color-text-secondary); margin: 0 0 var(--space-16); } .export-dialog-options { display: flex; flex-direction: column; gap: var(--space-8); margin-bottom: var(--space-16); } .export-option { display: flex; align-items: center; gap: var(--space-10); padding: var(--space-10) var(--space-12); border: 1px solid var(--color-border); border-radius: var(--radius-base); cursor: pointer; transition: all var(--duration-fast); } .export-option:hover { border-color: var(--color-primary); background: var(--color-secondary); } .export-option input[type="radio"] { accent-color: var(--color-primary); } .export-option span { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); } .export-option small { font-size: var(--font-size-xs); color: var(--color-text-secondary); margin-left: auto; } .export-dialog-range { margin-bottom: var(--space-16); font-size: var(--font-size-sm); color: var(--color-text-secondary); } .export-dialog-range input { width: 70px; padding: var(--space-4) var(--space-8); border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-background); color: var(--color-text); font-size: var(--font-size-sm); font-family: var(--font-family-mono); } .export-dialog-actions { display: flex; gap: var(--space-8); justify-content: flex-end; } /* --- Fullscreen --- */ .fullscreen-exit-btn { position: fixed; top: var(--space-12); right: var(--space-12); z-index: 10020; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); cursor: pointer; box-shadow: var(--shadow-md); transition: all var(--duration-fast); opacity: 0.7; } .fullscreen-exit-btn:hover { opacity: 1; color: var(--color-primary); } .is-fullscreen .tab-content.active { padding: var(--space-16); background: var(--color-background); } /* --- Responsive adjustments --- */ @media (max-width: 640px) { .cmd-palette { width: 95vw; max-height: 70vh; } .activity-log { height: 200px; } .conn-status-label { display: none; } } /* Drawer */ .mobile-nav-drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 9991; width: 280px; max-width: 80vw; background: var(--color-surface); border-left: 1px solid var(--color-border); box-shadow: -8px 0 24px rgba(0, 0, 0, 0.12); transform: translateX(100%); transition: transform var(--duration-normal) var(--ease-standard); display: flex; flex-direction: column; overflow-y: auto; } .mobile-nav-drawer.open { transform: translateX(0); } .mobile-nav-list { padding: var(--space-16) 0; flex: 1; } .mobile-nav-item { display: block; width: 100%; padding: var(--space-12) var(--space-24); background: none; border: none; text-align: left; font-size: var(--font-size-base); font-weight: var(--font-weight-medium); color: var(--color-text-secondary); cursor: pointer; transition: all var(--duration-fast); text-decoration: none; border-left: 3px solid transparent; } .mobile-nav-item:hover { background: var(--color-secondary); color: var(--color-text); } .mobile-nav-item:focus-visible { outline: var(--focus-outline); outline-offset: -2px; } .mobile-nav-item.active { color: var(--color-primary); border-left-color: var(--color-primary); background: rgba(var(--color-success-rgb), 0.05); font-weight: var(--font-weight-semibold); } .mobile-nav-hint { padding: var(--space-16) var(--space-24); font-size: var(--font-size-xs); color: var(--color-text-secondary); border-top: 1px solid var(--color-border); } /* On mobile: show hamburger, hide desktop tabs */ @media (max-width: 768px) { .mobile-hamburger { display: flex; } .mobile-nav-active .nav-tabs { display: none; } .header { padding-right: 60px; } } /* ========================================================================== ONBOARDING TOUR ========================================================================== */ .onboarding-overlay { position: fixed; inset: 0; z-index: 10100; } .onboarding-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.6); } .onboarding-highlight { position: relative; z-index: 10101; box-shadow: 0 0 0 4px var(--color-primary), 0 0 0 9999px rgba(0, 0, 0, 0.55); border-radius: var(--radius-base); transition: box-shadow var(--duration-normal); } .onboarding-tooltip { position: fixed; z-index: 10102; width: 360px; max-width: 90vw; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: var(--space-20); animation: onboarding-pop var(--duration-normal) var(--ease-standard); } .onboarding-tooltip.center { top: 50%; left: 50%; transform: translate(-50%, -50%); } @keyframes onboarding-pop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } .onboarding-tooltip.center { animation-name: onboarding-pop-center; } @keyframes onboarding-pop-center { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } } .onboarding-progress { display: flex; gap: var(--space-6); margin-bottom: var(--space-12); } .onboarding-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-secondary); border: 1px solid var(--color-border); transition: all var(--duration-fast); } .onboarding-dot.active { background: var(--color-primary); border-color: var(--color-primary); transform: scale(1.2); } .onboarding-dot.done { background: var(--color-primary); border-color: var(--color-primary); opacity: 0.5; } .onboarding-title { margin: 0 0 var(--space-8); font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); color: var(--color-text); } .onboarding-text { margin: 0 0 var(--space-16); font-size: var(--font-size-sm); color: var(--color-text-secondary); line-height: var(--line-height-normal); } .onboarding-actions { display: flex; align-items: center; justify-content: space-between; } .onboarding-skip { background: none; border: none; color: var(--color-text-secondary); font-size: var(--font-size-xs); cursor: pointer; padding: var(--space-4); } .onboarding-skip:hover { color: var(--color-text); } .onboarding-nav { display: flex; gap: var(--space-8); } .onboarding-prev, .onboarding-next { padding: var(--space-6) var(--space-16); border-radius: var(--radius-base); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); cursor: pointer; transition: all var(--duration-fast); } .onboarding-prev { background: var(--color-secondary); border: 1px solid var(--color-border); color: var(--color-text); } .onboarding-prev:hover { background: var(--color-secondary-hover); } .onboarding-next { background: var(--color-primary); border: 1px solid var(--color-primary); color: var(--color-btn-primary-text); } .onboarding-next:hover { background: var(--color-primary-hover); } .onboarding-next:focus-visible, .onboarding-prev:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* ========================================================================== NOTIFICATION CENTER ========================================================================== */ .notif-bell { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); cursor: pointer; transition: all var(--duration-fast); } .notif-bell:hover { background: var(--color-secondary-hover); color: var(--color-primary); } .notif-bell:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } .notif-badge { position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px; background: var(--color-error); color: #fff; font-size: 10px; font-weight: var(--font-weight-bold); line-height: 16px; text-align: center; border-radius: var(--radius-full); } .notif-panel { position: fixed; top: 60px; right: var(--space-16); z-index: 10050; width: 360px; max-width: 90vw; max-height: 70vh; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; opacity: 0; pointer-events: none; transform: translateY(-8px); transition: all var(--duration-normal) var(--ease-standard); } .notif-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0); } .notif-panel-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-12) var(--space-16); border-bottom: 1px solid var(--color-border); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); } .notif-panel-actions { display: flex; gap: var(--space-8); } .notif-mark-read, .notif-clear { background: none; border: none; color: var(--color-text-secondary); font-size: var(--font-size-xs); cursor: pointer; padding: var(--space-2) var(--space-4); } .notif-mark-read:hover, .notif-clear:hover { color: var(--color-primary); } .notif-panel-body { flex: 1; overflow-y: auto; padding: var(--space-4) 0; } .notif-item { display: flex; align-items: flex-start; gap: var(--space-10); padding: var(--space-8) var(--space-16); transition: background var(--duration-fast); } .notif-item:hover { background: var(--color-secondary); } .notif-item.unread { background: rgba(var(--color-success-rgb), 0.04); } .notif-item-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; } .notif-info .notif-item-dot { background: var(--color-primary); } .notif-warning .notif-item-dot { background: var(--color-warning); } .notif-error .notif-item-dot { background: var(--color-error); } .notif-item.read .notif-item-dot { opacity: 0.3; } .notif-item-content { flex: 1; min-width: 0; } .notif-item-msg { display: block; font-size: var(--font-size-xs); color: var(--color-text); line-height: 1.4; word-break: break-word; } .notif-item.read .notif-item-msg { color: var(--color-text-secondary); } .notif-item-time { display: block; font-size: 10px; color: var(--color-text-secondary); margin-top: 2px; } .notif-empty { padding: var(--space-24); text-align: center; font-size: var(--font-size-sm); color: var(--color-text-secondary); } /* ========================================================================== IDLE MODE - Reduce visual activity when user is inactive ========================================================================== */ .user-idle .progress-fill, .user-idle .sensing-bar-fill { transition-duration: 0s; animation: none; } .user-idle canvas { opacity: 0.5; transition: opacity 1s; } /* ========================================================================== I18N, SCREENSHOT, UPTIME, SETTINGS, REDUCED MOTION, HIGH CONTRAST ========================================================================== */ /* --- Language Selector --- */ .lang-selector-wrap { display: inline-flex; } .lang-selector { appearance: none; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); padding: var(--space-4) var(--space-20) var(--space-4) var(--space-8); cursor: pointer; background-image: var(--select-caret-light); background-repeat: no-repeat; background-position: right 4px center; background-size: 14px; } [data-color-scheme="dark"] .lang-selector { background-image: var(--select-caret-dark); } .lang-selector:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* --- Uptime Clock --- */ .uptime-clock { display: inline-flex; align-items: center; gap: var(--space-6); font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-text-secondary); } .uptime-separator { opacity: 0.3; } .uptime-duration { color: var(--color-primary); } /* --- Settings Gear --- */ .settings-gear { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; background: var(--color-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-base); color: var(--color-text); cursor: pointer; transition: all var(--duration-fast); } .settings-gear:hover { background: var(--color-secondary-hover); color: var(--color-primary); transform: rotate(30deg); } .settings-gear:focus-visible { outline: var(--focus-outline); outline-offset: 2px; } /* --- Quick Settings Panel --- */ .quick-settings-panel { position: fixed; top: 60px; right: var(--space-16); z-index: 10050; width: 320px; max-width: 90vw; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none; transform: translateY(-8px); transition: all var(--duration-normal) var(--ease-standard); } .quick-settings-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0); } .qs-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-12) var(--space-16); border-bottom: 1px solid var(--color-border); } .qs-header h3 { margin: 0; font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); } .qs-close { background: none; border: none; color: var(--color-text-secondary); font-size: 18px; cursor: pointer; padding: 0 var(--space-2); line-height: 1; } .qs-body { padding: var(--space-8) 0; } .qs-section { padding: var(--space-4) var(--space-16); } .qs-section-title { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-secondary); padding: var(--space-8) 0 var(--space-4); } .qs-toggle { display: flex; align-items: center; justify-content: space-between; padding: var(--space-6) 0; font-size: var(--font-size-sm); color: var(--color-text); cursor: pointer; } .qs-toggle input { display: none; } .qs-switch { width: 36px; height: 20px; border-radius: 10px; background: var(--color-secondary); border: 1px solid var(--color-border); position: relative; transition: all var(--duration-fast); flex-shrink: 0; } .qs-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--color-text-secondary); transition: all var(--duration-fast); } .qs-toggle input:checked + .qs-switch { background: var(--color-primary); border-color: var(--color-primary); } .qs-toggle input:checked + .qs-switch::after { transform: translateX(16px); background: var(--color-btn-primary-text); } .qs-row { display: flex; align-items: center; justify-content: space-between; padding: var(--space-6) 0; font-size: var(--font-size-sm); color: var(--color-text); } .qs-btn, .qs-btn-danger { padding: var(--space-4) var(--space-12); border-radius: var(--radius-sm); font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); cursor: pointer; border: 1px solid var(--color-border); background: var(--color-secondary); color: var(--color-text); transition: all var(--duration-fast); } .qs-btn:hover { background: var(--color-secondary-hover); } .qs-btn-danger { color: var(--color-error); border-color: var(--color-error); } .qs-btn-danger:hover { background: var(--color-error); color: #fff; } /* --- Screenshot Flash --- */ .screenshot-flash { position: fixed; inset: 0; z-index: 99999; background: white; animation: flash-anim 0.3s ease-out forwards; pointer-events: none; } @keyframes flash-anim { 0% { opacity: 0.7; } 100% { opacity: 0; } } /* --- Reduced Motion --- */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; animation-iteration-count: 1 !important; } } .reduced-motion *, .reduced-motion *::before, .reduced-motion *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; animation-iteration-count: 1 !important; } /* --- High Contrast --- */ .high-contrast { --color-text: #000; --color-text-secondary: #333; --color-background: #fff; --color-surface: #fff; --color-border: #000; --color-primary: #0055cc; --color-error: #cc0000; --color-warning: #cc6600; --color-success: #006600; } [data-color-scheme="dark"].high-contrast, .high-contrast[data-color-scheme="dark"] { --color-text: #fff; --color-text-secondary: #ddd; --color-background: #000; --color-surface: #111; --color-border: #fff; --color-primary: #66bbff; --color-error: #ff6666; --color-warning: #ffaa44; --color-success: #44ff44; } /* --- Compact Mode --- */ .compact-mode .header { padding: var(--space-8) var(--space-16); } .compact-mode .header h1 { font-size: var(--font-size-xl); } .compact-mode .subtitle { display: none; } .compact-mode .nav-tab { padding: var(--space-8) var(--space-12); font-size: var(--font-size-xs); } .compact-mode .tab-content { padding-top: var(--space-8); } .compact-mode .hero-section { padding: var(--space-12); } .compact-mode .benefit-card { padding: var(--space-8); } /* --- Responsive --- */ @media (max-width: 640px) { .uptime-clock { display: none; } .lang-selector-wrap { display: none; } }