Spaces:
Running
Running
排版重構 Phase 1:四邊留白/三欄比例/輸入框多行/頂部列精簡
Browse files千卉用參考圖比對現況後逐項定案的版面調整(大範圍改動的第一階段,
先做低風險、互相獨立的項目):
- 四邊留白:真因不是原本猜測的 .contain wrapper padding(devtools 逐層
量測後排除,那層 padding 早就是 0),是 Gradio 的 .app 元素被設了
max-width:1280px + auto 置中 margin,改成 max-width:100% + margin 歸零
- 三欄比例 nav:chat:canvas 從 2:4:7 改成 2:3:7
- 對話輸入框 lines=3 變成真正多行 textarea;對話視窗跟輸入框改用
flex-grow(6:1)依可用高度動態分配,不寫死 px,實測比例約 5.4:1
- 頂部列(app-header)從三行大標題+額外進度條精簡成單行產品名+步驟列,
拿掉進度條(跟步驟列的已完成/進行中/失敗三態是重複資訊)
A/B/D 三欄頂端對齊問題:實測 devtools 確認三欄 DOM 頂端本來就是像素級
對齊(皆 top:73px),不是 CSS bug,是 nav-col 第一個項目沒有卡片邊框
(收合按鈕裸露),視覺上比相鄰有邊框卡片的欄位「感覺」低,留給下一階段
nav-col 視覺重做時一併處理。
已用 Playwright 驗證:三欄邊界貼齊、輸入框可打多行且高度比例正確、
頂部列精簡且無進度條、reset 流程正常回首頁無殘留,首頁本身不受
.app 這個全域選擇器改動影響。
- app_agent.py +82 -74
app_agent.py
CHANGED
|
@@ -1394,9 +1394,10 @@ _STEPS = [
|
|
| 1394 |
def _build_header_html(done_steps: list = None, current_step: int = None,
|
| 1395 |
failed_step: int = None) -> str:
|
| 1396 |
"""
|
| 1397 |
-
產生完整標題區塊 HTML(
|
| 1398 |
-
|
| 1399 |
-
|
|
|
|
| 1400 |
done_steps: 已完成步驟(1-based list)
|
| 1401 |
current_step: 目前執行步驟(1-based int)
|
| 1402 |
failed_step: 執行失敗時卡住的步驟(1-based int),失敗時該步驟改用失敗樣式,
|
|
@@ -1427,15 +1428,10 @@ def _build_header_html(done_steps: list = None, current_step: int = None,
|
|
| 1427 |
f'<span class="step-num">{num}</span>{name}</span>'
|
| 1428 |
)
|
| 1429 |
|
| 1430 |
-
pct = int(len(done_steps) / len(_STEPS) * 100)
|
| 1431 |
-
|
| 1432 |
return (
|
| 1433 |
'<div class="app-header">'
|
| 1434 |
-
' <
|
| 1435 |
-
' <p class="subtitle">TransPrism: An Analytical Framework for Retranslation</p>'
|
| 1436 |
-
' <p class="subtitle-3">II 分析引擎 SpectraEngine</p>'
|
| 1437 |
f' <div class="steps">{"".join(pills)}</div>'
|
| 1438 |
-
f' <div class="step-progress-track"><div class="step-progress-fill" style="width:{pct}%"></div></div>'
|
| 1439 |
'</div>'
|
| 1440 |
)
|
| 1441 |
|
|
@@ -1849,12 +1845,19 @@ _CUSTOM_CSS = """
|
|
| 1849 |
padding: 0 0 1.5rem !important;
|
| 1850 |
}
|
| 1851 |
/* .gradio-container 內部還包了一層 Gradio 自己的 .app(class="main fillable app")
|
| 1852 |
-
wrapper
|
| 1853 |
-
|
| 1854 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1855 |
.app {
|
| 1856 |
padding-left: 0 !important;
|
| 1857 |
padding-right: 0 !important;
|
|
|
|
|
|
|
|
|
|
| 1858 |
}
|
| 1859 |
*, *::before, *::after { box-sizing: border-box; }
|
| 1860 |
/* 全域安全網(陷阱 13 第 3 點):Gradio 的 markdown 渲染統一包在
|
|
@@ -1864,10 +1867,14 @@ _CUSTOM_CSS = """
|
|
| 1864 |
字級仍留給各自的選擇器決定,這裡不覆寫 font-size。 */
|
| 1865 |
.md { display: block !important; }
|
| 1866 |
|
| 1867 |
-
/* ── 2. HEADER(卡片化)─────────────────────
|
| 1868 |
.app-header {
|
| 1869 |
-
|
| 1870 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1871 |
position: relative;
|
| 1872 |
margin: 1rem 0 1.25rem;
|
| 1873 |
border: 1px solid var(--c-border);
|
|
@@ -1892,41 +1899,22 @@ _CUSTOM_CSS = """
|
|
| 1892 |
`background-image: linear-gradient(...) !important;` 這個子屬性本身,
|
| 1893 |
跳過簡寫展開的解析路徑——已用瀏覽器 devtools 即時修改驗證過,改長寫法
|
| 1894 |
後漸層立即正常顯示。*/
|
| 1895 |
-
.app-header
|
| 1896 |
font-family: 'Crimson Pro', 'Noto Serif TC', Georgia, serif !important;
|
| 1897 |
-
font-size:
|
| 1898 |
font-weight: 700 !important;
|
| 1899 |
-webkit-background-clip: text;
|
| 1900 |
-webkit-text-fill-color: transparent;
|
| 1901 |
background-clip: text;
|
| 1902 |
-
margin: 0
|
| 1903 |
letter-spacing: -.01em;
|
| 1904 |
line-height: 1.2 !important;
|
|
|
|
|
|
|
| 1905 |
}
|
| 1906 |
-
.app-header .
|
| 1907 |
-
font-size: 1.
|
| 1908 |
-
|
| 1909 |
-
margin: 0 0 .25rem !important;
|
| 1910 |
-
-webkit-background-clip: text !important;
|
| 1911 |
-
-webkit-text-fill-color: transparent !important;
|
| 1912 |
-
background-clip: text !important;
|
| 1913 |
-
color: transparent !important;
|
| 1914 |
-
}
|
| 1915 |
-
/* 第三排:字型比第二排大、比主標題小 */
|
| 1916 |
-
.app-header .subtitle-3 {
|
| 1917 |
-
font-size: 1.5rem !important;
|
| 1918 |
-
font-weight: 700 !important;
|
| 1919 |
-
line-height: 1.4 !important;
|
| 1920 |
-
margin: 0 !important;
|
| 1921 |
-
-webkit-background-clip: text !important;
|
| 1922 |
-
-webkit-text-fill-color: transparent !important;
|
| 1923 |
-
background-clip: text !important;
|
| 1924 |
-
color: transparent !important;
|
| 1925 |
-
}
|
| 1926 |
-
.app-header .subtitle strong {
|
| 1927 |
-
-webkit-text-fill-color: transparent !important;
|
| 1928 |
-
color: transparent !important;
|
| 1929 |
-
font-weight: 600;
|
| 1930 |
}
|
| 1931 |
.badge {
|
| 1932 |
display: inline-flex; align-items: center; gap: 4px;
|
|
@@ -1948,10 +1936,12 @@ _CUSTOM_CSS = """
|
|
| 1948 |
color: var(--c-accent2-strong);
|
| 1949 |
border: 1px solid rgba(var(--c-accent2-rgb),.30);
|
| 1950 |
}
|
| 1951 |
-
/* step indicators
|
|
|
|
|
|
|
| 1952 |
.app-header .steps {
|
| 1953 |
-
display: flex; justify-content:
|
| 1954 |
-
gap: 4px; margin-
|
| 1955 |
}
|
| 1956 |
.step-pill {
|
| 1957 |
display: inline-flex; align-items: center; gap: 6px;
|
|
@@ -2018,21 +2008,6 @@ _CUSTOM_CSS = """
|
|
| 2018 |
background: #dc2626;
|
| 2019 |
color: #fff;
|
| 2020 |
}
|
| 2021 |
-
/* 步驟列下方的整體進度條,取代原本另外放在右欄、跟步驟列資訊重複的執行進度面板 */
|
| 2022 |
-
.step-progress-track {
|
| 2023 |
-
height: 4px;
|
| 2024 |
-
background: var(--c-border);
|
| 2025 |
-
border-radius: 2px;
|
| 2026 |
-
margin-top: .75rem;
|
| 2027 |
-
overflow: hidden;
|
| 2028 |
-
}
|
| 2029 |
-
.step-progress-fill {
|
| 2030 |
-
height: 100%;
|
| 2031 |
-
background: linear-gradient(90deg, var(--c-accent-strong), var(--c-accent2));
|
| 2032 |
-
border-radius: 2px;
|
| 2033 |
-
transition: width .3s ease;
|
| 2034 |
-
}
|
| 2035 |
-
|
| 2036 |
/* ── 3. TABS ───────────────────────────────────────────────────── */
|
| 2037 |
/* 注意:這裡原本用 backdrop-filter 做毛玻璃效果,搭配 position: sticky
|
| 2038 |
會讓瀏覽器每個捲動影格都要重新計算模糊,頁面一長(大表格、多張圖)就會
|
|
@@ -2117,6 +2092,17 @@ _CUSTOM_CSS = """
|
|
| 2117 |
overflow-y: auto !important;
|
| 2118 |
overflow-x: hidden !important;
|
| 2119 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2120 |
|
| 2121 |
/* 訊息從頂部開始排列,消除空白 */
|
| 2122 |
div[role="log"].bubble-wrap,
|
|
@@ -2344,12 +2330,25 @@ div[role="log"][aria-label="chatbot conversation"],
|
|
| 2344 |
display: flex !important;
|
| 2345 |
flex-direction: column !important;
|
| 2346 |
flex-wrap: nowrap !important;
|
| 2347 |
-
gap:
|
| 2348 |
height: calc(100vh - 150px) !important;
|
| 2349 |
-
overflow
|
| 2350 |
-
overflow-y: auto !important;
|
| 2351 |
min-width: 0 !important;
|
| 2352 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2353 |
/* canvas-col 本身「不」捲動——它只負責把步驟列(固定)跟 canvas-scroll
|
| 2354 |
(捲動)疊在一起、限制在同一個總高度內。踩坑記錄:原本想讓步驟列用
|
| 2355 |
position:sticky 貼在 canvas-col 頂端,但 sticky 元素只能在「自己最近的
|
|
@@ -2425,7 +2424,7 @@ div[role="log"][aria-label="chatbot conversation"],
|
|
| 2425 |
}
|
| 2426 |
.homepage-hero h1 {
|
| 2427 |
margin: 1rem 0 .6rem; font-size: 2.1rem; line-height: 1.3; font-weight: 700;
|
| 2428 |
-
/* 同 .app-header
|
| 2429 |
background 簡寫在瀏覽器展開成子屬性時 background-image 會解析成
|
| 2430 |
空值,改直接寫 background-image 這個子屬性本身即可 */
|
| 2431 |
background-image: linear-gradient(100deg, var(--c-accent) 10%, var(--c-accent2) 90%);
|
|
@@ -2654,11 +2653,19 @@ img.button-icon { opacity: .82; }
|
|
| 2654 |
margin: .6rem 0 0 !important;
|
| 2655 |
width: 100% !important;
|
| 2656 |
}
|
| 2657 |
-
/* chat-col
|
| 2658 |
-
|
| 2659 |
-
|
|
|
|
| 2660 |
#chat_upload_zone {
|
| 2661 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2662 |
}
|
| 2663 |
/* 格式要求直接寫在上傳卡片裡,跟卡片本身有明顯區隔但仍在同一張卡片內,
|
| 2664 |
使用者不用往上捲回對話視窗找 AI 說過的規則 */
|
|
@@ -3052,7 +3059,7 @@ a:hover { color: var(--c-link-hover); }
|
|
| 3052 |
.canvas-scroll { overflow-y: visible !important; min-height: 0 !important; }
|
| 3053 |
}
|
| 3054 |
@media (max-width: 768px) {
|
| 3055 |
-
.app-header
|
| 3056 |
.tabitem { padding: 1rem .75rem !important; }
|
| 3057 |
.app-header .steps { gap: 3px; }
|
| 3058 |
.step-pill { font-size: 0.62rem; padding: 2px 7px; }
|
|
@@ -3079,9 +3086,7 @@ a:hover { color: var(--c-link-hover); }
|
|
| 3079 |
# 同一批修掉(見 _CUSTOM_CSS 對應區塊)。
|
| 3080 |
_DARK_MODE_HEAD_CSS = """
|
| 3081 |
<style>
|
| 3082 |
-
.app-header
|
| 3083 |
-
.app-header .subtitle,
|
| 3084 |
-
.app-header .subtitle-3 {
|
| 3085 |
background-image: linear-gradient(130deg, var(--c-accent-strong) 0%, var(--c-accent2) 55%, var(--c-accent3) 100%) !important;
|
| 3086 |
-webkit-background-clip: text !important;
|
| 3087 |
background-clip: text !important;
|
|
@@ -3569,10 +3574,12 @@ def create_app():
|
|
| 3569 |
elem_id="nav_report_btn", elem_classes=["result-nav-btn"], variant="secondary",
|
| 3570 |
)
|
| 3571 |
|
| 3572 |
-
with gr.Column(scale=
|
|
|
|
|
|
|
|
|
|
| 3573 |
chatbot = gr.Chatbot(
|
| 3574 |
show_label=False,
|
| 3575 |
-
height=400,
|
| 3576 |
elem_classes=["main-chat"],
|
| 3577 |
)
|
| 3578 |
# Phase 8(千卉實測後回頭調整):對話輸入框改回「常駐顯示、
|
|
@@ -3589,6 +3596,7 @@ def create_app():
|
|
| 3589 |
sources=[],
|
| 3590 |
placeholder="對話輸入框(功能開發中)",
|
| 3591 |
show_label=False,
|
|
|
|
| 3592 |
)
|
| 3593 |
|
| 3594 |
with gr.Column(scale=7, min_width=380, elem_classes=["canvas-col"]):
|
|
|
|
| 1394 |
def _build_header_html(done_steps: list = None, current_step: int = None,
|
| 1395 |
failed_step: int = None) -> str:
|
| 1396 |
"""
|
| 1397 |
+
產生完整標題區塊 HTML(精簡單行產品名+動態步驟列),確定性、不依賴 LLM。
|
| 1398 |
+
2026-07-23 千卉回報原本三行大標題+額外進度條佔比過高,改成單行精簡
|
| 1399 |
+
產品名、拿掉進度條(進度資訊本來就已經完整表達在步驟列的已完成/進行中
|
| 1400 |
+
/失敗三種狀態上,進度條是重複資訊)。
|
| 1401 |
done_steps: 已完成步驟(1-based list)
|
| 1402 |
current_step: 目前執行步驟(1-based int)
|
| 1403 |
failed_step: 執行失敗時卡住的步驟(1-based int),失敗時該步驟改用失敗樣式,
|
|
|
|
| 1428 |
f'<span class="step-num">{num}</span>{name}</span>'
|
| 1429 |
)
|
| 1430 |
|
|
|
|
|
|
|
| 1431 |
return (
|
| 1432 |
'<div class="app-header">'
|
| 1433 |
+
' <p class="title-line">譯彩紛呈 <span class="en">SpectraEngine</span></p>'
|
|
|
|
|
|
|
| 1434 |
f' <div class="steps">{"".join(pills)}</div>'
|
|
|
|
| 1435 |
'</div>'
|
| 1436 |
)
|
| 1437 |
|
|
|
|
| 1845 |
padding: 0 0 1.5rem !important;
|
| 1846 |
}
|
| 1847 |
/* .gradio-container 內部還包了一層 Gradio 自己的 .app(class="main fillable app")
|
| 1848 |
+
wrapper。原本以為是它的左右 padding 造成貼不到邊界,歸零後留白仍在;
|
| 1849 |
+
千卉 2026-07-23 截圖回報四邊仍有留白,重新用 devtools 沿著
|
| 1850 |
+
.main-layout-row 往上逐層量 computed style 才找到真因:.app 被 Gradio
|
| 1851 |
+
設了 `max-width:1280px` 搭配 auto 置中的 margin-left(量到 77.5px =
|
| 1852 |
+
(1435-1280)/2,抓包抓得很準),是 margin 不是 padding。真正修法是拿掉
|
| 1853 |
+
max-width 限制、margin 歸零,padding 那條規則留著無害但其實沒解決過
|
| 1854 |
+
問題。 */
|
| 1855 |
.app {
|
| 1856 |
padding-left: 0 !important;
|
| 1857 |
padding-right: 0 !important;
|
| 1858 |
+
max-width: 100% !important;
|
| 1859 |
+
margin-left: 0 !important;
|
| 1860 |
+
margin-right: 0 !important;
|
| 1861 |
}
|
| 1862 |
*, *::before, *::after { box-sizing: border-box; }
|
| 1863 |
/* 全域安全網(陷阱 13 第 3 點):Gradio 的 markdown 渲染統一包在
|
|
|
|
| 1867 |
字級仍留給各自的選擇器決定,這裡不覆寫 font-size。 */
|
| 1868 |
.md { display: block !important; }
|
| 1869 |
|
| 1870 |
+
/* ── 2. HEADER(卡片化,2026-07-23 精簡成單行)───────────────────── */
|
| 1871 |
.app-header {
|
| 1872 |
+
display: flex;
|
| 1873 |
+
align-items: center;
|
| 1874 |
+
flex-wrap: wrap;
|
| 1875 |
+
gap: .9rem;
|
| 1876 |
+
text-align: left;
|
| 1877 |
+
padding: .85rem 1.25rem;
|
| 1878 |
position: relative;
|
| 1879 |
margin: 1rem 0 1.25rem;
|
| 1880 |
border: 1px solid var(--c-border);
|
|
|
|
| 1899 |
`background-image: linear-gradient(...) !important;` 這個子屬性本身,
|
| 1900 |
跳過簡寫展開的解析路徑——已用瀏覽器 devtools 即時修改驗證過,改長寫法
|
| 1901 |
後漸層立即正常顯示。*/
|
| 1902 |
+
.app-header .title-line {
|
| 1903 |
font-family: 'Crimson Pro', 'Noto Serif TC', Georgia, serif !important;
|
| 1904 |
+
font-size: 1.3rem !important;
|
| 1905 |
font-weight: 700 !important;
|
| 1906 |
-webkit-background-clip: text;
|
| 1907 |
-webkit-text-fill-color: transparent;
|
| 1908 |
background-clip: text;
|
| 1909 |
+
margin: 0 !important;
|
| 1910 |
letter-spacing: -.01em;
|
| 1911 |
line-height: 1.2 !important;
|
| 1912 |
+
white-space: nowrap;
|
| 1913 |
+
flex: none;
|
| 1914 |
}
|
| 1915 |
+
.app-header .title-line .en {
|
| 1916 |
+
font-size: 1.05rem !important;
|
| 1917 |
+
font-weight: 600 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1918 |
}
|
| 1919 |
.badge {
|
| 1920 |
display: inline-flex; align-items: center; gap: 4px;
|
|
|
|
| 1936 |
color: var(--c-accent2-strong);
|
| 1937 |
border: 1px solid rgba(var(--c-accent2-rgb),.30);
|
| 1938 |
}
|
| 1939 |
+
/* step indicators:2026-07-23 header 改單行版面後,steps 改成跟標題
|
| 1940 |
+
同一行左右排列(flex-wrap 讓視窗窄時自動換行),不再置中、不再需要
|
| 1941 |
+
靠 margin-top 跟上方大標題拉開距離(間距已交給 .app-header 的 gap) */
|
| 1942 |
.app-header .steps {
|
| 1943 |
+
display: flex; justify-content: flex-start; flex-wrap: wrap;
|
| 1944 |
+
gap: 4px; margin: 0; flex: 1 1 auto; min-width: 0;
|
| 1945 |
}
|
| 1946 |
.step-pill {
|
| 1947 |
display: inline-flex; align-items: center; gap: 6px;
|
|
|
|
| 2008 |
background: #dc2626;
|
| 2009 |
color: #fff;
|
| 2010 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2011 |
/* ── 3. TABS ───────────────────────────────────────────────────── */
|
| 2012 |
/* 注意:這裡原本用 backdrop-filter 做毛玻璃效果,搭配 position: sticky
|
| 2013 |
會讓瀏覽器每個捲動影格都要重新計算模糊,頁面一長(大表格、多張圖)就會
|
|
|
|
| 2092 |
overflow-y: auto !important;
|
| 2093 |
overflow-x: hidden !important;
|
| 2094 |
}
|
| 2095 |
+
/* 2026-07-23:.main-chat 外層改用 flex-grow 決定高度(見「5b. COLUMN
|
| 2096 |
+
LAYOUT」區塊的 5:1 比例設定),中間這層 wrapper 也要跟著撐滿,
|
| 2097 |
+
高度才會一路傳到 bubble-wrap,捲動區域才會是「剩下的全部空間」
|
| 2098 |
+
而不是「內容多高就多高」。 */
|
| 2099 |
+
.main-chat > div,
|
| 2100 |
+
.main-chat [class*="wrapper"] {
|
| 2101 |
+
flex: 1 1 auto !important;
|
| 2102 |
+
min-height: 0 !important;
|
| 2103 |
+
display: flex !important;
|
| 2104 |
+
flex-direction: column !important;
|
| 2105 |
+
}
|
| 2106 |
|
| 2107 |
/* 訊息從頂部開始排列,消除空白 */
|
| 2108 |
div[role="log"].bubble-wrap,
|
|
|
|
| 2330 |
display: flex !important;
|
| 2331 |
flex-direction: column !important;
|
| 2332 |
flex-wrap: nowrap !important;
|
| 2333 |
+
gap: 1rem !important;
|
| 2334 |
height: calc(100vh - 150px) !important;
|
| 2335 |
+
overflow: hidden !important;
|
|
|
|
| 2336 |
min-width: 0 !important;
|
| 2337 |
}
|
| 2338 |
+
/* 對話視窗:輸入框高度比例 5:1(千卉要求,2026-07-23)。用 flex-grow
|
| 2339 |
+
依 chat-col 當下的可用高度分配,不寫死 px,縮放視窗時比例仍會維持;
|
| 2340 |
+
chatbot 元件不再用 Gradio 原生 height= 參數(那是寫死 px),改讓外層
|
| 2341 |
+
wrapper 高度完全交給 flex 決定。訊息列表本身的捲動仍是 Gradio 原生
|
| 2342 |
+
行為(.bubble-wrap 內部自己有捲軸),外層 wrapper 用 overflow:hidden
|
| 2343 |
+
避免出現雙捲軸。 */
|
| 2344 |
+
.main-chat {
|
| 2345 |
+
flex: 6 1 0 !important;
|
| 2346 |
+
min-height: 0 !important;
|
| 2347 |
+
height: auto !important;
|
| 2348 |
+
overflow: hidden !important;
|
| 2349 |
+
display: flex !important;
|
| 2350 |
+
flex-direction: column !important;
|
| 2351 |
+
}
|
| 2352 |
/* canvas-col 本身「不」捲動——它只負責把步驟列(固定)跟 canvas-scroll
|
| 2353 |
(捲動)疊在一起、限制在同一個總高度內。踩坑記錄:原本想讓步驟列用
|
| 2354 |
position:sticky 貼在 canvas-col 頂端,但 sticky 元素只能在「自己最近的
|
|
|
|
| 2424 |
}
|
| 2425 |
.homepage-hero h1 {
|
| 2426 |
margin: 1rem 0 .6rem; font-size: 2.1rem; line-height: 1.3; font-weight: 700;
|
| 2427 |
+
/* 同 .app-header .title-line 的漸層文字踩坑(見 _DARK_MODE_HEAD_CSS 上方註解):
|
| 2428 |
background 簡寫在瀏覽器展開成子屬性時 background-image 會解析成
|
| 2429 |
空值,改直接寫 background-image 這個子屬性本身即可 */
|
| 2430 |
background-image: linear-gradient(100deg, var(--c-accent) 10%, var(--c-accent2) 90%);
|
|
|
|
| 2653 |
margin: .6rem 0 0 !important;
|
| 2654 |
width: 100% !important;
|
| 2655 |
}
|
| 2656 |
+
/* 2026-07-23:chat-col 改成 gap:1rem 的 flex 欄,跟 chatbot 之間的留白
|
| 2657 |
+
已經由 gap 統一處理,這裡不用再疊加 margin-top(舊註解提到的「技術
|
| 2658 |
+
執行紀錄」分組已在 Phase 8-B 搬去 canvas-col,跟這裡無關,是過期
|
| 2659 |
+
說明)。改成跟 .main-chat 同一套 5:1 flex-grow 比例分配高度。 */
|
| 2660 |
#chat_upload_zone {
|
| 2661 |
+
flex: 1 1 0 !important;
|
| 2662 |
+
min-height: 0 !important;
|
| 2663 |
+
display: flex !important;
|
| 2664 |
+
flex-direction: column !important;
|
| 2665 |
+
}
|
| 2666 |
+
#chat_upload_zone .multimodal-textbox,
|
| 2667 |
+
#chat_upload_zone textarea {
|
| 2668 |
+
height: 100% !important;
|
| 2669 |
}
|
| 2670 |
/* 格式要求直接寫在上傳卡片裡,跟卡片本身有明顯區隔但仍在同一張卡片內,
|
| 2671 |
使用者不用往上捲回對話視窗找 AI 說過的規則 */
|
|
|
|
| 3059 |
.canvas-scroll { overflow-y: visible !important; min-height: 0 !important; }
|
| 3060 |
}
|
| 3061 |
@media (max-width: 768px) {
|
| 3062 |
+
.app-header .title-line { font-size: 1.1rem !important; }
|
| 3063 |
.tabitem { padding: 1rem .75rem !important; }
|
| 3064 |
.app-header .steps { gap: 3px; }
|
| 3065 |
.step-pill { font-size: 0.62rem; padding: 2px 7px; }
|
|
|
|
| 3086 |
# 同一批修掉(見 _CUSTOM_CSS 對應區塊)。
|
| 3087 |
_DARK_MODE_HEAD_CSS = """
|
| 3088 |
<style>
|
| 3089 |
+
.app-header .title-line {
|
|
|
|
|
|
|
| 3090 |
background-image: linear-gradient(130deg, var(--c-accent-strong) 0%, var(--c-accent2) 55%, var(--c-accent3) 100%) !important;
|
| 3091 |
-webkit-background-clip: text !important;
|
| 3092 |
background-clip: text !important;
|
|
|
|
| 3574 |
elem_id="nav_report_btn", elem_classes=["result-nav-btn"], variant="secondary",
|
| 3575 |
)
|
| 3576 |
|
| 3577 |
+
with gr.Column(scale=3, min_width=280, elem_classes=["chat-col"]):
|
| 3578 |
+
# 高度不再寫死 px,改用 CSS flex-grow 讓對話視窗跟輸入框依
|
| 3579 |
+
# chat-col 當下的可用高度按 5:1 比例分配(見 .main-chat/
|
| 3580 |
+
# #chat_upload_zone 的 flex 設定),視窗縮放時比例仍會維持。
|
| 3581 |
chatbot = gr.Chatbot(
|
| 3582 |
show_label=False,
|
|
|
|
| 3583 |
elem_classes=["main-chat"],
|
| 3584 |
)
|
| 3585 |
# Phase 8(千卉實測後回頭調整):對話輸入框改回「常駐顯示、
|
|
|
|
| 3596 |
sources=[],
|
| 3597 |
placeholder="對話輸入框(功能開發中)",
|
| 3598 |
show_label=False,
|
| 3599 |
+
lines=3,
|
| 3600 |
)
|
| 3601 |
|
| 3602 |
with gr.Column(scale=7, min_width=380, elem_classes=["canvas-col"]):
|