diff --git a/app.py b/app.py index 0e04348..f10ba2d 100644 --- a/app.py +++ b/app.py @@ -179,13 +179,132 @@ def ui_full_pipeline( # --------------------------------------------------------------------------- # Gradio 界面 # --------------------------------------------------------------------------- +APP_ROOT = Path(__file__).resolve().parent +PWA_DIR = APP_ROOT / "pwa" + +PWA_HEAD = """ + + + + + + + + + + +""" + CUSTOM_CSS = """ -/* ========== 高对比度暗色主题(确保文字清晰可读) ========== */ +/* ========== 居中布局 + 响应式 + 高对比度 ========== */ +html, body { + width: 100% !important; + min-height: 100vh !important; + margin: 0 !important; + padding: 0 !important; + background: #0f1419 !important; + overflow-x: hidden !important; +} + +/* 外层全宽背景,内容区水平居中 */ +gradio-app, +.gradio-app, +#main, +.app, +.fillable, +.contain { + width: 100% !important; + max-width: 100% !important; + display: flex !important; + flex-direction: column !important; + align-items: center !important; + justify-content: flex-start !important; + background: #0f1419 !important; + box-sizing: border-box !important; +} + +/* 核心内容容器居中 */ .gradio-container { background: #0f1419 !important; color: #eef2f7 !important; font-size: 15px !important; - max-width: 1400px !important; + width: 100% !important; + max-width: min(1200px, 94vw) !important; + margin-left: auto !important; + margin-right: auto !important; + padding: 16px clamp(12px, 3vw, 32px) !important; + box-sizing: border-box !important; + float: none !important; +} + +/* 带鱼屏 / 超宽屏 */ +@media (min-width: 1920px) { + .gradio-container { max-width: min(1280px, 82vw) !important; } +} +@media (min-width: 2560px) { + .gradio-container { max-width: min(1360px, 68vw) !important; } +} +@media (min-width: 3440px) { + .gradio-container { max-width: 1440px !important; } +} + +/* 平板 */ +@media (max-width: 1024px) { + .gradio-container { + max-width: 100% !important; + padding: 14px 18px !important; + } +} + +/* 手机 */ +@media (max-width: 640px) { + .gradio-container { + max-width: 100% !important; + padding: 10px 12px !important; + font-size: 14px !important; + } + .gradio-container h1 { font-size: 1.35rem !important; } + .gradio-container .tab-nav { + flex-wrap: wrap !important; + gap: 6px !important; + } + .gradio-container .tab-nav button { + flex: 1 1 28% !important; + min-width: 88px !important; + padding: 8px 8px !important; + font-size: 0.8rem !important; + } + .status-row, + .status-row > div, + .pipeline-steps, + .pipeline-steps > div, + .pipeline-output-row, + .pipeline-output-row > div { + flex-direction: column !important; + width: 100% !important; + } + .status-row button, + .pipeline-steps button, + .pipeline-output-row button { + width: 100% !important; + } + .dark-panel table { + font-size: 0.85rem !important; + display: block !important; + overflow-x: auto !important; + } + .install-hint { font-size: 0.85rem !important; } +} + +/* 触摸设备:按钮最小点击区域 44px */ +@media (hover: none) and (pointer: coarse) { + .gradio-container button { min-height: 44px !important; } } /* 全局文字 */ @@ -198,7 +317,6 @@ CUSTOM_CSS = """ color: #eef2f7 !important; } -/* 标题 */ .gradio-container h1 { color: #ffffff !important; font-size: 1.75rem !important; @@ -211,7 +329,6 @@ CUSTOM_CSS = """ font-weight: 600 !important; } -/* 标签 */ .gradio-container .block-label, .gradio-container label, .gradio-container .label-wrap span { @@ -220,7 +337,6 @@ CUSTOM_CSS = """ font-size: 0.95rem !important; } -/* 输入框 / 文本域 */ .gradio-container textarea, .gradio-container input[type="text"], .gradio-container .wrap textarea, @@ -238,14 +354,12 @@ CUSTOM_CSS = """ opacity: 1 !important; } -/* 只读日志框 */ .gradio-container .wrap .readonly textarea { background: #111827 !important; color: #e5e7eb !important; border-color: #374151 !important; } -/* Tab 标签页 */ .gradio-container .tab-nav button { color: #9ca3af !important; font-weight: 600 !important; @@ -258,7 +372,6 @@ CUSTOM_CSS = """ border-bottom: 3px solid #3b82f6 !important; } -/* 按钮 */ .gradio-container button.primary, .gradio-container .primary { background: #2563eb !important; @@ -267,9 +380,7 @@ CUSTOM_CSS = """ font-size: 0.95rem !important; border: 1px solid #3b82f6 !important; } -.gradio-container button.primary:hover { - background: #1d4ed8 !important; -} +.gradio-container button.primary:hover { background: #1d4ed8 !important; } .gradio-container button.secondary, .gradio-container button:not(.primary) { color: #e5e7eb !important; @@ -278,13 +389,14 @@ CUSTOM_CSS = """ font-weight: 600 !important; } -/* 顶部信息面板 */ .dark-panel { border: 1px solid #3b82f6 !important; border-radius: 10px !important; padding: 18px 20px !important; background: #1a2332 !important; margin-bottom: 16px !important; + width: 100% !important; + box-sizing: border-box !important; } .dark-panel code { color: #93c5fd !important; @@ -293,7 +405,16 @@ CUSTOM_CSS = """ border-radius: 4px !important; } -/* 状态卡片 */ +.install-hint { + margin-top: 12px !important; + padding: 10px 14px !important; + border-radius: 8px !important; + background: #1e3a5f !important; + border: 1px dashed #3b82f6 !important; + color: #bfdbfe !important; + font-size: 0.9rem !important; +} + .status-card { border-radius: 10px; padding: 14px 16px; @@ -301,13 +422,14 @@ CUSTOM_CSS = """ border-left: 5px solid #6b7280; background: #1f2937; min-height: 72px; + width: 100%; + box-sizing: border-box; } .status-card .status-title { font-size: 0.85rem; font-weight: 700; color: #93c5fd !important; margin-bottom: 8px; - letter-spacing: 0.03em; } .status-card .status-body { font-size: 0.92rem; @@ -315,23 +437,13 @@ CUSTOM_CSS = """ color: #f3f4f6 !important; word-break: break-word; } -.status-ok { - border-left-color: #22c55e !important; - background: #14291a !important; -} +.status-ok { border-left-color: #22c55e !important; background: #14291a !important; } .status-ok .status-body { color: #bbf7d0 !important; } -.status-warn { - border-left-color: #f59e0b !important; - background: #2a2010 !important; -} +.status-warn { border-left-color: #f59e0b !important; background: #2a2010 !important; } .status-warn .status-body { color: #fde68a !important; } -.status-err { - border-left-color: #ef4444 !important; - background: #2a1515 !important; -} +.status-err { border-left-color: #ef4444 !important; background: #2a1515 !important; } .status-err .status-body { color: #fecaca !important; } -/* 音频上传区 */ .gradio-container .audio-container, .gradio-container .upload-container { border: 2px dashed #4b5563 !important; @@ -413,14 +525,16 @@ def build_app() -> gr.Blocks: | ChatTTS | 本地 GPU 固定音色合成 | > 仓库: [{GIT_REPO_URL}]({GIT_REPO_URL}) + +