diff --git a/static/index.html b/static/index.html
index b064008..2eed4fd 100644
--- a/static/index.html
+++ b/static/index.html
@@ -12,6 +12,7 @@
+
@@ -158,6 +159,7 @@
+
@@ -231,7 +233,8 @@
传输配置
@@ -303,7 +305,6 @@
-
diff --git a/static/style-3.css b/static/style-3.css
index 92f72e4..73a3c6b 100644
--- a/static/style-3.css
+++ b/static/style-3.css
@@ -1,4 +1,4 @@
-/* ===== style-3.css - 主界面 ===== */
+/* ===== style-3.css - 主界面核心 ===== */
/* ---------- 顶部导航 ---------- */
.top-bar {
@@ -145,130 +145,6 @@
height: 100%;
}
-/* ---------- 全局配置页 ---------- */
-.config-grid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 16px;
- margin-bottom: 20px;
-}
-
-.metric-card {
- background: var(--bg-metric);
- border-radius: 16px;
- padding: 16px 20px;
- border: 1px solid var(--border-subtle);
-}
-
-.metric-label {
- font-size: 12px;
- color: var(--text-dim);
- text-transform: uppercase;
- letter-spacing: 1px;
- margin-bottom: 8px;
-}
-
-.metric-value {
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-.big-number {
- font-size: 28px;
- font-weight: 600;
- color: #fff;
-}
-
-.unit {
- font-size: 14px;
- color: var(--text-dim);
-}
-
-.digit {
- font-family: 'JetBrains Mono', monospace;
- font-size: 18px;
- color: #fff;
-}
-
-.sep {
- color: var(--text-dim);
-}
-
-/* ---------- 展开详情 ---------- */
-.detail-collapse {
- padding: 12px 0;
- color: var(--text-dim);
- font-size: 13px;
- cursor: pointer;
- user-select: none;
- transition: color 0.3s;
-}
-
-.detail-collapse:hover {
- color: var(--text-secondary);
-}
-
-.detail-panel {
- background: rgba(255, 255, 255, 0.02);
- border-radius: 12px;
- padding: 16px 20px;
- border: 1px solid var(--border-subtle);
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 12px 24px;
- margin-bottom: 16px;
-}
-
-.detail-panel .form-row {
- display: flex;
- flex-direction: column;
- gap: 4px;
-}
-
-.detail-panel .form-row label {
- font-size: 11px;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- color: var(--text-dim);
-}
-
-.detail-panel .form-row input,
-.detail-panel .form-row select {
- padding: 8px 12px;
- background: rgba(255, 255, 255, 0.04);
- border: 1px solid var(--border-subtle);
- border-radius: 8px;
- color: #fff;
- font-size: 14px;
- outline: none;
- transition: border-color 0.3s;
-}
-
-.detail-panel .form-row input:focus,
-.detail-panel .form-row select:focus {
- border-color: var(--primary-blue-border);
-}
-
-.save-btn {
- grid-column: 1 / -1;
- padding: 10px 24px;
- background: linear-gradient(135deg, var(--primary-blue), #2a5adf);
- border: none;
- border-radius: 10px;
- font-size: 14px;
- font-weight: 600;
- color: #0a0a0f;
- cursor: pointer;
- transition: transform 0.2s, box-shadow 0.2s;
- margin-top: 4px;
-}
-
-.save-btn:hover {
- transform: scale(1.01);
- box-shadow: 0 4px 16px var(--primary-blue-glow);
-}
-
/* ---------- 账户管理区域 ---------- */
.profile-section {
background: rgba(255, 255, 255, 0.02);
@@ -329,13 +205,6 @@
border-color: var(--primary-blue-border);
}
-.profile-form .save-btn {
- grid-column: auto;
- padding: 8px 20px;
- margin-top: 0;
- height: 40px;
-}
-
.login-success {
color: #63e2b7;
font-size: 14px;
@@ -344,6 +213,57 @@
min-height: 24px;
}
+/* ---------- 统一保存按钮 ---------- */
+.save-btn,
+.save-config-btn {
+ padding: 10px 24px;
+ background: linear-gradient(135deg, var(--primary-blue), #2a5adf);
+ border: none;
+ border-radius: 10px;
+ font-size: 14px;
+ font-weight: 600;
+ color: #0a0a0f;
+ cursor: pointer;
+ transition: filter 0.3s ease;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ /* 确保按钮本身不裁切阴影 */
+ isolation: isolate;
+}
+
+.save-btn:hover,
+.save-config-btn:hover {
+ filter: brightness(1.25);
+ transform: none;
+}
+
+.save-btn:active,
+.save-config-btn:active {
+ filter: brightness(0.9);
+ transform: scale(0.97);
+}
+
+/* 账户管理中的修改密码按钮(覆盖尺寸) */
+.profile-form .save-btn {
+ grid-column: auto;
+ padding: 8px 20px;
+ margin-top: 0;
+ height: 40px;
+ font-size: 13px;
+ border-radius: 8px;
+}
+
+/* 保存配置按钮全宽(在全局配置页使用) */
+.save-config-btn {
+ width: 100%;
+ margin-top: 8px;
+ padding: 12px;
+ font-size: 16px;
+ border-radius: 12px;
+}
+
/* ---------- 隧道列表 ---------- */
.toolbar {
display: flex;
@@ -783,371 +703,35 @@ select:disabled {
opacity: 1;
}
-/* ============================================================
- v1.5 新增样式:配置卡片 + 日志面板
- ============================================================ */
-
-/* ---------- 配置页面 ---------- */
-.config-tab-content {
- padding-bottom: 20px;
-}
-
-.config-page-header {
- margin-bottom: 12px;
-}
-.config-page-header h2 {
- font-size: 18px;
- font-weight: 500;
- color: var(--text-primary);
- margin-bottom: 2px;
-}
-.config-subtitle {
- font-size: 13px;
- color: var(--text-dim);
-}
-
-/* 首次使用提示 */
-.config-tip {
- background: rgba(255, 200, 50, 0.08);
- border: 1px solid rgba(255, 200, 50, 0.15);
- border-radius: 10px;
- padding: 10px 16px;
- font-size: 13px;
- color: #f0c040;
- margin-bottom: 16px;
-}
-
-/* 配置卡片 */
-.config-card {
- background: rgba(255, 255, 255, 0.02);
- border: 1px solid var(--border-subtle);
- border-radius: 14px;
- padding: 16px 20px;
- margin-bottom: 14px;
-}
-
-.config-card-header {
- display: flex;
- align-items: center;
- gap: 10px;
- padding-bottom: 10px;
- border-bottom: 1px solid var(--border-subtle);
- margin-bottom: 14px;
-}
-.card-icon {
- font-size: 18px;
-}
-.card-title {
- font-size: 14px;
- font-weight: 500;
- color: var(--text-secondary);
-}
-
-.config-card-body {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 12px 24px;
-}
-.config-card-body .form-row {
- display: flex;
- flex-direction: column;
- gap: 4px;
-}
-.config-card-body .form-row label {
- font-size: 11px;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- color: var(--text-dim);
-}
-.config-card-body .form-row input,
-.config-card-body .form-row select {
- padding: 8px 12px;
- background: rgba(255, 255, 255, 0.04);
- border: 1px solid var(--border-subtle);
- border-radius: 8px;
- color: #fff;
- font-size: 14px;
- outline: none;
- transition: border-color 0.3s;
- width: 100%;
-}
-.config-card-body .form-row input:focus,
-.config-card-body .form-row select:focus {
- border-color: var(--primary-blue-border);
-}
-.config-card-body .form-row .unit-suffix {
- font-size: 12px;
- color: var(--text-dim);
- margin-top: 2px;
-}
-
-/* 只读行(TCP Mux) */
-.readonly-row {
- grid-column: 1 / -1;
-}
-.readonly-value {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 6px 12px;
- background: rgba(255, 255, 255, 0.02);
- border-radius: 8px;
-}
-.readonly-value .status-dot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- background: #63e2b7;
- box-shadow: 0 0 10px rgba(99, 226, 183, 0.3);
- flex-shrink: 0;
-}
-.readonly-value .status-text.active {
- color: #63e2b7;
- font-size: 13px;
-}
-.readonly-value .hint-text {
- font-size: 12px;
- color: var(--text-dim);
- margin-left: 8px;
-}
-
-/* Token 输入框 + 显示按钮 */
-.token-input-wrapper {
- display: flex;
- gap: 8px;
-}
-.token-input-wrapper input {
- flex: 1;
-}
-.token-toggle-btn {
- padding: 8px 16px;
- background: rgba(255, 255, 255, 0.06);
- border: 1px solid var(--border-subtle);
- border-radius: 8px;
- color: var(--text-secondary);
- font-size: 12px;
- cursor: pointer;
- white-space: nowrap;
-}
-.token-toggle-btn:hover {
- background: rgba(255, 255, 255, 0.1);
-}
-
-/* 保存配置按钮(独立大按钮) */
-.save-config-btn {
- width: 100%;
- padding: 12px;
- background: linear-gradient(135deg, var(--primary-blue), #2a5adf);
- border: none;
- border-radius: 12px;
- font-size: 16px;
- font-weight: 600;
- color: #0a0a0f;
- cursor: pointer;
- transition: transform 0.2s, box-shadow 0.2s;
- margin-top: 8px;
-}
-.save-config-btn:hover {
- transform: scale(1.01);
- box-shadow: 0 4px 20px var(--primary-blue-glow);
-}
-
-/* ---------- 日志面板 ---------- */
-.log-tab-content {
- display: flex;
- flex-direction: column;
- height: 100%;
- min-height: 400px;
-}
-
-.log-toolbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 8px 0 12px;
- flex-shrink: 0;
- flex-wrap: wrap;
- gap: 10px;
-}
-.log-toolbar-left {
- display: flex;
- align-items: center;
- gap: 14px;
-}
-.log-toolbar-right {
- display: flex;
- align-items: center;
- gap: 10px;
-}
-
-.log-info-badge {
- font-size: 13px;
- color: var(--text-secondary);
-}
-.log-error-badge {
- font-size: 13px;
- color: #f87171;
-}
-.log-auto-scroll-label {
- font-size: 13px;
- color: var(--text-secondary);
- display: flex;
- align-items: center;
- gap: 6px;
- cursor: pointer;
-}
-.log-auto-scroll-label input[type="checkbox"] {
- width: 16px;
- height: 16px;
- accent-color: var(--primary-blue);
- cursor: pointer;
-}
-
-.log-btn {
- padding: 6px 14px;
- background: rgba(255, 255, 255, 0.04);
- border: 1px solid var(--border-subtle);
- border-radius: 8px;
- color: var(--text-secondary);
- font-size: 13px;
- cursor: pointer;
- transition: background 0.2s;
-}
-.log-btn:hover {
- background: rgba(255, 255, 255, 0.08);
-}
-
-/* 终端样式(类似命令行) */
-.log-terminal {
- flex: 1;
- background: rgba(0, 0, 0, 0.6);
- border-radius: 12px;
- border: 1px solid var(--border-subtle);
- padding: 12px 16px;
- overflow-y: auto;
- font-family: 'JetBrains Mono', 'Consolas', monospace;
- font-size: 13px;
- line-height: 1.7;
- min-height: 300px;
- max-height: 500px;
-}
-.log-terminal::-webkit-scrollbar {
- width: 6px;
-}
-.log-terminal::-webkit-scrollbar-track {
- background: rgba(255, 255, 255, 0.02);
- border-radius: 4px;
-}
-.log-terminal::-webkit-scrollbar-thumb {
- background: rgba(74, 124, 255, 0.25);
- border-radius: 4px;
-}
-.log-terminal::-webkit-scrollbar-thumb:hover {
- background: rgba(74, 124, 255, 0.4);
-}
-
-.log-lines {
- display: flex;
- flex-direction: column;
-}
-.log-line {
- color: #c0c0c0;
- white-space: pre-wrap;
- word-break: break-all;
- padding: 1px 0;
-}
-.log-line:hover {
- background: rgba(255, 255, 255, 0.02);
-}
-.log-empty {
- color: var(--text-dim);
- text-align: center;
- padding: 40px 0;
-}
-
-/* 日志底部状态 */
-.log-footer {
- display: flex;
- justify-content: space-between;
- padding: 10px 4px 0;
- font-size: 12px;
- color: var(--text-dim);
- flex-shrink: 0;
-}
-.log-polling-status {
- color: var(--primary-blue);
-}
-
/* ---------- 响应式调整 ---------- */
@media (max-width: 768px) {
- .config-card-body {
- grid-template-columns: 1fr;
- }
.profile-form {
grid-template-columns: 1fr;
}
- .log-toolbar {
+ .proxy-list {
+ grid-template-columns: 1fr 1fr;
+ }
+ .toolbar {
flex-direction: column;
align-items: stretch;
}
- .log-toolbar-right {
- flex-wrap: wrap;
- }
- .token-input-wrapper {
- flex-wrap: wrap;
+ .toolbar-right .search-input {
+ width: 100%;
}
}
-/* ============================================================
- v2 协议开关(灰标禁用)
- ============================================================ */
-
-.v2-switch-row {
- grid-column: 1 / -1 !important;
- padding-top: 4px;
- border-top: 1px solid var(--border-subtle);
- margin-top: 4px;
-}
-
-.v2-switch-wrapper {
- display: flex;
- align-items: center;
- gap: 14px;
- padding: 6px 0;
-}
-
-/* 禁用状态开关 - 灰标 */
-.switch.disabled {
- opacity: 0.4;
- cursor: not-allowed;
- pointer-events: none;
-}
-.switch.disabled .slider {
- background: rgba(255, 255, 255, 0.08);
-}
-.switch.disabled input:checked + .slider {
- background: rgba(74, 124, 255, 0.25);
-}
-.switch.disabled .slider::before {
- background: #3a3a4a;
-}
-
-/* "即将推出" 徽章 */
-.v2-badge {
- font-size: 11px;
- padding: 2px 12px;
- background: rgba(255, 200, 50, 0.12);
- border: 1px solid rgba(255, 200, 50, 0.15);
- border-radius: 12px;
- color: #f0c040;
- letter-spacing: 0.5px;
- font-weight: 500;
-}
-
-.v2-hint {
- font-size: 12px;
- color: var(--text-dim);
- line-height: 1.5;
- padding: 2px 0 4px;
- display: block;
+@media (max-width: 480px) {
+ .proxy-list {
+ grid-template-columns: 1fr;
+ }
+ .top-left .nav-logo {
+ width: 36px;
+ height: 36px;
+ }
+ .brand-info .logo-text {
+ font-size: 18px;
+ }
+ .dialog-card {
+ padding: 20px;
+ }
}
\ No newline at end of file
diff --git a/static/style-4.css b/static/style-4.css
new file mode 100644
index 0000000..2a2368b
--- /dev/null
+++ b/static/style-4.css
@@ -0,0 +1,339 @@
+/* ===== style-4.css - v1.5 新增样式 ===== */
+
+/* ---------- 配置页面 ---------- */
+.config-tab-content {
+ padding-bottom: 20px;
+}
+
+.config-page-header {
+ margin-bottom: 12px;
+}
+.config-page-header h2 {
+ font-size: 18px;
+ font-weight: 500;
+ color: var(--text-primary);
+ margin-bottom: 2px;
+}
+.config-subtitle {
+ font-size: 13px;
+ color: var(--text-dim);
+}
+
+/* 首次使用提示 */
+.config-tip {
+ background: rgba(255, 200, 50, 0.08);
+ border: 1px solid rgba(255, 200, 50, 0.15);
+ border-radius: 10px;
+ padding: 10px 16px;
+ font-size: 13px;
+ color: #f0c040;
+ margin-bottom: 16px;
+}
+
+/* ---------- 配置卡片 ---------- */
+.config-card {
+ background: rgba(255, 255, 255, 0.02);
+ border: 1px solid var(--border-subtle);
+ border-radius: 14px;
+ padding: 16px 20px;
+ margin-bottom: 14px;
+}
+
+.config-card-header {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid var(--border-subtle);
+ margin-bottom: 14px;
+}
+.card-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--text-secondary);
+}
+
+.config-card-body {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px 24px;
+}
+.config-card-body .form-row {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+.config-card-body .form-row label {
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--text-dim);
+}
+.config-card-body .form-row input,
+.config-card-body .form-row select {
+ padding: 8px 12px;
+ background: rgba(255, 255, 255, 0.04);
+ border: 1px solid var(--border-subtle);
+ border-radius: 8px;
+ color: #fff;
+ font-size: 14px;
+ outline: none;
+ transition: border-color 0.3s;
+ width: 100%;
+}
+.config-card-body .form-row input:focus,
+.config-card-body .form-row select:focus {
+ border-color: var(--primary-blue-border);
+}
+
+/* 数字输入框统一宽度 */
+.config-card-body .form-row input[type="number"] {
+ width: 100%;
+ max-width: 120px;
+}
+
+/* 只读行(TCP Mux) */
+.readonly-value {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 12px;
+ background: rgba(255, 255, 255, 0.02);
+ border-radius: 8px;
+}
+.readonly-value .status-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #63e2b7;
+ box-shadow: 0 0 10px rgba(99, 226, 183, 0.3);
+ flex-shrink: 0;
+}
+.readonly-value .status-text.active {
+ color: #63e2b7;
+ font-size: 13px;
+}
+.readonly-value .hint-text {
+ font-size: 12px;
+ color: var(--text-dim);
+ margin-left: 8px;
+}
+
+/* Token 输入框 + 显示按钮 */
+.token-input-wrapper {
+ display: flex;
+ gap: 8px;
+}
+.token-input-wrapper input {
+ flex: 1;
+}
+.token-toggle-btn {
+ padding: 8px 16px;
+ background: rgba(255, 255, 255, 0.06);
+ border: 1px solid var(--border-subtle);
+ border-radius: 8px;
+ color: var(--text-secondary);
+ font-size: 12px;
+ cursor: pointer;
+ white-space: nowrap;
+}
+.token-toggle-btn:hover {
+ background: rgba(255, 255, 255, 0.1);
+}
+
+/* ---------- v2 协议开关(灰标禁用) ---------- */
+.v2-switch-row {
+ grid-column: 1 / -1 !important;
+ padding-top: 4px;
+ border-top: 1px solid var(--border-subtle);
+ margin-top: 4px;
+}
+
+.v2-switch-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ padding: 6px 0;
+}
+
+/* 禁用状态开关 - 灰标 */
+.switch.disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+ pointer-events: none;
+}
+.switch.disabled .slider {
+ background: rgba(255, 255, 255, 0.08);
+}
+.switch.disabled input:checked + .slider {
+ background: rgba(74, 124, 255, 0.25);
+}
+.switch.disabled .slider::before {
+ background: #3a3a4a;
+}
+
+/* "即将推出" 徽章 */
+.v2-badge {
+ font-size: 11px;
+ padding: 2px 12px;
+ background: rgba(255, 200, 50, 0.12);
+ border: 1px solid rgba(255, 200, 50, 0.15);
+ border-radius: 12px;
+ color: #f0c040;
+ letter-spacing: 0.5px;
+ font-weight: 500;
+}
+
+.v2-hint {
+ font-size: 12px;
+ color: var(--text-dim);
+ line-height: 1.5;
+ padding: 2px 0 4px;
+ display: block;
+}
+
+/* ---------- 日志面板 ---------- */
+.log-tab-content {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ min-height: 400px;
+}
+
+.log-toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 0 12px;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+.log-toolbar-left {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+}
+.log-toolbar-right {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.log-info-badge {
+ font-size: 13px;
+ color: var(--text-secondary);
+}
+.log-error-badge {
+ font-size: 13px;
+ color: #f87171;
+}
+.log-auto-scroll-label {
+ font-size: 13px;
+ color: var(--text-secondary);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ cursor: pointer;
+}
+.log-auto-scroll-label input[type="checkbox"] {
+ width: 16px;
+ height: 16px;
+ accent-color: var(--primary-blue);
+ cursor: pointer;
+}
+
+.log-btn {
+ padding: 6px 14px;
+ background: rgba(255, 255, 255, 0.04);
+ border: 1px solid var(--border-subtle);
+ border-radius: 8px;
+ color: var(--text-secondary);
+ font-size: 13px;
+ cursor: pointer;
+ transition: background 0.2s;
+}
+.log-btn:hover {
+ background: rgba(255, 255, 255, 0.08);
+}
+
+/* 终端样式(类似命令行) */
+.log-terminal {
+ flex: 1;
+ background: rgba(0, 0, 0, 0.6);
+ border-radius: 12px;
+ border: 1px solid var(--border-subtle);
+ padding: 12px 16px;
+ overflow-y: auto;
+ font-family: 'JetBrains Mono', 'Consolas', monospace;
+ font-size: 13px;
+ line-height: 1.7;
+ min-height: 300px;
+ max-height: 500px;
+}
+.log-terminal::-webkit-scrollbar {
+ width: 6px;
+}
+.log-terminal::-webkit-scrollbar-track {
+ background: rgba(255, 255, 255, 0.02);
+ border-radius: 4px;
+}
+.log-terminal::-webkit-scrollbar-thumb {
+ background: rgba(74, 124, 255, 0.25);
+ border-radius: 4px;
+}
+.log-terminal::-webkit-scrollbar-thumb:hover {
+ background: rgba(74, 124, 255, 0.4);
+}
+
+.log-lines {
+ display: flex;
+ flex-direction: column;
+}
+.log-line {
+ color: #c0c0c0;
+ white-space: pre-wrap;
+ word-break: break-all;
+ padding: 1px 0;
+}
+.log-line:hover {
+ background: rgba(255, 255, 255, 0.02);
+}
+.log-empty {
+ color: var(--text-dim);
+ text-align: center;
+ padding: 40px 0;
+}
+
+/* 日志底部状态 */
+.log-footer {
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 4px 0;
+ font-size: 12px;
+ color: var(--text-dim);
+ flex-shrink: 0;
+}
+.log-polling-status {
+ color: var(--primary-blue);
+}
+
+/* ---------- 响应式调整 ---------- */
+@media (max-width: 768px) {
+ .config-card-body {
+ grid-template-columns: 1fr;
+ }
+ .log-toolbar {
+ flex-direction: column;
+ align-items: stretch;
+ }
+ .log-toolbar-right {
+ flex-wrap: wrap;
+ }
+ .token-input-wrapper {
+ flex-wrap: wrap;
+ }
+ .v2-switch-wrapper {
+ flex-wrap: wrap;
+ }
+}
\ No newline at end of file