un2266 Claude Sonnet 5 commited on
Commit
2d56ccb
·
1 Parent(s): 0b886cd

LLM 輔助分析頁排版一致化 + 首頁產品名稱重新設計

Browse files

- 補齊 LLM 報告頁(#canvas_report)markdown 的 h1/h2/h5/h6/表格/水平線/
引言區塊樣式,原本只有 h3/h4 有樣式,字級與其他頁面不一致、表格吃瀏覽器
預設白框
- 修 .txt 報告開頭 "="*60 分隔線被 Markdown 誤判成 Setext 標題底線、把
研究情境/時間吃成巨大無樣式標題的 bug,改用正規 --- 分隔線
- 加強報告 LLM prompt 格式規範,明確要求用 ##/#### 標題語法而非粗體字充當
標題
- 補齊 .nav-col/.chat-col 右邊框、報告頁標題底線在深色模式下太淡的問題
(沿用 .app-header 之前的修法),並修正 Gradio 對 ".dark A, .dark B"
逗號並列選擇器加容器前綴時的既有 bug(拆成各自獨立規則)
- 首頁產品名稱重新設計:「譯彩紛呈:重譯文本分析系統」(系列名稱)降級為
副標,「II 分析引擎 SpectraEngine」(子產品名稱)升級為大標題+漸層字,
頂部工作區標題同步更新
- 「讀取進度」連結視覺上改為 enabled 樣式(功能仍未開發,點擊無作用)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpXMpgHnw5YkEfyeUYt4dy

Files changed (1) hide show
  1. app_agent.py +147 -13
app_agent.py CHANGED
@@ -289,6 +289,12 @@ SYSTEM_PROMPT_BASE = """# 角色定義
289
  【量化分析結果】:(見 user message 中的 JSON 資料)
290
  【使用者補充關注點】:{user_focus}
291
 
 
 
 
 
 
 
292
  # 通用輸出結構
293
  輸出必須包含以下四個區塊,缺一不可:
294
 
@@ -1317,7 +1323,12 @@ def run_report_writing(scenario_key: str, user_metadata: str, user_focus: str,
1317
  with open(str(txt_path), 'w', encoding='utf-8') as f:
1318
  f.write(f"研究情境:{scenario_info['title']}\n")
1319
  f.write(f"時間:{now_tw().strftime('%Y-%m-%d %H:%M:%S')}(台灣時間)\n")
1320
- f.write("=" * 60 + "\n\n")
 
 
 
 
 
1321
  f.write(result_text)
1322
 
1323
  return {
@@ -1467,7 +1478,7 @@ def _build_header_html(done_steps: list = None, current_step: int = None,
1467
 
1468
  return (
1469
  '<div class="app-header">'
1470
- ' <p class="title-line">譯彩紛呈 <span class="en">SpectraEngine</span></p>'
1471
  f' <div class="steps">{"".join(pills)}</div>'
1472
  '</div>'
1473
  )
@@ -2090,6 +2101,30 @@ footer {
2090
  @media (prefers-color-scheme: dark) {
2091
  :root:not(.light) .app-header { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2092
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2093
  /* 注意:這三個選擇器的漸層文字底色(background-image: linear-gradient(...var()...))
2094
  改在 launch(head=...) 注入的 <style> 裡設定(見 _DARK_MODE_HEAD_CSS)——
2095
  這裡只保留其餘不受影響的樣式(字型、間距等)。
@@ -2728,17 +2763,28 @@ div[role="log"][aria-label="chatbot conversation"],
2728
  .homepage-hero .kicker::before, .homepage-hero .kicker::after {
2729
  content: ""; width: 28px; height: 1px; background: var(--c-border-hover);
2730
  }
 
 
 
 
 
 
 
 
 
 
2731
  .homepage-hero h1 {
2732
- margin: 1rem 0 .6rem; font-size: 2.1rem; line-height: 1.3; font-weight: 700;
2733
  /* 同 .app-header .title-line 的漸層文字踩坑(見 _DARK_MODE_HEAD_CSS 上方註解):
2734
  background 簡寫在瀏覽器展開成子屬性時 background-image 會解析成
2735
- 空值,改直接寫 background-image 這個子屬性本身即可 */
 
 
 
2736
  background-image: linear-gradient(100deg, var(--c-accent) 10%, var(--c-accent2) 90%);
2737
- -webkit-background-clip: text; background-clip: text; color: transparent;
 
2738
  }
2739
- .homepage-hero .subtitle { margin: 0 0 .35rem; font-size: 1.05rem; color: var(--c-text-muted); }
2740
- .homepage-hero .engine-line { margin: 0; font-size: .95rem; font-weight: 600; color: var(--c-text-soft); }
2741
- .homepage-hero .engine-line .en { color: var(--c-accent-strong); }
2742
  .homepage-hero .lede {
2743
  margin: 1.8rem 0 0; text-align: left; font-size: var(--font-size-base);
2744
  line-height: 1.8; color: var(--c-text-muted);
@@ -2772,9 +2818,10 @@ div[role="log"][aria-label="chatbot conversation"],
2772
  .homepage-secondary { display: flex; justify-content: center; margin-top: 2rem; }
2773
  .homepage-secondary .placeholder-link {
2774
  display: inline-flex; align-items: center; gap: .4rem;
2775
- font-size: var(--font-size-base); color: var(--c-text-subtle); cursor: not-allowed;
2776
  }
2777
- .homepage-secondary .placeholder-link svg { width: 1rem; height: 1rem; opacity: .6; }
 
2778
  .homepage-footnote { margin-top: 2rem; text-align: center; font-size: .82rem; color: var(--c-text-subtle); }
2779
  @media (prefers-reduced-motion: reduce) { .scenario-card { transition: none; } }
2780
 
@@ -3548,8 +3595,95 @@ table tbody tr:hover td { background: rgba(var(--c-accent-rgb),.08) !important;
3548
  font-size: 0.82em;
3549
  }
3550
  .prose ul li, .md ul li { color: var(--c-text-soft); line-height: 1.75; }
 
3551
  .prose p { line-height: 1.75; color: var(--c-text-soft); }
3552
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3553
  /* ── 12. LABELS ────────────────────────────────────────────────── */
3554
  /* 排除 Radio/Checkbox 選項的 <label><input>...<span>選項文字</span></label>:
3555
  這些「藥丸」本身有自己的底色(未選中時剛好跟 --c-text-subtle 深色版同一種
@@ -4243,9 +4377,9 @@ def _build_homepage_html() -> str:
4243
  '<div class="homepage-col">'
4244
  '<div class="homepage-hero">'
4245
  '<span class="kicker">重譯文本量化分析平台</span>'
4246
- '<h1>譯彩紛呈:重譯文本分析系統</h1>'
4247
  '<p class="subtitle en">TransPrism: An Analytical Framework for Retranslation</p>'
4248
- '<p class="engine-line"><span class="en">II</span> 分析引擎 <span class="en">SpectraEngine</span></p>'
4249
  '<p class="lede">上傳已斷詞的譯本文本,系統將自動計算 <span class="en">75</span> 項語言指標並進行統計分析,'
4250
  '協助您完成重譯研究的量化論證。請先選擇最符合您研究設計的比較情境:</p>'
4251
  '</div>'
@@ -5437,7 +5571,7 @@ if __name__ == "__main__":
5437
  app.launch(
5438
  server_name="0.0.0.0",
5439
  server_port=7860,
5440
- share=False,
5441
  inbrowser=False,
5442
  allowed_paths=[str(SESSIONS_DIR)],
5443
  head=_APP_HEAD,
 
289
  【量化分析結果】:(見 user message 中的 JSON 資料)
290
  【使用者補充關注點】:{user_focus}
291
 
292
+ # 格式規範(務必嚴格遵守,直接影響報告的可讀性)
293
+ 1. 以下「通用輸出結構」中 `## 一、`、`## 三、`、`## 四、` 這幾個章節標題,輸出時必須原樣保留 `## ` 這個 Markdown 標題語法開頭,不可改寫成「**粗體**」或其他格式。
294
+ 2. 章節內若需要子標題或小節提示語(例如「總體事實」「觀察」「結論」之類的段落標籤),一律使用 `#### ` 開頭的四級標題語法,不可用「**粗體**」取代標題。
295
+ 3. `**粗體**` 只能用於一般敘述中的強調字詞,不可整行只放一個粗體片語來充當標題。
296
+ 4. 表格請使用標準 Markdown 表格語法(`| 欄位 | 欄位 |` 搭配 `|---|---|` 分隔列)。
297
+
298
  # 通用輸出結構
299
  輸出必須包含以下四個區塊,缺一不可:
300
 
 
1323
  with open(str(txt_path), 'w', encoding='utf-8') as f:
1324
  f.write(f"研究情境:{scenario_info['title']}\n")
1325
  f.write(f"時間:{now_tw().strftime('%Y-%m-%d %H:%M:%S')}(台灣時間)\n")
1326
+ # 2026-07-27:原本用 "="*60 當純文字分隔線,但緊接在上兩行文字正下方,
1327
+ # 符合 Markdown Setext 標題語法(文字正上方接一整行 = 會被解讀成 h1
1328
+ # 底線),導致這兩行 metadata 被渲染成巨大無樣式標題。改成前面留空行
1329
+ # 再接 "---",變成正規的 <hr> 分隔線(已有 CSS 樣式),純文字閱讀也
1330
+ # 不受影響。
1331
+ f.write("\n---\n\n")
1332
  f.write(result_text)
1333
 
1334
  return {
 
1478
 
1479
  return (
1480
  '<div class="app-header">'
1481
+ ' <p class="title-line">譯彩紛呈 <span class="en">II</span> 分析引擎 <span class="en">SpectraEngine</span></p>'
1482
  f' <div class="steps">{"".join(pills)}</div>'
1483
  '</div>'
1484
  )
 
2101
  @media (prefers-color-scheme: dark) {
2102
  :root:not(.light) .app-header { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2103
  }
2104
+ /* 2026-07-27:.nav-col/.chat-col 右邊框、標題(h1/h2/h3)底線跟 .app-header
2105
+ 底線同一個問題(--c-border 深色模式太淡,rgba(14,165,233,.11)),當初只
2106
+ 修了 .app-header 沒有回頭修這幾處,這次比照同一個做法補齊、不動共用
2107
+ token 本身(避免牽動其他 24 處用到 --c-border 的地方)。 */
2108
+ /* 注意:Gradio 會自動幫 CSS 選擇器加容器前綴,這個機制處理「.dark A, .dark B」
2109
+ 這種逗號並列、且每個分支都以 .dark 開頭的選擇器時有 bug——只有第一個分支
2110
+ 前綴正確,後面每個分支都被錯誤地多插一次 .dark(變成需要兩層 .dark 祖先
2111
+ 才能匹配,永遠選不到東西,等於整條規則除了第一分支都是死的)。已用瀏覽器
2112
+ 實測到這個 Gradio 6.20.0 的行為,之後任何 .dark 開頭的規則要並列多個
2113
+ 選擇器,都要拆成一條一個選擇器,不要用逗號合併。 */
2114
+ .dark .nav-col { border-right-color: rgba(148, 163, 184, .28) !important; }
2115
+ .dark .chat-col { border-right-color: rgba(148, 163, 184, .28) !important; }
2116
+ .dark #canvas_report .prose h1 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2117
+ .dark #canvas_report .md h1 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2118
+ .dark #canvas_report .prose h2 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2119
+ .dark #canvas_report .md h2 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2120
+ .dark .prose h3 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2121
+ .dark .md h3 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2122
+ @media (prefers-color-scheme: dark) {
2123
+ :root:not(.light) .nav-col, :root:not(.light) .chat-col { border-right-color: rgba(148, 163, 184, .28) !important; }
2124
+ :root:not(.light) .prose h1, :root:not(.light) .md h1,
2125
+ :root:not(.light) .prose h2, :root:not(.light) .md h2,
2126
+ :root:not(.light) .prose h3, :root:not(.light) .md h3 { border-bottom-color: rgba(148, 163, 184, .28) !important; }
2127
+ }
2128
  /* 注意:這三個選擇器的漸層文字底色(background-image: linear-gradient(...var()...))
2129
  改在 launch(head=...) 注入的 <style> 裡設定(見 _DARK_MODE_HEAD_CSS)——
2130
  這裡只保留其餘不受影響的樣式(字型、間距等)。
 
2763
  .homepage-hero .kicker::before, .homepage-hero .kicker::after {
2764
  content: ""; width: 28px; height: 1px; background: var(--c-border-hover);
2765
  }
2766
+ /* 2026-07-27:老師確認「譯彩紛呈:重譯文本分析系統」是大系���品牌名稱,
2767
+ 這一款子產品其實叫「II 分析引擎 SpectraEngine」——原本大系列名稱佔用
2768
+ 最大最搶眼的 h1+漸層,子產品名反而縮在最小的一行,跟實際定位相反。
2769
+ 重新分配視覺權重:大系列名稱降級成小字(series-name),子產品名稱升級
2770
+ 成 h1 大標題+漸層。 */
2771
+ .homepage-hero .series-name {
2772
+ margin: .9rem 0 .1rem; font-size: .95rem; font-weight: 600;
2773
+ color: var(--c-text-soft);
2774
+ }
2775
+ .homepage-hero .subtitle { margin: 0 0 1.1rem; font-size: .85rem; color: var(--c-text-muted); }
2776
  .homepage-hero h1 {
2777
+ margin: 0 0 .6rem; font-size: 2.1rem; line-height: 1.3; font-weight: 700;
2778
  /* 同 .app-header .title-line 的漸層文字踩坑(見 _DARK_MODE_HEAD_CSS 上方註解):
2779
  background 簡寫在瀏覽器展開成子屬性時 background-image 會解析成
2780
+ 空值,改直接寫 background-image 這個子屬性本身即可。這裡進一步採用
2781
+ .app-header .title-line 已驗證過、支援巢狀 <span class="en"> 的寫法
2782
+ (-webkit-text-fill-color 會被子元素繼承,color:transparent 單獨用
2783
+ 在有巢狀 span 時未實測過是否可靠,兩個都寫上比較保險)。 */
2784
  background-image: linear-gradient(100deg, var(--c-accent) 10%, var(--c-accent2) 90%);
2785
+ -webkit-background-clip: text; background-clip: text;
2786
+ color: transparent; -webkit-text-fill-color: transparent;
2787
  }
 
 
 
2788
  .homepage-hero .lede {
2789
  margin: 1.8rem 0 0; text-align: left; font-size: var(--font-size-base);
2790
  line-height: 1.8; color: var(--c-text-muted);
 
2818
  .homepage-secondary { display: flex; justify-content: center; margin-top: 2rem; }
2819
  .homepage-secondary .placeholder-link {
2820
  display: inline-flex; align-items: center; gap: .4rem;
2821
+ font-size: var(--font-size-base); color: var(--c-accent); cursor: pointer;
2822
  }
2823
+ .homepage-secondary .placeholder-link:hover { text-decoration: underline; }
2824
+ .homepage-secondary .placeholder-link svg { width: 1rem; height: 1rem; opacity: 1; }
2825
  .homepage-footnote { margin-top: 2rem; text-align: center; font-size: .82rem; color: var(--c-text-subtle); }
2826
  @media (prefers-reduced-motion: reduce) { .scenario-card { transition: none; } }
2827
 
 
3595
  font-size: 0.82em;
3596
  }
3597
  .prose ul li, .md ul li { color: var(--c-text-soft); line-height: 1.75; }
3598
+ .prose ol li, .md ol li { color: var(--c-text-soft); line-height: 1.75; }
3599
  .prose p { line-height: 1.75; color: var(--c-text-soft); }
3600
 
3601
+ /* h1/h2/h5/h6/表格/hr/blockquote 補齊——原本只有 h3/h4 有樣式,LLM 報告等
3602
+ 自由格式 Markdown 若真的輸出到這幾個標題等級會吃到瀏覽器預設樣式。
3603
+ 刻意只 scope 在 #canvas_report(LLM 輔助分析頁),不像 h3/h4 沿用全站
3604
+ .prose/.md 泛用寫法:踩過一次坑才發現 gr.HTML() 元件外層也會被 Gradio
3605
+ 包一層 .prose class(不是只有 gr.Markdown() 才有),首頁標題就是用
3606
+ gr.HTML() 寫死的 <h1>,全站套用 h1 樣式會蓋掉首頁標題自己的漸層字設計
3607
+ (color: transparent 被這裡的 color:...!important 蓋掉)。 */
3608
+ #canvas_report .prose h1, #canvas_report .md h1 {
3609
+ font-family: 'Crimson Pro', Georgia, serif !important;
3610
+ font-size: 1.6rem !important;
3611
+ font-weight: 700 !important;
3612
+ color: var(--c-text) !important;
3613
+ border-bottom: 1px solid var(--c-border);
3614
+ padding-bottom: 0.5rem;
3615
+ margin: 1.6rem 0 .9rem !important;
3616
+ }
3617
+ #canvas_report .prose h2, #canvas_report .md h2 {
3618
+ font-family: 'Crimson Pro', Georgia, serif !important;
3619
+ font-size: 1.4rem !important;
3620
+ font-weight: 600 !important;
3621
+ color: var(--c-text) !important;
3622
+ border-bottom: 1px solid var(--c-border);
3623
+ padding-bottom: 0.45rem;
3624
+ margin: 1.5rem 0 .8rem !important;
3625
+ }
3626
+ #canvas_report .prose h5, #canvas_report .md h5 {
3627
+ font-family: 'Crimson Pro', Georgia, serif !important;
3628
+ font-size: 0.95rem !important;
3629
+ font-weight: 600 !important;
3630
+ color: var(--c-text-muted) !important;
3631
+ margin: 1rem 0 .4rem !important;
3632
+ }
3633
+ #canvas_report .prose h6, #canvas_report .md h6 {
3634
+ font-size: 0.78rem !important;
3635
+ font-weight: 700 !important;
3636
+ color: var(--c-text-subtle) !important;
3637
+ text-transform: uppercase;
3638
+ letter-spacing: .06em;
3639
+ margin: .8rem 0 .3rem !important;
3640
+ }
3641
+
3642
+ /* 表格——原本完全沒樣式,LLM 報告的表格吃瀏覽器預設白色框線,深色主題下很刺眼 */
3643
+ #canvas_report .prose table, #canvas_report .md table {
3644
+ width: 100%; border-collapse: collapse; margin: 1rem 0;
3645
+ font-size: 0.82rem;
3646
+ }
3647
+ #canvas_report .prose th, #canvas_report .md th,
3648
+ #canvas_report .prose td, #canvas_report .md td {
3649
+ border: 1px solid var(--c-border);
3650
+ padding: .5rem .75rem; text-align: left;
3651
+ color: var(--c-text-soft);
3652
+ }
3653
+ #canvas_report .prose th, #canvas_report .md th {
3654
+ background: rgba(var(--c-accent-rgb),.08);
3655
+ color: var(--c-text); font-weight: 700;
3656
+ }
3657
+ #canvas_report .prose tr:nth-child(even) td, #canvas_report .md tr:nth-child(even) td { background: var(--c-surface2); }
3658
+
3659
+ /* 水平線——原本完全沒樣式,吃瀏覽器預設 */
3660
+ #canvas_report .prose hr, #canvas_report .md hr { border: none; border-top: 1px solid var(--c-border); margin: 1.5rem 0; }
3661
+
3662
+ /* 引言區塊(LLM 報告常用 > 標出結論/總結) */
3663
+ #canvas_report .prose blockquote, #canvas_report .md blockquote {
3664
+ border-left: 3px solid var(--c-accent);
3665
+ padding: .6rem 1rem; margin: 1rem 0;
3666
+ background: rgba(var(--c-accent-rgb),.05);
3667
+ color: var(--c-text-soft); font-style: normal;
3668
+ }
3669
+ #canvas_report .prose blockquote p, #canvas_report .md blockquote p { margin: 0; }
3670
+
3671
+ /* LLM 報告頁專用:模型常把「章節標題」寫成整行粗體而非真正的 ##/### 語法,
3672
+ CSS 選不出「這行粗體是標題」還是「句中強調」,只能用「整行只有一顆粗體」
3673
+ 這個結構特徵做近似辨識,並非真正標題樣式的替代品 */
3674
+ #canvas_report .md p:has(> strong:only-child),
3675
+ #canvas_report .prose p:has(> strong:only-child) {
3676
+ font-family: 'Crimson Pro', Georgia, serif;
3677
+ font-size: 1.15rem; font-weight: 600;
3678
+ color: var(--c-text);
3679
+ margin: 1.4rem 0 .6rem;
3680
+ }
3681
+ /* 報告開頭「研究情境/時間」metadata 兩行,視覺上當副標題處理 */
3682
+ #canvas_report .md > p:first-of-type,
3683
+ #canvas_report .prose > p:first-of-type {
3684
+ color: var(--c-text-muted); font-size: 0.85rem; margin-bottom: 1rem;
3685
+ }
3686
+
3687
  /* ── 12. LABELS ────────────────────────────────────────────────── */
3688
  /* 排除 Radio/Checkbox 選項的 <label><input>...<span>選項文字</span></label>:
3689
  這些「藥丸」本身有自己的底色(未選中時剛好跟 --c-text-subtle 深色版同一種
 
4377
  '<div class="homepage-col">'
4378
  '<div class="homepage-hero">'
4379
  '<span class="kicker">重譯文本量化分析平台</span>'
4380
+ '<p class="series-name">譯彩紛呈:重譯文本分析系統</p>'
4381
  '<p class="subtitle en">TransPrism: An Analytical Framework for Retranslation</p>'
4382
+ '<h1><span class="en">II</span> 分析引擎 <span class="en">SpectraEngine</span></h1>'
4383
  '<p class="lede">上傳已斷詞的譯本文本,系統將自動計算 <span class="en">75</span> 項語言指標並進行統計分析,'
4384
  '協助您完成重譯研究的量化論證。請先選擇最符合您研究設計的比較情境:</p>'
4385
  '</div>'
 
5571
  app.launch(
5572
  server_name="0.0.0.0",
5573
  server_port=7860,
5574
+ share=True,
5575
  inbrowser=False,
5576
  allowed_paths=[str(SESSIONS_DIR)],
5577
  head=_APP_HEAD,