Files
repo-smod-atsc/out/rootfs/aw/anywave/web/www/css/styles.css
T

1697 lines
38 KiB
CSS
Executable File

/* ==========================================================================
EXCITER DASHBOARD - Responsive Modern Dark Theme (Fixed Bottom Dashboard)
========================================================================== */
:root {
/* Vibrant green - primary accent, status good, active states */
--accent-green: #22c55e;
--accent-green-bright: #4ade80;
--accent-green-dim: #16a34a;
/* Error / alert */
--status-err: #ef4444;
--status-err-dim: #dc2626;
/* Warning / amber */
--status-warn: #f59e0b;
--status-warn-dim: #eab308;
/* Neutral / info */
--status-neutral: #38bdf8;
--status-neutral-dim: #0ea5e9;
/* Dark palette */
--bg-main: #111827;
--bg-panel: #1f2937;
--bg-card: #374151;
--bg-card-hover: #4b5563;
/* Text */
--text-primary: #f9fafb;
--text-secondary: #d1d5db;
--text-muted: #9ca3af;
/* Borders */
--border-subtle: #4b5563;
--border-accent: var(--accent-green);
/* Sidebar */
--sidebar-bg: #0f172a;
--sidebar-text: #94a3b8;
--sidebar-text-active: #ffffff;
--sidebar-hover: #1e293b;
/* Legacy / UI */
--primary: var(--accent-green);
--primary-hover: var(--accent-green-dim);
--font-family: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
/* Layout */
--container-width: 1250px;
--sidebar-width: 220px;
--header-height: 64px;
--dashboard-height: auto;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: var(--font-family);
}
html {
font-size: 14px;
}
body {
background-color: var(--bg-main);
color: var(--text-primary);
font-size: 14px;
line-height: 1.5;
height: 100vh;
overflow: hidden;
}
/* ==========================================================================
LAYOUT GRID SYSTEM - Dashboard under header
========================================================================== */
.app-layout {
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
grid-template-rows: var(--header-height) var(--dashboard-height) 1fr;
grid-template-areas:
"header header"
"sidebar dashboard"
"sidebar main";
height: 100vh;
}
/* ==========================================================================
HEADER
========================================================================== */
.app-header {
grid-area: header;
background: var(--bg-panel);
border-bottom: 2px solid var(--accent-green);
display: flex;
align-items: center;
padding: 0 24px;
position: relative;
}
.app-header h1 {
font-size: 18px;
font-weight: 700;
color: var(--accent-green);
margin-right: 12px;
display: flex;
align-items: center;
}
.app-header h1 .logo-bg {
width: 180px;
height: 64px;
background: url(../images/logo.png) no-repeat left center;
background-size: contain;
}
.app-header h2 {
font-size: 16px;
color: var(--accent-green);
font-weight: 600;
border-left: 1px solid var(--border-subtle);
padding-left: 24px;
margin-left: 12px;
}
.app-header h3 {
font-size: 13px;
color: var(--text-secondary);
font-weight: 500;
text-align: right;
margin-left: auto;
padding-left: 16px;
}
/* ==========================================================================
SIDEBAR
========================================================================== */
.app-sidebar {
grid-area: sidebar;
background: var(--sidebar-bg);
display: flex;
flex-direction: column;
z-index: 101;
border-right: 1px solid var(--border-subtle);
overflow: hidden;
}
.app-sidebar ul.items {
list-style: none;
margin-bottom: auto;
padding: 12px 0;
flex: 1;
overflow-y: auto;
}
.app-sidebar li a {
display: block;
padding: 11px 16px;
color: var(--sidebar-text);
text-decoration: none;
font-size: 13px;
font-weight: 500;
transition: all 0.2s ease;
border-left: 3px solid transparent;
border-radius: 0 6px 6px 0;
}
.app-sidebar li a:hover {
background: var(--sidebar-hover);
color: var(--sidebar-text-active);
}
.app-sidebar li.active a {
background: transparent;
color: var(--sidebar-text-active);
border-left: 3px solid var(--accent-green);
font-weight: 600;
}
.sidebar-footer {
padding: 16px;
color: var(--text-muted);
font-size: 12px;
line-height: 1.5;
border-top: 1px solid var(--border-subtle);
}
.sidebar-footer h4 {
color: var(--text-secondary);
margin-bottom: 8px;
font-size: 13px;
font-weight: 600;
}
.sidebar-footer p {
font-size: 12px;
font-weight: 400;
margin: 0;
}
.sidebar-footer .redbox-label {
font-weight: 600;
color: var(--text-secondary);
}
.sidebar-footer a {
color: var(--status-neutral);
font-weight: 500;
}
/* ==========================================================================
MAIN CONTENT - Scrollable area (1250px centered)
========================================================================== */
.app-main {
grid-area: main;
padding: 20px 24px;
background: var(--bg-main);
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
display: flex;
flex-direction: column;
align-items: center;
}
.app-main > * {
width: 100%;
max-width: 1250px;
}
.app-main::-webkit-scrollbar {
width: 8px;
}
.app-main::-webkit-scrollbar-track {
background: var(--bg-main);
}
.app-main::-webkit-scrollbar-thumb {
background: var(--border-subtle);
border-radius: 4px;
}
.app-main::-webkit-scrollbar-thumb:hover {
background: var(--bg-card-hover);
}
/* ==========================================================================
FIXED DASHBOARD SUMMARY - Top of page, under header
========================================================================== */
.dashboard-fixed {
grid-area: dashboard;
background: var(--bg-panel);
border-top: 2px solid var(--accent-green);
padding: 8px 24px;
z-index: 100;
overflow: hidden;
display: flex;
justify-content: center;
}
.summary-dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 8px;
width: 100%;
max-width: 1250px;
height: 100%;
}
.summary-card {
background: var(--bg-card);
border-radius: 8px;
border: 1px solid var(--border-subtle);
padding: 6px 8px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 2px;
transition: box-shadow 0.2s ease, border-color 0.2s ease;
min-height: 0;
}
.summary-card:hover {
border-color: var(--bg-card-hover);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
.summary-card:has(.value-err) {
border-left: 3px solid var(--status-err);
background: rgba(239, 68, 68, 0.08);
animation: errPulseBg 2s ease-in-out infinite;
}
@keyframes errPulseBg {
0%, 100% { background: rgba(239, 68, 68, 0.08); }
50% { background: rgba(239, 68, 68, 0.18); }
}
.summary-card:has(.value-warn) {
border-left: 3px solid var(--status-warn);
background: rgba(245, 158, 11, 0.08);
}
.summary-label-row {
display: flex;
align-items: center;
gap: 4px;
}
.status-dot {
width: 7px;
height: 7px;
border-radius: 50%;
flex-shrink: 0;
transition: background-color 0.2s ease, box-shadow 0.2s ease;
}
.status-dot.status-ok {
background-color: var(--accent-green);
box-shadow: 0 0 4px rgba(34, 197, 94, 0.5);
}
.status-dot.status-err {
background-color: var(--status-err);
box-shadow: 0 0 4px rgba(239, 68, 68, 0.5);
}
.status-dot.status-warn {
background-color: var(--status-warn);
box-shadow: 0 0 4px rgba(245, 158, 11, 0.5);
}
.status-dot.status-neutral {
background-color: var(--status-neutral);
box-shadow: 0 0 4px rgba(56, 189, 248, 0.4);
}
.status-dot.status-off {
background-color: var(--text-muted);
box-shadow: 0 0 3px rgba(156, 163, 175, 0.3);
}
.summary-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.summary-value-wrapper {
display: flex;
align-items: baseline;
gap: 2px;
min-width: 0;
}
.summary-value {
font-size: 16px;
font-weight: 700;
line-height: 1.1;
transition: color 0.2s ease;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.summary-value.value-ok { color: var(--accent-green); }
.summary-value.value-err { color: var(--status-err); }
.summary-value.value-warn { color: var(--status-warn); }
.summary-value.value-neutral { color: var(--status-neutral); }
.summary-value.value-muted { color: var(--text-muted); }
.summary-value.value-off { color: var(--text-muted); }
.summary-unit {
font-size: 9px;
font-weight: 500;
color: var(--text-muted);
}
/* ==========================================================================
STATUS ALERT STRIP
========================================================================== */
.content-page-title {
font-size: 18px;
font-weight: 600;
color: var(--accent-green);
margin: 0 0 12px 0;
padding-bottom: 6px;
border-bottom: 1px solid var(--border-subtle);
}
.content-page-title:empty {
display: none;
margin: 0;
padding: 0;
border: none;
}
#status-alert-strip, .status-alert {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 14px;
border-radius: 8px;
margin-bottom: 16px;
font-size: 13px;
font-weight: 600;
transition: all 0.3s ease;
}
.status-alert-icon {
width: 10px;
height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
#status-alert-strip.status-alert-ok, .status-alert-ok {
background: rgba(34, 197, 94, 0.15);
border: 1px solid rgba(34, 197, 94, 0.4);
color: var(--accent-green);
}
#status-alert-strip.status-alert-ok .status-alert-icon, .status-alert-ok .status-alert-icon {
background: var(--accent-green);
box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
}
#status-alert-strip.status-alert-warn, .status-alert-warn {
background: rgba(245, 158, 11, 0.15);
border: 1px solid rgba(245, 158, 11, 0.4);
color: var(--status-warn);
}
#status-alert-strip.status-alert-warn .status-alert-icon, .status-alert-warn .status-alert-icon {
background: var(--status-warn);
}
#status-alert-strip.status-alert-err, .status-alert-err {
background: rgba(239, 68, 68, 0.15);
border: 1px solid rgba(239, 68, 68, 0.4);
color: var(--status-err);
}
#status-alert-strip.status-alert-err .status-alert-icon, .status-alert-err .status-alert-icon {
background: var(--status-err);
box-shadow: 0 0 8px rgba(239, 68, 68, 0.4);
}
#status-alert-detail, .status-alert-detail {
color: var(--text-secondary);
font-weight: 500;
}
.status-alert-detail:empty {
display: none;
}
/* ==========================================================================
CONTENT SECTIONS
========================================================================== */
.app-main h2 {
color: var(--text-primary);
font-size: 17px;
font-weight: 600;
margin: 20px 0 10px 0;
padding-bottom: 6px;
border-bottom: 1px solid var(--border-subtle);
}
.app-main h2:first-of-type {
margin-top: 0;
}
.box {
background: var(--bg-card);
border-radius: 10px;
border: 1px solid var(--border-subtle);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
padding: 14px;
margin-bottom: 14px;
}
/* Grid system for content boxes */
.content-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.content-grid .box {
margin-bottom: 0;
}
.content-grid-full {
grid-column: 1 / -1;
}
/* ==========================================================================
BOX ACCORDION HEADER
========================================================================== */
.box-header {
padding: 10px 14px;
background-color: var(--bg-card-hover);
border-bottom: 1px solid var(--border-subtle);
margin: -14px -14px 14px -14px;
border-radius: 10px 10px 0 0;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
color: var(--text-primary);
transition: background-color 0.2s ease;
user-select: none;
}
.box-header:hover {
background-color: var(--border-subtle);
}
.box-header::after {
content: '\25BC';
font-size: 12px;
color: var(--accent-green);
}
.box-header.has-error::after,
.box-header.has-error.collapsed::after {
color: var(--status-err) !important;
}
.box-header.collapsed::after {
content: '\25C0';
}
.box-header.collapsed {
border-bottom: none;
margin-bottom: -14px;
border-radius: 10px;
}
.box-header .toggle-text {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.5px;
background-color: var(--accent-green);
color: #fff;
padding: 4px 10px;
border-radius: 6px;
margin-left: auto;
margin-right: 10px;
transition: background-color 0.2s ease;
}
.box-header.collapsed .toggle-text {
background-color: var(--text-muted);
}
/* Accordion Specific Settings */
.app-main .sysset-accordion .box-header {
border-radius: 10px 10px 0 0;
}
.app-main .sysset-accordion .box-header.collapsed {
border-radius: 10px;
margin-bottom: 0;
}
.app-main .sysset-accordion .box-content {
display: none;
padding: 14px;
margin: 0 -14px -14px -14px;
border-radius: 0 0 10px 10px;
border-top: 1px solid var(--border-subtle);
}
.app-main .sysset-accordion .box-header:not(.collapsed) + .box-content {
display: block;
}
.app-main .sysset-accordion .box-header.accordion-header-warning {
background-color: rgba(239, 68, 68, 0.15);
border-left: 4px solid var(--status-err);
}
.app-main .sysset-accordion .box-header.accordion-header-warning:hover {
background-color: rgba(239, 68, 68, 0.22);
}
.app-main .sysset-accordion .box-header.accordion-header-warning::after {
color: var(--status-err);
}
/* ==========================================================================
TABLES & FORMS
========================================================================== */
table {
width: 100%;
border-collapse: collapse;
}
td {
padding: 6px 8px;
vertical-align: middle;
color: var(--text-primary);
border-bottom: 1px solid var(--border-subtle);
}
.app-main .box table td {
border-bottom: 1px solid var(--border-subtle);
}
.app-main .box table tr:last-child td {
border-bottom: none;
}
td:nth-child(odd) {
font-weight: 600;
color: var(--text-secondary);
font-size: 12px;
letter-spacing: 0.4px;
min-width: 130px;
width: 1%;
white-space: nowrap;
background-color: transparent;
}
td:nth-child(even) {
min-width: 0;
width: auto;
}
tr:last-child td {
border-bottom: none;
}
/* Advanced Table Layouts */
.app-main .box table.table-layout-4col,
.app-main .box table.table-layout-dgv,
.app-main .box table.table-layout-freq,
.app-main .box table.table-layout-standard {
table-layout: fixed;
width: 100%;
text-align: left;
}
.app-main .box table.table-layout-freq td:first-child,
.app-main .box table.table-layout-standard td:first-child {
width: 260px;
min-width: 260px;
max-width: 260px;
white-space: nowrap;
}
.app-main .box table.table-layout-4col td:first-child {
width: 260px;
min-width: 260px;
max-width: 260px;
white-space: nowrap;
}
.app-main .box table.table-layout-4col td:nth-child(2) {
width: 220px;
min-width: 220px;
max-width: 220px;
}
.app-main .box table.table-layout-4col td:nth-child(3) {
width: 260px;
min-width: 260px;
max-width: 260px;
white-space: nowrap;
}
.app-main .box table.table-layout-dgv td:first-child {
width: 260px;
min-width: 260px;
max-width: 260px;
white-space: nowrap;
}
.app-main .box table.table-layout-dgv td:nth-child(2) {
width: 100px;
min-width: 100px;
max-width: 100px;
}
.app-main .box table.table-layout-dgv td:nth-child(3) {
width: 120px;
min-width: 120px;
max-width: 120px;
white-space: nowrap;
}
.app-main .box table.table-layout-dgv td:nth-child(4) {
width: 260px;
min-width: 260px;
max-width: 260px;
white-space: nowrap;
}
.app-main .box table.table-layout-dgv td:nth-child(5) {
width: 100px;
min-width: 100px;
max-width: 100px;
}
.app-main .box table.table-layout-dgv td:nth-child(6) {
width: auto;
min-width: 0;
}
/* Error highlighting */
tr.row-has-error td {
background: rgba(239, 68, 68, 0.08);
}
tr.row-has-error td:nth-child(odd) {
background: rgba(239, 68, 68, 0.12);
}
tr.header-row td {
background-color: var(--bg-card-hover);
color: var(--text-primary);
font-weight: 700;
font-size: 13px;
}
/* Log Export Styles */
.log-export-box td.log-export-label {
min-width: 220px;
width: auto;
white-space: nowrap;
}
.log-export-box td.log-export-actions {
display: flex;
align-items: center;
gap: 12px;
}
/* Inputs */
input[type="text"],
input[type="password"],
input[readonly],
input:not([type]),
select {
width: 100%;
max-width: 90px;
padding: 6px 8px;
font-size: 13px;
color: var(--text-secondary);
background-color: var(--bg-panel);
border: 1px solid var(--border-subtle);
border-radius: 6px;
transition: all 0.2s ease;
outline: none;
}
.app-main select {
width: auto;
min-width: 100px;
max-width: 180px;
}
input:focus,
.app-main select:focus,
select:focus {
border-color: var(--accent-green);
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2);
}
input[readonly] {
background-color: var(--bg-panel);
border-color: var(--border-subtle);
color: var(--text-secondary);
font-weight: 500;
cursor: default;
}
/* Display-only select menus */
select.display-only-select:disabled {
opacity: 1;
color: var(--text-secondary);
-webkit-text-fill-color: var(--text-secondary);
}
select.display-only-select:disabled.state-error {
color: var(--status-err) !important;
-webkit-text-fill-color: var(--status-err) !important;
font-weight: bold !important;
}
select.display-only-select:disabled.state-ok {
color: var(--accent-green) !important;
-webkit-text-fill-color: var(--accent-green) !important;
font-weight: bold !important;
}
/* Buttons */
input[type="button"].btn-modern,
input[type="submit"].btn-modern {
background-color: var(--accent-green-dim);
color: var(--text-primary);
font-size: 13px;
font-weight: 600;
padding: 8px 18px;
border: 1px solid var(--border-subtle);
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
outline: none;
text-transform: none;
}
input[type="button"].btn-modern:hover,
input[type="submit"].btn-modern:hover {
background-color: var(--accent-green);
border-color: var(--accent-green);
color: #fff;
}
input[type="button"].btn-modern:active,
input[type="submit"].btn-modern:active {
background-color: var(--accent-green-dim);
}
input[type="button"].btn-modern:disabled,
input[type="submit"].btn-modern:disabled {
background-color: var(--bg-card);
color: var(--text-muted);
border-color: var(--border-subtle);
cursor: not-allowed;
}
/* Unsaved reminder */
input[type="button"].btn-modern.is-unsaved:not(:disabled),
input[type="submit"].btn-modern.is-unsaved:not(:disabled) {
background-color: var(--accent-green) !important;
border-color: var(--accent-green) !important;
color: #fff !important;
box-shadow: 0 0 10px rgba(34, 197, 94, 0.35);
}
fieldset {
border: none;
display: flex;
align-items: center;
gap: 6px;
}
fieldset input {
text-align: center;
}
.app-main .box table td fieldset {
justify-content: flex-start;
}
.app-main .box table td fieldset input {
text-align: left;
}
/* ==========================================================================
DROPDOWN
========================================================================== */
.dropdown {
position: relative;
display: inline-block;
}
.dropbtn-modern {
background-color: var(--bg-card);
color: var(--text-primary);
font-size: 12px;
font-weight: 600;
padding: 6px 12px;
border: 1px solid var(--border-subtle);
border-radius: 6px;
cursor: pointer;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.2s ease;
outline: none;
text-transform: none;
}
.dropdown:hover .dropbtn-modern {
border-color: var(--accent-green);
color: var(--accent-green-bright);
}
.dropdown-content {
display: none;
position: absolute;
right: 0;
background-color: var(--bg-card);
min-width: 160px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4);
border-radius: 8px;
border: 1px solid var(--border-subtle);
z-index: 1000;
overflow: hidden;
}
.dropdown-content a {
color: var(--text-primary);
font-size: 13px;
font-weight: 500;
padding: 10px 14px;
text-decoration: none;
display: flex;
align-items: center;
gap: 10px;
transition: background-color 0.2s ease, color 0.2s ease;
}
.dropdown-content a:hover {
background-color: var(--sidebar-hover);
color: var(--accent-green-bright);
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown-content a svg {
width: 16px;
height: 16px;
color: var(--text-muted);
}
.dropdown-content a:hover svg {
color: var(--accent-green);
}
/* ==========================================================================
MODAL
========================================================================== */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
}
.modal-content {
background-color: var(--bg-card);
margin: 10% auto;
padding: 0;
border-radius: 12px;
border: 1px solid var(--border-subtle);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
width: 400px;
animation: modalFadeIn 0.3s ease-out;
}
@keyframes modalFadeIn {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
.modal-header {
background-color: var(--bg-card-hover);
padding: 15px 20px;
border-bottom: 1px solid var(--border-subtle);
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 12px 12px 0 0;
}
.modal-header h3 {
margin: 0;
color: var(--text-primary);
font-size: 16px;
font-weight: 600;
}
.modal-header .close {
color: var(--text-secondary);
font-size: 24px;
font-weight: bold;
cursor: pointer;
transition: color 0.2s;
}
.modal-header .close:hover {
color: var(--status-err);
}
.modal-body {
padding: 20px;
}
.modal-table {
width: 100%;
}
.modal-table td {
border: none;
padding: 10px 5px;
color: var(--text-primary);
}
.modal-table td:nth-child(odd) {
width: 40%;
text-align: right;
padding-right: 15px;
color: var(--text-secondary);
}
.modal-table td:nth-child(even) {
width: 60%;
}
.modal-table input[type="text"],
.modal-table input[type="password"] {
width: 100%;
max-width: none;
padding: 8px 10px;
box-sizing: border-box;
background-color: var(--bg-panel);
border-color: var(--border-subtle);
color: var(--text-primary);
}
.modal-footer {
padding-top: 20px;
display: flex;
justify-content: flex-end;
gap: 10px;
}
/* ==========================================================================
LOGIN PAGE SPECIFIC
========================================================================== */
.login-container {
display: flex;
align-items: center;
justify-content: center;
min-height: calc(100vh - var(--header-height) - var(--dashboard-height) - 40px);
}
.login-box {
width: 100%;
max-width: 400px;
}
/* ==========================================================================
UTILITY CLASSES
========================================================================== */
/* Highlighted input fields (editable emphasis) */
.highlight {
border-color: var(--accent-green) !important;
background-color: rgba(34, 197, 94, 0.08);
transition: background-color 0.2s ease, border-color 0.2s ease;
}
.highlight:focus {
background-color: rgba(34, 197, 94, 0.15);
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.3);
}
/* Clearfix for floated elements */
.clear::after {
content: "";
display: table;
clear: both;
}
/* Responsive table wrapper for horizontal scroll on narrow screens */
.table-responsive-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
/* ==========================================================================
BUTTON VIEW DETAILS
========================================================================== */
.btn-view-details {
display: inline-block;
background-color: var(--bg-card-hover);
color: var(--text-primary);
font-size: 12px;
font-weight: 600;
padding: 8px 16px;
border: 1px solid var(--border-subtle);
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
outline: none;
margin-top: 12px;
}
.btn-view-details:hover {
background-color: var(--accent-green);
border-color: var(--accent-green);
color: #fff;
}
/* ==========================================================================
HAMBURGER MENU TOGGLE
========================================================================== */
.menu-toggle {
display: none;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
background: none;
border: 1px solid var(--border-subtle);
border-radius: 6px;
cursor: pointer;
padding: 0;
margin-right: 12px;
transition: border-color 0.2s ease;
}
.menu-toggle:hover {
border-color: var(--accent-green);
}
.menu-toggle svg {
width: 20px;
height: 20px;
color: var(--text-primary);
}
/* ==========================================================================
RESPONSIVE BREAKPOINTS
========================================================================== */
/* 1080P and above (1920px+) */
@media (min-width: 1920px) {
:root {
--container-width: 1440px;
--sidebar-width: 240px;
}
.summary-dashboard {
grid-template-columns: repeat(12, 1fr);
}
.content-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Standard 1080P (1250px - 1919px) */
@media (min-width: 1250px) and (max-width: 1919px) {
:root {
--container-width: 1250px;
--sidebar-width: 220px;
}
.summary-dashboard {
grid-template-columns: repeat(6, 1fr);
}
.content-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Tablet landscape (1024px - 1279px) */
@media (min-width: 1024px) and (max-width: 1279px) {
:root {
--container-width: 100%;
--sidebar-width: 200px;
}
.summary-dashboard {
grid-template-columns: repeat(6, 1fr);
}
.content-grid {
grid-template-columns: 1fr;
}
}
/* Tablet portrait (768px - 1023px) */
@media (min-width: 768px) and (max-width: 1023px) {
.app-layout {
grid-template-columns: 1fr;
grid-template-rows: var(--header-height) var(--dashboard-height) 1fr;
grid-template-areas:
"header"
"dashboard"
"main";
}
/* Overlay sidebar */
.app-sidebar {
position: fixed;
top: 0;
left: -220px;
width: 220px;
height: 100vh;
z-index: 500;
transition: left 0.3s ease;
box-shadow: none;
}
.app-sidebar.sidebar-open {
left: 0;
box-shadow: 4px 0 20px rgba(0, 0, 0, 0.5);
}
.sidebar-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 499;
}
.sidebar-overlay.active {
display: block;
}
.menu-toggle {
display: flex;
}
.summary-dashboard {
grid-template-columns: repeat(4, 1fr);
}
.content-grid {
grid-template-columns: 1fr;
}
}
/* Mobile (< 768px) */
@media (max-width: 767px) {
:root {
}
.app-layout {
grid-template-columns: 1fr;
grid-template-rows: var(--header-height) var(--dashboard-height) 1fr;
grid-template-areas:
"header"
"dashboard"
"main";
}
/* Overlay sidebar */
.app-sidebar {
position: fixed;
top: 0;
left: -220px;
width: 220px;
height: 100vh;
z-index: 500;
transition: left 0.3s ease;
box-shadow: none;
}
.app-sidebar.sidebar-open {
left: 0;
box-shadow: 4px 0 20px rgba(0, 0, 0, 0.5);
}
.sidebar-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 499;
}
.sidebar-overlay.active {
display: block;
}
.menu-toggle {
display: flex;
}
.summary-dashboard {
grid-template-columns: repeat(3, 1fr);
}
.content-grid {
grid-template-columns: 1fr;
}
.app-header {
padding: 0 16px;
}
.app-main {
padding: 16px;
}
.dashboard-fixed {
padding: 8px 16px;
}
}
/* Very small screens */
@media (max-width: 480px) {
:root {
}
.summary-dashboard {
grid-template-columns: repeat(2, 1fr);
}
}
/* ==========================================================================
GATEWAY STATUS - UTILIZATION BARS
========================================================================== */
/* Total Status - enhanced alarm display */
.total-status-grid {
display: grid;
grid-template-columns: auto 1fr auto 1fr;
align-items: center;
gap: 4px 12px;
padding: 4px 0;
}
.total-status-grid .status-label {
font-weight: 600;
color: var(--text-secondary);
font-size: 12px;
letter-spacing: 0.4px;
white-space: nowrap;
}
.total-status-grid .status-value {
font-size: 15px;
font-weight: 700;
color: var(--text-primary);
}
.total-status-grid .status-value.alarm-ok {
color: var(--accent-green);
}
.total-status-grid .status-value.alarm-overflow {
color: var(--status-err);
animation: alarmPulse 1.2s ease-in-out infinite;
}
.total-status-grid .frame-time-value {
font-size: 15px;
font-weight: 700;
color: var(--status-neutral);
font-variant-numeric: tabular-nums;
}
.total-status-grid .frame-time-unit {
font-size: 11px;
font-weight: 500;
color: var(--text-muted);
margin-left: 3px;
}
@keyframes alarmPulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
.alarm-overflow-border {
animation: alarmBorderPulse 1.2s ease-in-out infinite;
}
@keyframes alarmBorderPulse {
0%, 100% { border-color: var(--status-err); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
50% { border-color: var(--status-err); box-shadow: 0 0 12px 2px rgba(239, 68, 68, 0.35); }
}
/* Subframe container */
.subframe-title {
font-size: 15px;
font-weight: 700;
color: var(--accent-green);
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 1px solid var(--border-subtle);
letter-spacing: 0.3px;
}
/* PLP row layout — same style as subframe-header: label | bar | bitrate | pct */
.plp-row {
display: grid;
grid-template-columns: 42px 1fr auto auto;
gap: 2px 10px;
align-items: center;
padding: 6px 0;
border-bottom: 1px solid rgba(75, 85, 99, 0.4);
}
.plp-row:last-of-type {
border-bottom: none;
}
/* PLP label (PLP0, PLP1, etc.) */
.plp-label {
grid-row: 1;
font-size: 12px;
font-weight: 800;
color: var(--text-secondary);
letter-spacing: 0.8px;
text-transform: uppercase;
text-align: center;
padding: 4px 0;
border-radius: 4px;
background: rgba(75, 85, 99, 0.3);
}
/* Bar track (background) */
.plp-bar-track {
grid-column: 2;
grid-row: 1;
position: relative;
height: 18px;
background: rgba(75, 85, 99, 0.35);
border-radius: 4px;
overflow: hidden;
}
/* Bar fill (colored portion) */
.plp-bar-fill {
height: 100%;
border-radius: 4px;
min-width: 0;
transition: width 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94),
background-color 0.4s ease;
position: relative;
}
/* Bar fill color states — muted tones for dark theme readability */
.plp-bar-fill.bar-green {
background: linear-gradient(90deg, #166534, #22c55e);
opacity: 0.75;
}
.plp-bar-fill.bar-amber {
background: linear-gradient(90deg, #92400e, #f59e0b);
opacity: 0.78;
}
.plp-bar-fill.bar-red {
background: linear-gradient(90deg, #991b1b, #ef4444);
opacity: 0.78;
}
.plp-bar-fill.bar-muted {
background: var(--bg-card-hover);
}
/* Bitrate text (right of bar, same line) */
.plp-row .plp-bitrate-text {
grid-column: 3;
grid-row: 1;
font-size: 12px;
font-weight: 600;
color: var(--text-primary);
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
/* Percentage text (right of bitrate, same line) */
.plp-pct-text {
grid-column: 4;
grid-row: 1;
font-size: 12px;
font-weight: 800;
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
.plp-pct-text.pct-green { color: var(--accent-green); }
.plp-pct-text.pct-amber { color: var(--status-warn); }
.plp-pct-text.pct-red { color: var(--status-err); }
.plp-pct-text.pct-muted { color: var(--text-muted); }
/* Detail line (services + FULL indicator, below bar) */
.plp-detail {
grid-column: 2 / -1;
grid-row: 2;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.plp-full-indicator {
font-size: 11px;
font-weight: 700;
color: var(--status-err);
background: rgba(239, 68, 68, 0.15);
border: 1px solid rgba(239, 68, 68, 0.35);
padding: 1px 7px;
border-radius: 4px;
white-space: nowrap;
display: none;
}
.plp-full-indicator.visible {
display: inline-block;
animation: alarmPulse 1.5s ease-in-out infinite;
}
.plp-services {
font-size: 13px;
font-weight: 600;
color: var(--status-neutral);
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.plp-services:empty {
display: none;
}
.plp-services::before {
content: '[';
color: var(--border-subtle);
}
.plp-services::after {
content: ']';
color: var(--border-subtle);
}
/* Subframe header bar (total payload at top) */
.subframe-header {
display: grid;
grid-template-columns: 56px 1fr auto;
gap: 0 10px;
align-items: center;
padding: 2px 0 10px 0;
margin-bottom: 6px;
border-bottom: 1px solid var(--border-subtle);
}
.subframe-header .summary-label {
font-size: 11px;
font-weight: 800;
color: var(--accent-green);
letter-spacing: 0.8px;
text-transform: uppercase;
text-align: center;
}
.subframe-header .plp-bar-track {
height: 22px;
border: 1px solid var(--border-subtle);
}
.subframe-header .plp-bar-fill {
border-radius: 3px;
}
.subframe-header .plp-bitrate-text {
font-size: 13px;
font-weight: 700;
color: var(--text-primary);
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
.subframe-header .summary-pct {
font-weight: 700;
margin-left: 4px;
}
.subframe-header .summary-pct.pct-green { color: var(--accent-green); }
.subframe-header .summary-pct.pct-amber { color: var(--status-warn); }
.subframe-header .summary-pct.pct-red { color: var(--status-err); }
/* Global payload bar (inside Total Status box) */
.global-header {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--border-subtle);
border-bottom: none;
padding-bottom: 2px;
margin-bottom: 0;
}
.global-header .plp-bar-track {
height: 26px;
border: 1px solid var(--border-subtle);
}
.global-header .summary-label {
color: var(--status-neutral);
font-size: 12px;
}
.global-header .plp-bitrate-text {
font-size: 14px;
font-weight: 800;
}
/* Responsive adjustments for utilization bars */
@media (max-width: 767px) {
.plp-row {
grid-template-columns: 36px 1fr auto;
}
.plp-row .plp-bitrate-text {
font-size: 11px;
}
.plp-pct-text {
display: none;
}
.plp-detail {
flex-wrap: wrap;
}
.plp-services {
max-width: none;
}
.subframe-header {
grid-template-columns: 48px 1fr;
}
.subframe-header .plp-bitrate-text {
grid-column: 1 / -1;
text-align: center;
margin-top: 4px;
}
.global-header {
grid-template-columns: 48px 1fr;
}
.global-header .plp-bitrate-text {
grid-column: 1 / -1;
text-align: center;
margin-top: 4px;
}
}
/* ==========================================================================
SESSION TIMEOUT WARNING
========================================================================== */
#session-timeout-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10000;
}
.session-timeout-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
}
.session-timeout-dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--bg-panel, #1e293b);
border: 1px solid var(--status-warn, #f59e0b);
border-radius: 12px;
padding: 28px 32px;
text-align: center;
min-width: 320px;
max-width: 420px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
.session-timeout-icon {
font-size: 40px;
margin-bottom: 12px;
}
.session-timeout-dialog h3 {
margin: 0 0 12px 0;
color: var(--status-warn, #f59e0b);
font-size: 18px;
}
.session-timeout-dialog p {
margin: 0 0 8px 0;
color: var(--text-secondary, #94a3b8);
font-size: 14px;
line-height: 1.5;
}
.session-timeout-dialog #session-countdown {
font-weight: 700;
color: var(--status-err, #ef4444);
font-size: 16px;
}
.session-timeout-actions {
margin-top: 20px;
display: flex;
gap: 12px;
justify-content: center;
}
.session-timeout-actions .btn-modern {
min-width: 120px;
}