You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1911 lines
67 KiB

:root {
--bg: #eef1f6;
--surface: #ffffff;
--surface-muted: #f5f7fb;
--line: #dfe5ee;
--text: #5d6a7d;
--heading: #33445b;
--sidebar: #31435f;
--sidebar-deep: #25354c;
--sidebar-active: #1f90ff;
--accent: #4ea0ff;
--accent-strong: #3f97f7;
--danger: #ff5e5e;
--success: #3e9b61;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; font-family: "Segoe UI", "Malgun Gothic", sans-serif; background: var(--bg); color: var(--text); }
a { text-decoration: none; color: inherit; }
button, input, select, textarea { font: inherit; }
.login-body {
min-height: 100vh;
background:
radial-gradient(circle at top left, rgba(78,160,255,0.22), transparent 30%),
linear-gradient(180deg, #1f2f45 0%, #2f4260 100%);
}
.login-shell {
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
}
.login-panel {
position: relative;
width: min(440px, 100%);
background: rgba(255,255,255,0.97);
border: 1px solid rgba(223,229,238,0.9);
border-radius: 18px;
padding: 28px;
box-shadow: 0 26px 70px rgba(16, 28, 44, 0.35);
}
.login-brand {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 22px;
}
.login-brand .brand-mark {
background: #25354c;
color: #ffffff;
border: 1px solid #1f2f45;
box-shadow: 0 5px 14px rgba(37, 53, 76, 0.22);
}
.login-brand .brand-title {
color: #25354c;
}
.login-brand .brand-subtitle {
color: #6e7d92;
opacity: 1;
}
.login-copy h1 {
margin: 0;
font-size: 28px;
color: var(--heading);
}
.login-copy p {
margin: 8px 0 0;
font-size: 14px;
color: #6e7d92;
}
.login-form {
display: grid;
gap: 14px;
margin-top: 22px;
}
.login-submit {
min-height: 40px;
}
.login-progress {
display: grid;
gap: 8px;
padding: 11px 12px;
border: 1px solid #cadbf0;
border-radius: 8px;
background: #f4f8fd;
}
.login-progress[hidden] { display: none; }
.login-progress-track {
height: 7px;
overflow: hidden;
border-radius: 999px;
background: #dce7f5;
}
.login-progress-track span {
display: block;
width: 42%;
height: 100%;
border-radius: inherit;
background: #3f97f7;
/* Update only when readiness changes; continuous compositing is costly on the device. */
animation: none;
}
.login-progress[data-state="ready"] {
border-color: #b9dec8;
background: #f0faf4;
}
.login-progress[data-state="ready"] .login-progress-track {
background: #d7ecdf;
}
.login-progress[data-state="ready"] .login-progress-track span {
width: 100%;
transform: none;
animation: none;
background: #3e9b61;
}
.login-progress[data-state="ready"] p { color: #34754e; }
.login-progress p {
margin: 0;
color: #536b89;
font-size: 12px;
}
.login-error {
margin-top: 18px;
border: 1px solid #f1c6c6;
background: #fff1f1;
color: #b14e4e;
border-radius: 10px;
padding: 12px 14px;
font-size: 13px;
}
.login-hint {
margin-top: 16px;
font-size: 13px;
color: #6f7d91;
}
.app-shell { display: flex; min-height: 100vh; }
.sidebar {
width: 200px;
background: linear-gradient(180deg, var(--sidebar-deep), var(--sidebar));
color: #dbe4f0;
padding: 18px 0 24px;
flex: 0 0 200px;
overflow-x: hidden;
overflow-y: auto;
scrollbar-color: rgba(255,255,255,0.22) transparent;
scrollbar-width: thin;
}
.brand { display: flex; align-items: center; gap: 10px; padding: 0 18px 16px; border-bottom: 1px solid rgba(255,255,255,0.08); }
.brand-mark { width: 34px; height: 34px; border-radius: 999px; background: rgba(255,255,255,0.12); display: flex; align-items: center; justify-content: center; font-weight: 700; color: #fff; }
.brand-title { color: #fff; font-size: 20px; font-weight: 700; line-height: 1; }
.brand-subtitle { margin-top: 4px; font-size: 11px; opacity: 0.7; }
.nav { padding: 10px 10px 0; }
.nav-group { margin-bottom: 2px; }
.nav-item, .nav-child {
display: flex;
align-items: center;
width: 100%;
min-height: 42px;
border-radius: 4px;
color: #dbe4f0;
}
.nav-item {
gap: 12px;
justify-content: flex-start;
padding: 0 10px;
}
.nav-item.active, .nav-child.active { background: rgba(78,160,255,0.18); color: #58a5ff; font-weight: 600; }
.nav-label {
min-width: 0;
overflow: hidden;
font-size: 14px;
text-overflow: ellipsis;
white-space: nowrap;
}
.nav-caret {
width: 8px;
height: 8px;
flex: 0 0 auto;
margin-right: 2px;
margin-left: auto;
border-right: 1.5px solid currentColor;
border-bottom: 1.5px solid currentColor;
transform: rotate(45deg);
transition: transform 0.18s ease;
}
.nav-children {
display: none;
margin: 2px 0 7px 12px;
padding: 2px 0 2px 8px;
border-left: 1px solid rgba(191, 210, 234, 0.24);
}
.nav-group.expanded .nav-children { display: block; }
.nav-group.expanded .nav-caret { transform: rotate(225deg); }
.nav-child {
min-height: 36px;
padding: 0 10px;
color: #c4d1e1;
font-size: 13px;
}
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
height: 56px;
background: #243349;
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
}
.topbar-left, .topbar-right { display: flex; align-items: center; gap: 12px; }
.language-switch {
display: inline-flex;
align-items: center;
gap: 6px;
color: inherit;
font-size: 12px;
font-weight: 700;
}
.language-switch select {
height: 30px;
border: 1px solid rgba(255,255,255,0.35);
border-radius: 4px;
background: rgba(15, 23, 42, 0.32);
color: #fff;
padding: 0 26px 0 9px;
font-size: 12px;
}
.language-switch select option { color: #172033; background: #fff; }
.login-language {
position: absolute;
top: 18px;
right: 18px;
color: #475569;
}
.login-language select {
border-color: #cbd5e1;
background: #fff;
color: #172033;
}
.menu-toggle { display: none; border: 0; background: transparent; color: #fff; font-size: 20px; }
.topbar-crumbs { font-size: 13px; opacity: 0.92; }
.crumb-sep { margin: 0 6px; opacity: 0.55; }
.legacy-link { font-size: 12px; padding: 6px 10px; border-radius: 4px; background: rgba(255,255,255,0.1); }
.user-pill { font-size: 14px; }
.theme-pill { border: 0; background: var(--accent-strong); color: #fff; border-radius: 3px; padding: 6px 12px; font-size: 12px; }
.reboot-button {
border: 1px solid #ef8d8d;
background: #b93737;
color: #fff;
border-radius: 4px;
padding: 6px 12px;
font-size: 12px;
cursor: pointer;
}
.logout-form { margin: 0; }
.logout-button {
border: 1px solid rgba(255,255,255,0.18);
background: rgba(255,255,255,0.06);
color: #fff;
border-radius: 4px;
padding: 6px 10px;
font-size: 12px;
cursor: pointer;
}
.workspace-tabs {
display: flex;
gap: 2px;
overflow-x: auto;
padding: 6px 8px 0;
background: #f5f6f8;
border-bottom: 1px solid #e0e4eb;
}
.workspace-tab {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
background: #fff;
border: 1px solid #dce3eb;
border-bottom: 0;
border-radius: 4px 4px 0 0;
font-size: 12px;
color: #6d7b90;
white-space: nowrap;
}
.workspace-tab-link { color: inherit; }
.workspace-tab.active { background: var(--accent-strong); color: #fff; border-color: var(--accent-strong); }
.workspace-close {
border: 0;
background: transparent;
color: inherit;
opacity: 0.7;
cursor: pointer;
padding: 0;
line-height: 1;
}
.workspace-close:hover { opacity: 1; }
.content { padding: 14px 8px 20px; }
.page-header { display: flex; align-items: center; gap: 12px; padding: 8px 10px 10px; }
.page-kicker { font-size: 13px; color: #7b8798; }
.page-header h1 { margin: 0; font-size: 20px; color: var(--heading); }
.mock-badge { margin-left: auto; padding: 5px 8px; background: #fff2cc; color: #8c6b00; border: 1px solid #f0d889; border-radius: 999px; font-size: 11px; font-weight: 700; }
.subtabs {
display: flex;
gap: 20px;
padding: 0 22px 0 22px;
border-bottom: 1px solid var(--line);
margin: 0 10px 0;
}
.subtabs.embedded { padding: 0 0 12px; margin: 0 0 12px; }
.subtab {
position: relative;
padding: 12px 0;
font-size: 13px;
font-weight: 600;
color: #5f6e84;
}
.subtab.active { color: var(--accent-strong); }
.subtab.active::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: -1px;
height: 2px;
background: var(--accent-strong);
}
/* Dashboard-only rules keep administration and terminal layouts unchanged. */
body[data-current-path="/"] .content { padding: 20px 22px 30px; }
body[data-current-path="/"] .page-header { padding: 0; margin-bottom: 5px; }
body[data-current-path="/"] .page-kicker { display: none; }
body[data-current-path="/"] .page-header h1 { font-size: 25px; letter-spacing: -0.6px; color: #20334d; }
.dashboard { display: grid; gap: 18px; color: #475a73; font-size: 13px; }
.dashboard [hidden] { display: none !important; }
.dashboard-toolbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
.dashboard-toolbar > p { margin: 0; color: #63738a; line-height: 1.6; }
.dashboard-sync { display: flex; align-items: center; gap: 7px; font-size: 11px; color: #52647a; }
.dashboard-sync time { font-variant-numeric: tabular-nums; border-left: 1px solid #cdd6e1; padding-left: 8px; }
.dashboard-status-dot { display: inline-block; flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%; background: #96a3b3; }
.dashboard-sync[data-state="ready"] .dashboard-status-dot { background: #188562; }
.dashboard-sync[data-state="error"] { color: #a33333; }
.dashboard-sync[data-state="error"] .dashboard-status-dot { background: #be4545; }
.dashboard-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.dashboard-metric { min-width: 0; display: flex; flex-direction: column; align-items: stretch; padding: 17px 19px; background: #fff; border: 1px solid #dce4ef; border-radius: 12px; box-shadow: 0 3px 12px #20334d04; }
.dashboard-metric-label { display: flex; align-items: center; gap: 9px; }
.dashboard-metric-label h2 { margin: 0; font-size: 13px; font-weight: 600; }
.dashboard-metric-icon { display: inline-flex; align-items: center; justify-content: center; width: 33px; height: 29px; border-radius: 7px; color: #2863ab; background: #edf4ff; font-size: 9px; font-weight: 800; letter-spacing: .4px; }
.dashboard-metric[data-metric="memory"] .dashboard-metric-icon { background: #f0effd; color: #7053af; }
.dashboard-metric[data-metric="sessions"] .dashboard-metric-icon { background: #eaf6f3; color: #217b64; }
.dashboard-metric[data-metric="alarms"] .dashboard-metric-icon { background: #f2f4f8; color: #64748b; }
.dashboard-metric-value { margin: 9px 0 10px; font-size: 32px; font-weight: 700; line-height: 1.15; letter-spacing: -1px; color: #233a57; font-variant-numeric: tabular-nums; }
.dashboard-metric p { margin: 8px 0 0; font-size: 11px; color: #67768a; display: flex; flex-wrap: wrap; gap: 4px 8px; line-height: 1.6; }
.dashboard-metric p strong { color: #455970; font-weight: 600; font-variant-numeric: tabular-nums; }
.dashboard-metric .dashboard-metric-description { margin-top: auto; min-height: 25px; align-items: flex-end; }
.dashboard-metric[data-attention="true"] { border-color: #e4b9b9; background: #fffafa; }
.dashboard-metric[data-attention="true"] .dashboard-metric-value,
.dashboard-metric[data-attention="true"] .dashboard-metric-description { color: #ac3636; }
.dashboard-metric meter { display: block; appearance: none; width: 100%; height: 6px; border: 0; border-radius: 5px; background: #eaf0f7; overflow: hidden; }
.dashboard-metric meter::-webkit-meter-bar { background: #eaf0f7; border: 0; border-radius: 5px; height: 6px; }
.dashboard-metric meter::-webkit-meter-optimum-value { background: #4488d8; border-radius: 5px; }
.dashboard-metric meter::-moz-meter-bar { background: #4488d8; border-radius: 5px; }
.dashboard-metric[data-metric="memory"] meter::-webkit-meter-optimum-value { background: #8b75c5; }
.dashboard-metric[data-metric="memory"] meter::-moz-meter-bar { background: #8b75c5; }
.dashboard .panel { padding: 19px 20px; border-radius: 12px; border-color: #dce4ef; min-width: 0; box-shadow: 0 3px 12px #20334d03; }
.dashboard .panel-header { padding-bottom: 13px; margin-bottom: 15px; }
.dashboard .panel-header h2 { color: #283e59; font-size: 15px; }
.dashboard .panel-header p { color: #65758b; font-size: 11px; }
.dashboard-panel-heading { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dashboard-detail-link { color: #2968b4; font-size: 12px; font-weight: 600; flex-shrink: 0; }
.dashboard-detail-link span { margin-left: 5px; }
.dashboard a:focus-visible, .dashboard button:focus-visible { outline: 3px solid #397fce; outline-offset: 3px; }
.dashboard-port-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 17px; }
.dashboard-port-summary { display: flex; align-items: baseline; gap: 8px; color: #65758b; font-size: 12px; }
.dashboard-port-summary strong { font-size: 24px; font-weight: 700; color: #168061; font-variant-numeric: tabular-nums; }
.dashboard-filters { display: flex; flex-wrap: wrap; gap: 5px; }
.dashboard-filters button { display: flex; align-items: center; gap: 6px; padding: 7px 9px; background: #fff; border: 1px solid #e1e7ef; border-radius: 7px; color: #50627a; font-size: 11px; cursor: pointer; }
.dashboard-filters button:hover { background: #f3f7fc; border-color: #b8cce5; }
.dashboard-filters button[aria-pressed="true"] { color: #215eaa; background: #edf4ff; border-color: #8fb5e6; }
.dashboard-filters b { min-width: 13px; font-variant-numeric: tabular-nums; }
.dashboard [data-port-filter="up"] .dashboard-status-dot, .dashboard [data-port-state="up"] .dashboard-status-dot { background: #188562; }
.dashboard [data-port-filter="session"] .dashboard-status-dot, .dashboard [data-port-state="session"] .dashboard-status-dot { background: #397cce; }
.dashboard [data-port-filter="down"] .dashboard-status-dot, .dashboard [data-port-state="down"] .dashboard-status-dot { background: #bf4848; }
.dashboard .port-link-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 7px; }
.dashboard .port-link { display: flex; flex-direction: column; gap: 6px; padding: 9px 10px; border: 1px solid #e1e7ef; background: #f6f8fb; border-radius: 7px; text-align: left; min-width: 0; }
.dashboard .port-link:hover { border-color: #6897d1; box-shadow: 0 0 0 2px #4488d815; }
.dashboard-port-top { display: flex; align-items: center; justify-content: space-between; gap: 5px; }
.dashboard-port-alias { display: block; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11px; color: #50627a; }
.dashboard .port-link-number { font-size: 13px; font-variant-numeric: tabular-nums; color: #3b4f69; }
.dashboard .port-link-state { font-size: 10px; margin: 0; color: #6a788c; line-height: 1.3; overflow-wrap: anywhere; }
.dashboard .port-link[data-port-state="up"] { background: #ecf8f2; border-color: #8dc6af; }
.dashboard .port-link[data-port-state="up"] .port-link-state { color: #126d4e; font-weight: 700; }
.dashboard .port-link[data-port-state="session"] { background: #edf4ff; border-color: #94b6e3; }
.dashboard .port-link[data-port-state="session"] .port-link-state { color: #235faa; font-weight: 700; }
.dashboard .port-link[data-port-state="down"] { background: #fff1f1; border-color: #dfabab; }
.dashboard .port-link[data-port-state="down"] .port-link-state { color: #aa3535; font-weight: 700; }
.dashboard-port-note { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 6px 14px; color: #65758b; font-size: 11px; line-height: 1.6; padding-top: 13px; }
.dashboard-port-empty { padding: 25px 10px; text-align: center; color: #65758b; background: #f6f8fb; border-radius: 8px; }
.dashboard-details { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: 18px; }
.dashboard-section-tag { font-size: 9px; font-weight: 700; color: #667992; letter-spacing: 1.2px; }
.dashboard-interface { border: 1px solid #e1e8f1; border-radius: 8px; padding: 12px 14px; margin-bottom: 10px; background: #fbfcfe; }
.dashboard-interface-heading { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.dashboard-interface-heading strong { font-size: 12px; color: #465b77; }
.dashboard-network-badge { font-size: 10px; border-radius: 4px; padding: 3px 6px; background: #e9eef5; color: #586b84; }
.dashboard-network-badge[data-state="up"] { color: #146b4f; background: #e7f4ed; }
.dashboard-network-badge[data-state="down"] { color: #a33333; background: #fae8e8; }
.dashboard-interface-address { margin: 5px 0; color: #2a415f; font-size: 19px; letter-spacing: -.3px; font-weight: 600; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.dashboard-interface-meta { display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: #6b7d93; }
.dashboard-facts { margin: 0; }
.dashboard-facts > div { display: grid; grid-template-columns: minmax(100px, .85fr) minmax(0, 1.4fr); gap: 12px; padding: 9px 0; border-bottom: 1px solid #edf1f6; line-height: 1.5; }
.dashboard-facts > div:last-child { border-bottom: 0; }
.dashboard-facts dt { color: #65758b; font-size: 12px; }
.dashboard-facts dd { margin: 0; color: #344c6a; overflow-wrap: anywhere; font-size: 12px; font-variant-numeric: tabular-nums; }
.dashboard-network-meta { margin-top: 11px; }
.dashboard-traffic-totals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; border-bottom: 1px solid #e9eef5; padding-bottom: 18px; }
.dashboard-traffic-totals > div { display: flex; flex-direction: column; gap: 7px; }
.dashboard-traffic-totals span { font-size: 12px; color: #65758b; }
.dashboard-traffic-totals strong { font-size: 24px; font-weight: 650; color: #2a588f; font-variant-numeric: tabular-nums; }
.dashboard-traffic-totals > div:last-child strong { color: #59659b; }
.dashboard-traffic h3 { font-size: 12px; color: #536780; margin: 17px 0 14px; }
.dashboard-ranking { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; }
.dashboard-rank-heading { display: flex; align-items: center; gap: 10px; font-size: 12px; }
.dashboard-rank-heading a { color: #2968b4; font-weight: 600; }
.dashboard-rank-heading strong { margin-left: auto; font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 500; }
.dashboard-rank-number { width: 17px; height: 17px; display: grid; place-items: center; background: #edf3fa; border-radius: 4px; color: #617895; font-size: 10px; }
.dashboard-rank-track { margin: 7px 0 0 27px; background: #edf2f8; height: 5px; border-radius: 5px; overflow: hidden; }
.dashboard-rank-track span { display: block; height: 100%; background: #77a1d3; border-radius: inherit; }
.dashboard-footnote { margin: 19px 0 0; font-size: 11px; color: #65758b; line-height: 1.7; }
.dashboard-system { grid-column: 1 / -1; }
.dashboard-device { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.dashboard-device > strong { font-size: 18px; font-weight: 650; color: #2e4562; }
.dashboard-device > span { padding: 6px 10px; border-radius: 6px; background: #f2f6fb; font-size: 11px; }
.dashboard-device b { margin-left: 8px; font-weight: 500; color: #344c6a; }
.dashboard-system-facts { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 36px; }
.dashboard-placeholder { margin: 12px 0; color: #65758b; font-size: 12px; }
@media (min-width: 1600px) {
.dashboard-details { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr); }
.dashboard-system { grid-column: auto; }
.dashboard-system-facts { grid-template-columns: 1fr; }
}
@media (max-width: 1100px) {
.dashboard .port-link-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.dashboard-metric { padding: 14px; }
}
@media (max-width: 650px) {
body[data-current-path="/"] .content { padding: 16px 12px 24px; }
.dashboard-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.dashboard-details { grid-template-columns: 1fr; }
.dashboard-system-facts { grid-template-columns: 1fr; }
.dashboard .panel { padding: 16px 13px; }
.dashboard .port-link-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 5px; }
.dashboard .port-link { padding: 8px 6px; }
.dashboard-panel-heading { flex-wrap: wrap; }
.dashboard-metric-value { font-size: 28px; }
}
@media (max-width: 400px) {
.dashboard .port-link-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.blocks { display: grid; gap: 14px; padding: 0 10px; }
.panel {
background: var(--surface);
border: 1px solid var(--line);
border-radius: 4px;
padding: 14px 22px 20px;
}
.panel-header { padding-bottom: 12px; border-bottom: 1px solid #edf1f6; margin-bottom: 14px; }
.panel-header h2 { margin: 0; font-size: 14px; font-weight: 700; color: #5f6e84; }
.panel-header p { margin: 6px 0 0; font-size: 12px; color: #8996a8; }
.panel-header-actions { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.port-link-grid {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: 8px;
}
.port-link {
border: 1px solid #aeb7c4;
background: #f8fafc;
border-radius: 6px;
padding: 8px 4px;
text-align: center;
font-size: 11px;
}
.port-link.up { border-color: #6da884; background: #edf9f1; }
.port-link.down { border-color: #b7bec8; background: #f5f6f8; }
.port-link.session { border-color: #5b8fd9; background: #eef5ff; }
.port-link.signal { border-color: #d3a64f; background: #fff8e8; }
.port-link.error { border-color: #c86a6a; background: #fff1f1; }
.port-link.blink { box-shadow: 0 0 0 2px rgba(78,160,255,0.18); }
.port-link-card {
border: 1px solid #aeb7c4;
background: #f8fafc;
border-radius: 8px;
overflow: hidden;
}
.port-link-card.up { border-color: #6da884; background: #edf9f1; }
.port-link-card.down { border-color: #b7bec8; background: #f5f6f8; }
.port-link-card.session { border-color: #5b8fd9; background: #eef5ff; }
.port-link-card.signal { border-color: #d3a64f; background: #fff8e8; }
.port-link-card.error { border-color: #c86a6a; background: #fff1f1; }
.port-link-card.blink { box-shadow: 0 0 0 2px rgba(78,160,255,0.18); }
.port-link-card.active {
box-shadow: 0 0 0 2px rgba(63,151,247,0.32);
}
.port-link-view {
border: 0;
background: transparent;
padding: 8px 4px;
text-align: center;
font-size: 11px;
width: 100%;
cursor: pointer;
}
.port-link-view { min-height: 78px; display: grid; align-content: center; gap: 4px; }
.port-link-number { font-weight: 700; color: #44546a; }
.port-link-state { margin-top: 4px; color: #718197; }
.port-link-caption { font-size: 10px; color: #4f86d6; font-weight: 700; }
.port-link-apply {
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
box-sizing: border-box;
width: 100%;
border: 0;
border-top: 1px solid rgba(94, 112, 135, 0.16);
background: rgba(255,255,255,0.7);
color: #4c627d;
font-size: 11px;
font-weight: 700;
padding: 7px 4px;
cursor: pointer;
}
.port-link-apply.selected {
background: #3f97f7;
color: #fff;
}
.port-link-apply input[type="checkbox"] { width: 16px; height: 16px; margin: 0; flex: 0 0 16px; accent-color: #236dc7; cursor: pointer; }
.port-link-apply:focus-within { outline: 2px solid #236dc7; outline-offset: -2px; }
.port-link-apply span { white-space: nowrap; }
body[data-current-path^="/ports/"] .blocks {
grid-template-columns: clamp(510px, 34vw, 600px) minmax(0, 1fr);
column-gap: 18px;
align-items: stretch;
min-height: calc(100vh - 205px);
position: relative;
}
body[data-current-path^="/ports/"]:not([data-port-load-state="ready"]) .blocks > .panel {
visibility: hidden;
}
body[data-current-path^="/ports/"]:not([data-port-load-state="ready"]) .blocks::after {
position: absolute;
inset: 0;
z-index: 2;
display: grid;
place-items: center;
min-height: 360px;
border: 1px solid #dfe5ee;
border-radius: 4px;
background: #fff;
color: #66768d;
font-size: 14px;
content: "포트 설정과 상태를 불러오는 중입니다.";
}
body[data-current-path^="/ports/"][data-port-load-state="error"] .blocks::after {
border-color: #f1b8b8;
background: #fff7f7;
color: #ba3f3f;
content: "포트 정보를 불러오지 못했습니다. 잠시 후 새로고침하세요.";
}
body[data-current-path^="/ports/"] .port-selector-panel {
grid-column: 1;
padding: 11px 12px 13px;
height: 100%;
box-sizing: border-box;
}
body[data-current-path^="/ports/"] .form-panel {
grid-column: 2;
min-width: 0;
height: 100%;
box-sizing: border-box;
}
body[data-current-path^="/ports/"] .port-selector-panel .panel-header {
padding-bottom: 5px;
margin-bottom: 5px;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-grid {
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 7px;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-card {
border-radius: 5px;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-view {
min-height: 72px;
grid-template-columns: minmax(0, 1fr);
padding: 8px 4px;
gap: 3px;
font-size: 12px;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-number {
font-size: 14px;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-state {
margin-top: 0;
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-caption {
display: none;
}
body[data-current-path^="/ports/"] .port-link-alias {
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 11px;
color: #60738d;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-apply {
min-height: 34px;
padding: 7px 3px;
font-size: 11px;
}
body[data-current-path^="/ports/"] .form-panel .form-grid {
grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 360px));
}
body[data-current-path^="/ports/"] .form-panel .mock-form {
gap: 10px;
}
.kv-table { display: grid; }
.kv-row {
display: grid;
grid-template-columns: 240px 1fr;
min-height: 44px;
align-items: center;
border-bottom: 1px solid #eef2f6;
}
.kv-row:last-child { border-bottom: 0; }
.kv-key { color: #67778d; }
.kv-value { color: #4b5c73; }
.mock-form { display: grid; gap: 14px; }
.form-grid {
display: grid;
grid-template-columns: 360px;
gap: 14px 24px;
}
.compact-grid { grid-template-columns: repeat(2, minmax(240px, 360px)); }
.form-row { display: grid; gap: 7px; }
.form-row label { font-size: 13px; color: #6b7b91; }
.required { color: #ef7e7e; }
.form-row input[type="text"],
.form-row input[type="password"],
.form-row input[type="number"],
.form-row select,
.form-row textarea {
width: 100%;
min-height: 32px;
border: 1px solid #d9e0ea;
border-radius: 4px;
background: #fff;
padding: 6px 10px;
color: #607188;
}
.form-row textarea { resize: vertical; min-height: 110px; }
.field-hint { font-size: 11px; color: #97a4b3; }
.form-fixed {
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.form-fixed label {
color: inherit;
font-weight: 600;
}
.form-fixed input[type="text"]:disabled {
border-color: #d9e0ea;
background: #f6f7f9;
color: #607188;
opacity: 1;
cursor: not-allowed;
}
.fixed-value-badge {
display: inline-flex;
align-items: center;
margin-left: 5px;
padding: 2px 6px;
border-radius: 999px;
background: #d9e8f8;
color: #376897;
font-size: 10px;
font-weight: 700;
line-height: 1;
}
[hidden] { display: none !important; }
.network-mode-context,
.network-ipv6-disclosure,
.operating-mode-context {
grid-column: 1 / -1;
width: 720px;
max-width: 100%;
box-sizing: border-box;
}
body[data-current-path^="/network/interface-"] .form-panel .form-grid {
grid-template-columns: minmax(0, 780px);
}
body[data-current-path^="/network/interface-"] .network-mode-context { width: 780px; }
.network-interface-columns {
grid-column: 1 / -1;
display: grid;
grid-template-columns: repeat(2, minmax(0, 360px));
gap: 24px;
width: 780px;
max-width: 100%;
box-sizing: border-box;
}
.network-interface-column {
display: grid;
align-content: start;
gap: 14px;
width: 100%;
min-width: 0;
}
.network-interface-column > .form-row,
.network-interface-column > .network-ipv6-disclosure {
width: 100%;
min-width: 0;
}
.network-interface-column .form-row input,
.network-interface-column .form-row select,
.network-interface-column .form-row textarea {
max-width: 100%;
}
.network-interface-column.ipv6-column {
padding-left: 16px;
border-left: 2px solid transparent;
transition: border-color 160ms ease;
}
.network-interface-columns.ipv6-open .ipv6-column {
border-left-color: #8ab9ef;
background: none;
}
.network-mode-context {
display: grid;
gap: 4px;
padding: 11px 13px;
border: 1px solid #dce5ef;
border-left: 3px solid #6aa7ef;
border-radius: 4px;
background: #f7faff;
color: #53677f;
}
.network-mode-context strong { font-size: 13px; color: #40556f; }
.network-mode-context span { font-size: 12px; }
.network-mode-context[data-mode="oob"] { border-left-color: #e1a94a; background: #fffbf2; }
.network-ipv6-disclosure {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-top: 2px;
padding: 11px 13px;
border: 1px dashed #cfd9e6;
border-radius: 4px;
background: #fafbfd;
}
.network-ipv6-disclosure > div { display: grid; gap: 3px; }
.network-ipv6-disclosure strong { color: #50647c; font-size: 13px; }
.network-ipv6-disclosure span { color: #8a98a9; font-size: 11px; }
.btn.compact { padding: 6px 11px; white-space: nowrap; }
.operating-mode-context {
display: grid;
gap: 9px;
padding: 14px;
border: 1px solid #dce5ef;
border-radius: 4px;
background: #f8fbff;
}
.operating-mode-context > strong { color: #40556f; font-size: 14px; }
.operating-mode-context > p { margin: 0; color: #697b90; font-size: 12px; line-height: 1.55; }
.operating-mode-context[data-mode="oob"] { border-color: #efd69d; background: #fffbf2; }
.operating-mode-roles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.operating-mode-roles > div {
display: grid;
gap: 3px;
padding: 10px 11px;
border: 1px solid #dfe6ef;
border-radius: 4px;
background: #fff;
}
.operating-mode-roles strong { color: #4c6078; font-size: 12px; }
.operating-mode-roles span { color: #7c8b9d; font-size: 11px; }
.oob-runtime-summary {
padding: 8px 10px;
border-radius: 3px;
background: #eef4fb;
color: #58708a;
font-size: 11px;
}
.oob-runtime-summary[data-fallback-active="true"] { background: #fff0d5; color: #966915; }
.switch { position: relative; width: 34px; height: 18px; display: inline-flex; }
.switch input { display: none; }
.slider {
width: 34px;
height: 18px;
border-radius: 999px;
background: #d8dee8;
position: relative;
}
.slider::after {
content: "";
position: absolute;
top: 2px;
left: 2px;
width: 14px;
height: 14px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.14);
}
.switch input:checked + .slider { background: #72b1ff; }
.switch input:checked + .slider::after { transform: translateX(16px); }
.target-grid-wrap { border-top: 1px solid #edf1f6; padding-top: 10px; }
.target-title { margin-bottom: 10px; font-size: 13px; color: #67778d; font-weight: 600; }
.target-grid {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 10px;
}
.target-chip {
position: relative;
display: grid;
gap: 4px;
min-height: 72px;
padding: 12px 8px;
border: 1px solid #b8c2cf;
border-radius: 10px;
background: #f8fafc;
color: #5f6e84;
text-align: center;
cursor: pointer;
transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.target-chip:hover {
transform: translateY(-1px);
border-color: #7bb0f5;
}
.target-chip input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.target-chip.selected {
border-color: #6da884;
background: #edf9f1;
box-shadow: 0 0 0 2px rgba(78,160,255,0.16);
}
.target-chip-number {
font-size: 13px;
font-weight: 700;
color: #44546a;
}
.target-chip-state {
font-size: 11px;
color: #718197;
}
.panel-actions { display: flex; gap: 12px; align-items: center; }
.panel-actions.compact { margin-bottom: 0; }
.modal-form .panel-actions,
.group-modal .panel-actions {
margin-top: 18px;
}
.btn {
border: 1px solid transparent;
border-radius: 3px;
padding: 8px 18px;
font-size: 12px;
cursor: pointer;
}
.btn.primary { background: var(--accent-strong); color: #fff; }
.btn.secondary { background: #fff; border-color: #d7dee9; color: #6b7c91; }
.btn.danger { background: var(--danger); color: #fff; }
.btn:disabled { cursor: not-allowed; opacity: 0.55; }
.note-list { display: grid; gap: 6px; }
.firmware-status {
margin-top: 14px;
padding: 12px 14px;
border: 1px solid #cbd5e1;
border-radius: 4px;
background: #f8fafc;
color: #334155;
}
.firmware-status.is-success {
border-color: #86c89c;
background: #edf8f0;
color: #176b37;
}
.firmware-status progress { display: block; width: 100%; margin-top: 12px; height: 16px; }
.firmware-status progress[hidden] { display: none; }
.firmware-status p { margin: 10px 0 0; line-height: 1.6; overflow-wrap: anywhere; }
.firmware-status a { display: inline-block; margin-top: 10px; }
.firmware-status a[hidden] { display: none; }
.firmware-status.is-error {
border-color: #ef9a9a;
background: #fff1f1;
color: #b42318;
}
.note-item { font-size: 12px; color: #8a97a6; }
.table-wrap { overflow-x: auto; }
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table th, .data-table td { padding: 12px 14px; border-bottom: 1px solid #eef2f6; text-align: left; color: #5e7087; }
.data-table th { background: #f3f6fa; font-weight: 700; color: #6d7d94; }
body[data-current-path="/port-status"] .blocks { justify-items: stretch; }
body[data-current-path="/port-status"] .panel { width: 100%; min-width: 0; }
body[data-current-path="/port-status"] .table-wrap { max-height: 65vh; }
body[data-current-path="/port-status"] .data-table { table-layout: fixed; min-width: 1040px; }
body[data-current-path="/port-status"] .data-table th,
body[data-current-path="/port-status"] .data-table td { padding: 9px 8px; overflow-wrap: anywhere; }
body[data-current-path="/port-status"] .data-table th { position: sticky; top: 0; z-index: 1; background: #f3f6fa; white-space: nowrap; }
body[data-current-path="/port-status"] .data-table th:nth-child(1) { width: 6%; }
body[data-current-path="/port-status"] .data-table th:nth-child(2) { width: 9%; }
body[data-current-path="/port-status"] .data-table th:nth-child(3) { width: 15%; }
body[data-current-path="/port-status"] .data-table th:nth-child(4) { width: 10%; }
body[data-current-path="/port-status"] .data-table th:nth-child(5) { width: 5%; }
body[data-current-path="/port-status"] .data-table th:nth-child(n+6) { width: 11%; }
body[data-current-path="/port-status"] .data-table td:nth-child(3) { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.port-status-badge {
display: inline-flex;
align-items: center;
gap: 5px;
min-width: 66px;
padding: 2px 8px;
border: 1px solid #d9dee5;
border-radius: 999px;
background: #f7f8fa;
color: #687587;
font-size: 12px;
line-height: 1.25;
white-space: nowrap;
}
.port-status-dot {
width: 8px;
height: 8px;
flex: 0 0 8px;
border-radius: 50%;
background: #9aa1a9;
}
.port-status-badge.up {
border-color: #add9bc;
background: #edf9f1;
color: #247b43;
}
.port-status-badge.up .port-status-dot { background: #35a85b; }
.port-status-badge.down {
border-color: #efb5b5;
background: #fff1f1;
color: #bf3f3f;
}
.port-status-badge.down .port-status-dot { background: #df4a4a; }
.port-status-badge.session {
border-color: #a9c7ef;
background: #eef5ff;
color: #2b66ad;
}
.port-status-badge.session .port-status-dot { background: #3f8de0; }
.port-status-badge.unknown .port-status-dot { background: #9aa1a9; }
.row-actions { white-space: nowrap; }
.link-action { border: 0; background: transparent; padding: 0 2px; font-size: 12px; cursor: pointer; }
.link-action.primary { color: var(--accent-strong); }
.link-action.secondary { color: #61748d; }
.link-action.danger { color: var(--danger); }
.user-row-actions {
vertical-align: middle;
}
.user-row-actions > * + * {
margin-inline-start: 10px;
}
.account-status-badge,
.password-state-badge,
.system-group-label {
display: inline-flex;
align-items: center;
gap: 5px;
min-height: 22px;
padding: 2px 8px;
border: 1px solid #d8dee7;
border-radius: 999px;
background: #f7f8fa;
color: #66758a;
font-size: 11px;
line-height: 1.2;
white-space: nowrap;
}
.account-status-dot {
width: 7px;
height: 7px;
flex: 0 0 7px;
border-radius: 50%;
background: #98a2b1;
}
.account-status-badge.enabled {
border-color: #acd9bb;
background: #edf9f1;
color: #247b43;
}
.account-status-badge.enabled .account-status-dot { background: #35a85b; }
.account-status-badge.disabled {
border-color: #efb6b6;
background: #fff1f1;
color: #bf3f3f;
}
.account-status-badge.disabled .account-status-dot { background: #df4a4a; }
.password-state-badge.required {
border-color: #efd39b;
background: #fff8e8;
color: #9a6a10;
}
.password-state-badge.normal {
border-color: #cfd9e6;
background: #f6f8fb;
color: #60728a;
}
.system-group-label {
border-color: #cfd9e6;
background: #f3f6fa;
color: #61748d;
}
.empty-state { text-align: center; color: #98a5b3; }
body[data-current-path^="/logs/"] .blocks { gap: 10px; }
body[data-current-path^="/logs/"] .form-panel { padding: 14px 18px; }
body[data-current-path^="/logs/"] .form-panel .panel-header {
padding-bottom: 8px;
margin-bottom: 10px;
}
body[data-current-path^="/logs/"] .form-panel .form-grid {
grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
gap: 10px 14px;
}
body[data-current-path^="/settings/system-log/"] .form-panel .form-grid {
grid-template-columns: repeat(2, minmax(260px, 420px));
max-width: 880px;
}
body[data-current-path="/settings/system-log/remote"] .form-panel .form-grid {
grid-template-columns: minmax(300px, 520px);
}
body[data-current-path^="/logs/"] .form-panel .mock-form { gap: 12px; }
body[data-current-path^="/logs/"] .form-panel .panel-actions { justify-content: flex-end; }
body[data-current-path^="/logs/"] .table-wrap {
max-height: calc(100vh - 430px);
min-height: 240px;
overflow: auto;
}
body[data-current-path^="/logs/"] .data-table th {
position: sticky;
top: 0;
z-index: 1;
}
body[data-current-path^="/logs/"] .data-table th:not(:last-child),
body[data-current-path^="/logs/"] .data-table td:not(:last-child) { white-space: nowrap; }
body[data-current-path^="/logs/"] .data-table td:last-child {
min-width: 300px;
overflow-wrap: anywhere;
}
.log-type-tabs {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 14px;
border-bottom: 1px solid #e8edf4;
background: #fbfcfe;
}
.log-type-tabs > strong {
margin-right: 6px;
color: #566a83;
font-size: 12px;
}
.log-type-tab {
min-width: 62px;
padding: 6px 12px;
border: 1px solid #d6dfeb;
border-radius: 999px;
background: #fff;
color: #6c7e94;
font-size: 11px;
cursor: pointer;
}
.log-type-tab:hover { border-color: #8eb9ed; color: #3979c8; }
.log-type-tab.active {
border-color: #4e9cf4;
background: #eaf4ff;
color: #2469b8;
font-weight: 700;
}
.log-live-status {
display: inline-flex;
align-items: center;
min-height: 24px;
padding: 3px 9px;
border-radius: 999px;
background: #edf3fa;
color: #60738b;
font-size: 11px;
white-space: nowrap;
}
.log-live-status.loading { background: #fff6df; color: #9a711d; }
.log-live-status.success { background: #e9f7ee; color: #287a49; }
.log-live-status.error { background: #fff0f0; color: #b64949; }
.log-clock-banner {
margin: 12px 14px 0;
padding: 9px 12px;
border: 1px solid #d9e3ee;
border-radius: 4px;
background: #f6f8fb;
color: #536980;
font-size: 11px;
line-height: 1.45;
}
.log-clock-banner.success { border-color: #b9dfc8; background: #eef9f2; color: #287a49; }
.log-clock-banner.warning { border-color: #ecd69d; background: #fff8e8; color: #916b1c; }
.log-severity-info { color: #287a49 !important; font-weight: 700; }
.log-severity-warning { color: #a76f12 !important; font-weight: 700; }
.log-severity-critical { color: #c54444 !important; font-weight: 700; }
.log-direction-rx { color: #287a49 !important; font-weight: 700; }
.log-direction-tx { color: #3979c8 !important; font-weight: 700; }
.log-state-up { color: #287a49 !important; font-weight: 700; }
.log-state-down { color: #c54444 !important; font-weight: 700; }
.log-state-unknown { color: #7f8b99 !important; font-weight: 700; }
/* Log explorer: compact filters, readable rows and preserved original messages. */
body[data-current-path^="/logs/"] .content { padding: 14px 16px 24px; }
body[data-current-path^="/logs/"] .blocks { gap: 12px; }
body[data-current-path^="/logs/"] .panel { border-radius: 10px; }
.log-overview { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 22px; padding: 12px 18px; border: 1px solid #dbe5f1; border-radius: 10px; background: #f8fbff; color: #52677f; }
.log-overview-total { display: flex; align-items: baseline; gap: 7px; font-size: 12px; }
.log-overview-total strong { font-size: 24px; line-height: 1; font-weight: 700; color: #244e7d; font-variant-numeric: tabular-nums; }
.log-overview-breakdown { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.log-overview-scope { margin-left: auto; font-size: 11px; color: #65758b; }
.log-badge { display: inline-flex; align-items: center; gap: 7px; padding: 4px 8px; border-radius: 5px; background: #edf1f6; color: #516379; font-size: 11px; font-weight: 600; line-height: 1.4; white-space: nowrap; }
.log-badge strong { font-variant-numeric: tabular-nums; font-size: 12px; }
.log-badge[data-tone="info"], .log-badge[data-tone="tx"] { background: #eaf2ff; color: #245f9d; }
.log-badge[data-tone="warning"] { background: #fff3d6; color: #865500; }
.log-badge[data-tone="critical"], .log-badge[data-tone="down"], .log-badge[data-tone="error"] { background: #ffecec; color: #ad3232; }
.log-badge[data-tone="rx"], .log-badge[data-tone="up"], .log-badge[data-tone="connected"] { background: #e6f5ee; color: #176948; }
.log-badge[data-tone="session"] { background: #f0ebfa; color: #6b4b9a; }
body[data-current-path^="/logs/"] .log-filter-panel { padding: 12px 18px; }
body[data-current-path^="/logs/"] .log-filter-panel .panel-header { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; padding-bottom: 0; border: 0; margin-bottom: 12px; }
.log-filter-panel .panel-header h2 { color: #354d69; font-size: 13px; }
.log-filter-panel .panel-header p { margin: 0; color: #65758b; font-size: 11px; line-height: 1.5; }
body[data-current-path^="/logs/"] .log-filter-panel .mock-form { gap: 10px; }
.log-filter-line { display: flex; align-items: flex-end; gap: 16px; }
body[data-current-path^="/logs/"] .log-filter-panel .form-grid { flex: 1; width: auto; max-width: none; grid-template-columns: minmax(90px, .8fr) minmax(180px, 2.6fr) minmax(90px, .8fr); gap: 12px; }
body[data-current-path="/logs/ports"] .log-filter-panel .form-grid,
body[data-current-path="/logs/links"] .log-filter-panel .form-grid { grid-template-columns: minmax(90px, 1fr) minmax(80px, .8fr) minmax(180px, 2fr) minmax(85px, .8fr); }
.log-filter-panel .form-row { min-width: 0; gap: 5px; }
.log-filter-panel .form-row[hidden] { display: none; }
.log-filter-panel .form-row > label { font-size: 11px; color: #52677f; }
.log-filter-panel input[type="text"], .log-filter-panel input[type="datetime-local"], .log-filter-panel select { box-sizing: border-box; width: 100%; min-width: 0; height: 35px; padding: 7px 9px; border: 1px solid #cfdbe9; border-radius: 6px; background: #fff; color: #344c6a; font-family: inherit; font-size: 12px; }
.log-filter-panel .panel-actions { flex-shrink: 0; gap: 7px; }
.log-filter-panel .btn, .log-result-panel .btn { border-radius: 6px; padding: 8px 12px; font-size: 12px; min-height: 34px; }
.log-filter-footer { position: relative; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.log-advanced { flex: 1; min-width: 0; }
.log-advanced > summary { cursor: pointer; color: #376496; font-size: 11px; padding: 5px 0; width: fit-content; }
.log-advanced-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding-top: 12px; }
.log-search-note { color: #65758b; font-size: 11px; margin: 10px 0 0; }
.log-advanced .note-list { margin-top: 10px; }
.log-filter-panel .log-auto-refresh { display: flex; flex-direction: row-reverse; align-items: center; flex-shrink: 0; gap: 7px; padding: 3px 0; }
.log-auto-refresh .switch { margin: 0; }
body[data-current-path^="/logs/"] .log-result-panel { padding: 0; overflow: hidden; }
.log-result-panel .panel-header { margin: 0; padding: 13px 18px; }
.log-result-panel .panel-header h2 { color: #354d69; }
.log-result-panel .panel-header p { color: #65758b; font-size: 11px; }
.log-result-panel .panel-actions { gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
.log-result-panel .panel-header-actions { flex-wrap: wrap; }
.log-result-panel .port-log-clear { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; width: 100%; box-sizing: border-box; margin-top: 12px; padding: 12px 14px; background: #fafbfe; border: 1px solid #dfe6ef; border-radius: 8px; }
.port-log-clear-copy { flex: 1 1 360px; min-width: 0; }
.port-log-clear-target { display: block; color: #425873; font-size: 12px; line-height: 1.6; }
.log-result-panel .port-log-clear p { margin: 5px 0 0; line-height: 1.6; overflow-wrap: anywhere; }
.port-log-clear .btn { flex-shrink: 0; }
.port-log-clear[data-ready="true"] { border-color: #e9c6c6; background: #fffafa; }
.port-log-clear[data-ready="true"] .port-log-clear-target { color: #a33d3d; }
.log-result-panel .log-type-tabs { padding: 8px 18px; gap: 5px; overflow-x: auto; }
.log-result-panel .log-type-tab { min-width: 54px; padding: 5px 10px; border-radius: 5px; }
body[data-current-path^="/logs/"] .log-result-panel .table-wrap { max-height: max(280px, calc(100vh - 450px)); min-height: 220px; scrollbar-gutter: stable; }
.log-result-panel .data-table { table-layout: fixed; min-width: 840px; }
.log-result-panel .data-table th { background: #f0f4f9; color: #52677f; font-size: 11px; padding: 11px 12px; box-shadow: inset 0 -1px #e0e8f1; }
.log-result-panel .data-table th:first-child { width: 113px; }
.log-result-panel[data-log-kind="system"] th:nth-child(2) { width: 76px; }
.log-result-panel[data-log-kind="system"] th:nth-child(3) { width: 84px; }
.log-result-panel[data-log-kind="system"] th:nth-child(4) { width: 118px; }
.log-result-panel:not([data-log-kind="system"]) .data-table { min-width: 890px; }
.log-result-panel:not([data-log-kind="system"]) th:nth-child(2) { width: 160px; }
.log-result-panel:not([data-log-kind="system"]) th:nth-child(3) { width: 84px; }
.log-result-panel:not([data-log-kind="system"]) th:nth-child(4) { width: 114px; }
.log-result-panel:not([data-log-kind="system"]) th:nth-child(5) { width: 92px; }
.log-result-panel[data-log-kind="link"] th:nth-child(3) { width: 96px; }
.log-result-panel[data-log-kind="link"] th:nth-child(4) { width: 190px; }
.log-result-panel .data-table td { padding: 11px 12px; vertical-align: top; color: #3f536b; font-size: 12px; line-height: 1.6; border-bottom: 1px solid #eaf0f6; }
body[data-current-path^="/logs/"] .log-result-panel .data-table td:not(:last-child) { white-space: normal; overflow-wrap: anywhere; }
.log-event-row:hover, .log-event-row:focus-within { background: #f8fbff; }
.log-event-row[data-tone="critical"] .log-time-cell { box-shadow: inset 3px 0 #d45b5b; }
.log-event-row[data-tone="warning"] .log-time-cell { box-shadow: inset 3px 0 #e2ad46; }
.log-time-cell time { display: block; font-size: 13px; color: #344c6a; font-weight: 600; font-variant-numeric: tabular-nums; }
.log-date { display: block; color: #728199; font-size: 10px; font-variant-numeric: tabular-nums; }
.log-time-unset { display: block; color: #90631a; font-size: 10px; }
.log-channel { display: inline-block; color: #365e8c; font-family: ui-monospace, Consolas, monospace; font-weight: 600; }
.log-source { color: #60738b; font-size: 11px; }
.log-message-details > summary { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; list-style: none; }
.log-message-details > summary::-webkit-details-marker { display: none; }
.log-message-preview { flex: 1; min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; white-space: pre-line; }
.log-message-details[open] .log-message-preview { display: block; }
.log-detail-hint { flex-shrink: 0; font-size: 10px; color: #4776aa; padding: 1px 0; }
.log-detail-hint::after { content: " +"; }
.log-message-details[open] .log-detail-hint::after { content: " −"; }
.log-event-detail { margin-top: 12px; padding: 12px; border: 1px solid #dae5f1; border-radius: 7px; background: #f3f7fc; }
.log-event-metadata { margin: 0; display: grid; gap: 5px; }
.log-event-metadata > div { display: grid; grid-template-columns: 75px minmax(0, 1fr); gap: 8px; }
.log-event-metadata dt { color: #687b94; font-size: 10px; }
.log-event-metadata dd { margin: 0; font-size: 11px; overflow-wrap: anywhere; }
.log-event-detail h3 { margin: 10px 0 5px; color: #5b708b; font-size: 10px; font-weight: 600; }
.log-event-detail pre { margin: 0; padding: 10px; background: #fff; border: 1px solid #e1e8f1; border-radius: 5px; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 260px; overflow: auto; color: #344c6a; font: 11px/1.65 ui-monospace, Consolas, monospace; }
.log-event-detail > .log-badge { margin-top: 8px; }
.log-result-panel mark { background: #ffedac; color: inherit; border-radius: 2px; }
.log-result-feedback { margin: 0; padding: 9px 18px; color: #5c7290; background: #f0f5fc; font-size: 11px; line-height: 1.5; }
.log-result-feedback[data-tone="error"] { color: #a13a3a; background: #fff0f0; }
.log-result-feedback[hidden] { display: none; }
.log-result-footer { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 18px; padding: 10px 18px; border-top: 1px solid #e2e9f2; color: #65758b; background: #fcfdff; font-size: 10px; }
.log-result-footer .log-clock-banner { flex-basis: 100%; border: 0; border-radius: 0; padding: 0; margin: 0; background: none; color: #65758b; font-size: 10px; }
.log-result-footer .log-clock-banner.warning { color: #8b6219; background: #fff5df; padding: 7px 9px; border-radius: 4px; }
.log-updated { display: inline-flex; gap: 7px; font-variant-numeric: tabular-nums; }
.log-live-status.paused { color: #5a6b83; background: #edf1f6; }
.log-result-panel .log-empty-state { padding: 45px 18px; text-align: center; }
.log-empty-state strong { font-size: 13px; color: #4e647f; }
.log-empty-state p { font-size: 11px; color: #6f8098; margin: 8px 0 0; }
.log-filter-panel :is(input, select, button, summary):focus-visible, .log-result-panel :is(button, summary):focus-visible { outline: 2px solid #377ccc; outline-offset: 3px; }
@media (max-width: 1100px) {
.log-filter-line { flex-wrap: wrap; gap: 10px; }
.log-filter-line .panel-actions { margin-left: auto; }
.log-overview-scope { flex-basis: 100%; margin-left: 0; }
.log-advanced-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
body[data-current-path^="/logs/"] .content { padding: 12px 4px 20px; }
body[data-current-path^="/logs/"] .log-filter-panel .form-grid { flex-basis: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.log-keyword-field { grid-column: 1 / -1; }
.log-overview { gap: 10px; padding: 12px; }
.log-advanced-grid { grid-template-columns: minmax(0, 1fr); }
.log-filter-footer { flex-wrap: wrap; }
.log-advanced { flex-basis: 100%; }
.log-result-panel .panel-header-actions { flex-wrap: wrap; }
.log-result-panel .panel-actions { justify-content: flex-start; }
}
.action-panel .action-copy { margin-bottom: 16px; font-size: 13px; color: #6b7b90; }
body[data-current-path="/tools/nettest/ping"] .mock-form .form-grid {
grid-template-columns: repeat(2, minmax(260px, 360px));
width: min(744px, 100%);
}
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(1) {
grid-column: 1;
grid-row: 1;
}
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(2) {
grid-column: 1;
grid-row: 2;
}
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(3) {
grid-column: 2;
grid-row: 1;
}
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(4) {
grid-column: 2;
grid-row: 2;
}
body[data-current-path="/tools/alias"] .mock-form .form-grid {
grid-template-columns: repeat(2, minmax(260px, 360px));
width: min(744px, 100%);
}
.diagnostic-console {
margin-top: 14px;
overflow: hidden;
border: 1px solid #202b3a;
border-radius: 5px;
background: #070b11;
box-shadow: 0 8px 24px rgba(18, 26, 38, 0.1);
}
.diagnostic-console-titlebar {
display: grid;
grid-template-columns: 42px 1fr auto;
align-items: center;
min-height: 36px;
padding: 0 13px;
border-bottom: 1px solid #253142;
background: #111820;
color: #aebccc;
font: 11px/1 Consolas, "Courier New", monospace;
}
.diagnostic-console-titlebar > span:first-child { color: #7ee787; font-weight: 700; }
.diagnostic-console-titlebar strong { color: #d8e0ea; font-weight: 600; }
.diagnostic-console-titlebar > span:last-child { color: #738398; }
.result-box {
height: 250px;
min-height: 250px;
max-height: 250px;
margin: 0;
overflow: auto;
border: 0;
border-radius: 0;
background: #070b11;
padding: 15px 16px;
white-space: pre-wrap;
overflow-wrap: anywhere;
color: #d7e0e9;
scrollbar-color: #46566b #0a1018;
scrollbar-width: thin;
font: 13px/1.5 Consolas, "Courier New", monospace;
}
.result-box[data-state="running"] { color: #e7d38a; }
.result-box[data-state="succeeded"] { color: #d7e0e9; }
.result-box[data-state="failed"] { color: #ff9b9b; }
.serial-console {
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
border: 1px solid #202b3a;
border-radius: 5px;
background: #111827;
box-shadow: 0 10px 30px rgba(18, 26, 38, 0.12);
}
.serial-console-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 12px 16px;
border-bottom: 1px solid #344155;
background: #1e293b;
color: #e5edf7;
}
.serial-console-heading {
display: flex;
align-items: center;
gap: 12px;
min-width: 240px;
}
.serial-console-heading h2 {
margin: 0;
font-size: 14px;
color: #f8fafc;
}
.serial-console-heading p {
margin: 3px 0 0;
font-size: 11px;
color: #9fb0c5;
}
.serial-console-controls {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
flex-wrap: wrap;
}
.serial-console-controls label {
color: #b7c5d7;
font-size: 12px;
font-weight: 700;
}
.serial-console-controls select {
min-width: 150px;
height: 32px;
border: 1px solid #4b5c72;
border-radius: 3px;
background: #111827;
color: #f1f5f9;
padding: 0 28px 0 10px;
font-size: 12px;
}
.serial-console-controls select option:disabled { color: #758296; }
.terminal-button {
height: 32px;
border: 1px solid #4c5e75;
border-radius: 3px;
background: #2c3a4e;
color: #e6edf6;
padding: 0 12px;
font-size: 11px;
font-weight: 700;
cursor: pointer;
}
.terminal-button:hover { background: #394a61; }
.terminal-button.connect {
border-color: #218c52;
background: #19713f;
color: #fff;
}
.terminal-button.disconnect {
border-color: #a54343;
background: #833838;
color: #fff;
}
.terminal-button:disabled {
cursor: not-allowed;
opacity: 0.45;
}
.terminal-window {
display: flex;
flex: 0 0 560px;
height: 560px;
min-height: 560px;
max-height: 560px;
flex-direction: column;
background: #070b11;
}
.terminal-helpbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 38px;
padding: 0 12px;
border-bottom: 1px solid #283548;
background: #0f1724;
color: #aebdce;
}
.terminal-help-message {
overflow: hidden;
font-size: 11px;
line-height: 1.35;
text-overflow: ellipsis;
white-space: nowrap;
}
.terminal-advanced-toggle {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
gap: 6px;
height: 28px;
border: 1px solid #435269;
border-radius: 3px;
background: #172235;
color: #d8e2ef;
padding: 0 10px;
font-size: 11px;
font-weight: 700;
cursor: pointer;
}
.terminal-advanced-toggle::after {
content: "▾";
transition: transform 0.15s ease;
}
.terminal-advanced-toggle[aria-expanded="true"]::after { transform: rotate(180deg); }
.terminal-advanced-toggle:hover { background: #223149; }
.terminal-batch-toolbar {
display: flex;
align-items: end;
gap: 8px;
flex-wrap: wrap;
padding: 8px 12px;
border-bottom: 1px solid #283548;
background: #0f1724;
color: #afbdd0;
}
.terminal-batch-toolbar[hidden] { display: none; }
.terminal-batch-toolbar label {
display: grid;
gap: 3px;
font-size: 10px;
font-weight: 700;
}
.terminal-batch-toolbar select,
.terminal-batch-toolbar input {
height: 30px;
border: 1px solid #435269;
border-radius: 3px;
background: #172235;
color: #f1f5f9;
padding: 0 8px;
font: 12px/1 Consolas, "Courier New", monospace;
}
.terminal-batch-value { flex: 1 1 260px; }
.terminal-batch-value input { width: 100%; }
.terminal-log-state {
align-self: center;
min-width: 72px;
color: #7ee787;
font: 11px/1.2 Consolas, "Courier New", monospace;
text-align: right;
}
.terminal-titlebar {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 34px;
padding: 0 14px;
border-bottom: 1px solid #253142;
background: #111820;
color: #d8e0ea;
font: 12px/1 Consolas, "Courier New", monospace;
}
.terminal-connection-state {
display: inline-flex;
align-items: center;
gap: 6px;
color: #98a6b8;
font: 11px/1.2 Arial, sans-serif;
}
.terminal-state-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #718096;
box-shadow: 0 0 0 2px rgba(113, 128, 150, 0.16);
}
.terminal-connection-state[data-state="connecting"] { color: #e7b75e; }
.terminal-connection-state[data-state="connecting"] .terminal-state-dot { background: #e7b75e; }
.terminal-connection-state[data-state="ready"] { color: #66d38b; }
.terminal-connection-state[data-state="ready"] .terminal-state-dot {
background: #42c978;
box-shadow: 0 0 8px rgba(66, 201, 120, 0.45);
}
.terminal-connection-state[data-state="connected"] { color: #66d38b; }
.terminal-connection-state[data-state="connected"] .terminal-state-dot {
background: #42c978;
box-shadow: 0 0 8px rgba(66, 201, 120, 0.62);
}
.terminal-connection-state[data-state="error"] { color: #f07777; }
.terminal-connection-state[data-state="error"] .terminal-state-dot { background: #e25555; }
.terminal-connection-state[data-state="unavailable"] { color: #f07777; }
.terminal-connection-state[data-state="unavailable"] .terminal-state-dot { background: #e25555; }
.terminal-screen {
display: block;
flex: 1;
min-height: 0;
overflow-x: auto;
overflow-y: scroll;
padding: 16px;
background: #070b11;
cursor: text;
user-select: text;
scrollbar-color: #46566b #0a1018;
scrollbar-width: thin;
outline: none;
}
.terminal-output {
display: inline;
margin: 0;
padding: 0;
overflow: visible;
background: transparent;
color: #d7e0e9;
white-space: pre-wrap;
overflow-wrap: anywhere;
tab-size: 4;
font: 13px/1.48 Consolas, "Courier New", monospace;
}
.terminal-command-line {
display: inline;
align-items: baseline;
min-height: 20px;
margin: 0;
background: transparent;
}
.terminal-command-line[hidden] { display: none; }
.terminal-command-input {
display: inline;
min-width: 0;
min-height: 20px;
padding: 0;
border: 0;
background: transparent;
color: #f5f7fa;
caret-color: transparent;
outline: none;
white-space: pre-wrap;
overflow-wrap: anywhere;
user-select: text;
font: 13px/1.48 Consolas, "Courier New", monospace;
}
.terminal-command-input[contenteditable="false"] { color: #657386; }
.terminal-block-cursor {
display: inline-block;
position: relative;
width: 0;
height: 1.02em;
padding: 0;
line-height: 1.02em;
vertical-align: -0.16em;
pointer-events: none;
}
.terminal-block-cursor::after {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 0.62em;
height: 1.02em;
background: rgba(126, 231, 135, 0.82);
content: "";
animation: terminal-cursor-blink 1s steps(1, end) infinite;
}
.terminal-command-input.has-terminal-selection .terminal-block-cursor::after {
display: none;
}
.terminal-command-input::selection,
.terminal-command-input *::selection {
background: #2f81f7;
color: #ffffff;
}
@keyframes terminal-cursor-blink {
0%, 48% { opacity: 1; }
49%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.terminal-block-cursor::after { animation: none; }
}
.serial-console-footer {
display: flex;
gap: 18px;
padding: 8px 14px;
border-top: 1px solid #2e3a4b;
background: #182334;
color: #8fa1b7;
font-size: 10px;
}
.modal-layer {
position: fixed;
inset: 0;
display: grid;
place-items: center;
z-index: 1200;
}
.modal-layer[hidden] {
display: none;
}
.modal-backdrop {
position: absolute;
inset: 0;
background: rgba(27, 40, 58, 0.42);
backdrop-filter: blur(2px);
}
.modal-box {
position: relative;
z-index: 1;
width: min(720px, calc(100vw - 32px));
border: 1px solid #dfe5ee;
background: #fbfcfe;
border-radius: 10px;
padding: 18px;
box-shadow: 0 24px 60px rgba(20, 33, 52, 0.24);
}
.modal-form {
display: grid;
gap: 18px;
}
.modal-form .form-grid {
gap: 18px 24px;
}
.group-modal {
width: min(920px, calc(100vw - 32px));
}
.group-modal .form-grid {
gap: 18px 24px;
margin-bottom: 18px;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.modal-close {
border: 0;
background: transparent;
color: #6b7c91;
cursor: pointer;
font-size: 18px;
line-height: 1;
padding: 4px;
}
.modal-message { margin: 0 0 18px; font-size: 13px; color: #6d7c91; }
.group-permission-grid,
.group-permission-checks {
display: grid;
grid-template-columns: repeat(9, minmax(0, 1fr));
gap: 8px;
}
.group-permission-grid {
margin-top: 18px;
}
.group-permission-checks {
margin-top: 14px;
margin-bottom: 18px;
}
.group-permission-cell {
min-height: 64px;
border: 1px solid #dfe5ee;
border-radius: 8px;
background: #f8fbff;
padding: 12px 8px;
text-align: center;
font-size: 12px;
color: #6b7c91;
display: flex;
align-items: center;
justify-content: center;
line-height: 1.45;
}
.group-permission-cell.heading {
font-weight: 700;
color: #607188;
background: #f3f7fc;
}
.permission-chip {
min-height: 44px;
border: 1px solid #d9e3ef;
border-radius: 8px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 12px;
color: #5f6e84;
}
.permission-chip input {
margin: 0;
}
.permission-chip.selected {
border-color: #5aa57a;
background: #edf8f1;
color: #24523a;
}
.toast-root {
position: fixed;
right: 18px;
bottom: 18px;
display: grid;
gap: 10px;
z-index: 1000;
}
.toast {
min-width: 260px;
max-width: 360px;
background: #243349;
color: #fff;
border: 1px solid #3a4c65;
border-left-width: 5px;
border-radius: 6px;
padding: 12px 14px;
box-shadow: 0 12px 24px rgba(0,0,0,0.18);
font-size: 13px;
font-weight: 600;
}
.toast-success {
background: #e7f6ed;
border-color: #42a66b;
color: #22633d;
box-shadow: 0 12px 24px rgba(38, 119, 70, 0.18);
}
.toast-error {
background: #fdeaea;
border-color: #df5656;
color: #982f2f;
box-shadow: 0 12px 24px rgba(178, 45, 45, 0.18);
}
.toast-info {
background: #243349;
border-color: #6d8098;
color: #fff;
}
@media (max-width: 1100px) {
.compact-grid { grid-template-columns: 1fr; }
.port-link-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.target-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.group-permission-grid,
.group-permission-checks { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 920px) {
.sidebar { position: fixed; inset: 0 auto 0 0; transform: translateX(-100%); z-index: 30; }
body.sidebar-open .sidebar { transform: translateX(0); }
.menu-toggle { display: inline-flex; }
.compact-grid, .form-grid { grid-template-columns: 1fr; }
body[data-current-path="/tools/nettest/ping"] .mock-form .form-grid {
grid-template-columns: 1fr;
width: 100%;
}
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(1),
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(2),
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(3),
body[data-current-path="/tools/nettest/ping"] .mock-form .form-row:nth-child(4) {
grid-column: 1;
grid-row: auto;
}
.network-ipv6-disclosure { align-items: flex-start; flex-direction: column; }
body[data-current-path^="/network/interface-"] .form-panel .form-grid { grid-template-columns: 1fr; }
.network-interface-columns {
grid-template-columns: 1fr;
gap: 18px;
width: 100%;
}
.network-interface-column.ipv6-column {
padding-top: 16px;
padding-left: 0;
border-top: 2px solid transparent;
border-left: 0;
}
.network-interface-columns.ipv6-open .ipv6-column { border-top-color: #8ab9ef; }
.operating-mode-roles { grid-template-columns: 1fr; }
.target-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.group-permission-grid,
.group-permission-checks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
body[data-current-path^="/ports/"] .blocks {
grid-template-columns: 1fr;
min-height: 0;
}
body[data-current-path^="/ports/"] .port-selector-panel,
body[data-current-path^="/ports/"] .form-panel {
grid-column: 1;
}
body[data-current-path^="/ports/"] .port-selector-panel .port-link-grid {
grid-template-columns: repeat(auto-fit, minmax(82px, 1fr));
}
body[data-current-path^="/ports/"] .form-panel .form-grid {
grid-template-columns: 1fr;
}
.serial-console { min-height: 0; }
.serial-console-toolbar { align-items: flex-start; flex-direction: column; }
.serial-console-controls { justify-content: flex-start; }
.terminal-window {
flex-basis: 440px;
height: 440px;
min-height: 440px;
max-height: 440px;
}
.serial-console-footer { flex-wrap: wrap; gap: 6px 14px; }
}
.login-captcha[hidden], .login-captcha img[hidden] { display: none; }
.login-captcha-image-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.login-captcha-image-row img { display: block; max-width: 100%; width: 140px; height: auto; border: 1px solid #d6deea; border-radius: 6px; background: white; }
.login-captcha .login-captcha-hint { margin: 0; font-size: 12px; line-height: 1.5; color: #64748b; }
.btn.danger { color: #fff; background: #c93641; border: 1px solid #c93641; }
.btn.danger:hover:not(:disabled) { background: #aa2530; border-color: #aa2530; }
.btn.danger:disabled { opacity: .5; cursor: not-allowed; }
.login-progress[data-measured="true"] .login-progress-track span { animation: none; transform: none; transition: width .2s ease; }
.login-progress[data-state="failed"] { border-color: #d5a3a3; background: #fff4f4; }
.login-progress[data-state="failed"] p { color: #a12828; }
.login-progress[data-state="failed"] .login-progress-track span { background: #b83a3a; animation: none; }
.login-progress[data-state="delayed"] { border-color: #e4c58d; background: #fff9ed; }
.login-progress[data-state="delayed"] p { color: #875d13; }
.login-progress[data-state="delayed"] .login-progress-track span { background: #c88b23; animation: none; }
.reauth-dialog { border: 1px solid #d7dfeb; border-radius: 12px; padding: 24px; width: min(440px, calc(100vw - 48px)); }
.reauth-dialog::backdrop { background: #10203580; }
.reauth-dialog label { display: block; margin: 20px 0; }
.reauth-dialog input { display: block; width: 100%; margin-top: 8px; }
.reauth-dialog button { margin-right: 8px; }