From 8a0178e4dc335135640007efc0f2701f626ff351 Mon Sep 17 00:00:00 2001 From: MrSibe Date: Wed, 30 Sep 2026 15:51:24 +0800 Subject: [PATCH] feat(ui): widen the home and chat canvases and cap answers at 88ch --- DESIGN.md | 34 ++++-- src/renderer/src/assets/theme.css | 20 +++- src/renderer/src/components/home/Home.tsx | 4 +- .../src/components/notebook/ProcessPanel.tsx | 111 +++++++++--------- .../components/notebook/chat/MessageItem.tsx | 2 +- .../components/notebook/chat/MessageList.tsx | 8 +- 6 files changed, 103 insertions(+), 76 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index f31e64d..069f880 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -647,24 +647,36 @@ express selection — pair it with `bg-surface-selected`. Line height: UI text uses Tailwind defaults. Long-form reading surfaces (`markdown.css`, `noteEditor.css`) use 14px / `line-height: 1.75`. -**Measure.** A long-form reading surface is capped at `--reading-measure` (72ch) -and centred: +**Measure.** There are two widths, because a workspace and a reading column are +different things. + +A long-form reading surface is capped at `--reading-measure` (72ch) and centred: ```tsx
``` -The chat transcript (`MessageList.tsx`) and the note editor (`NoteEditor.tsx`, -`p-4`) both read the token, so a paragraph is the same width on either surface. -Widening a panel adds margin around the column; it must never lengthen the line — -uncapped, a 1000px centre panel sets an answer at roughly 130 characters per -line. The token is defined once in `theme.css`; take it as a variant rather than +The note editor (`NoteEditor.tsx`, `p-4`) is that surface. Widening a panel adds +margin around the column; it must never lengthen the line — uncapped, a 1000px +centre panel sets prose at roughly 130 characters per line. + +The chat transcript is not a reading column. Its canvas — the notebook header, +the empty state and the message list in `MessageList.tsx` — is `max-w-5xl` +(~1024px), the same width as the home page, so a wide centre panel is actually +used. Inside that canvas an answer is capped at `--answer-measure` (88ch) rather +than by `--reading-measure`: an answer carries tables and code as often as prose, +and a paragraph at 88ch is still inside a comfortable band. A user message keeps +its narrower bubble. The composer (`ProcessPanel.tsx`) is centred on the same +`max-w-5xl` canvas, so the input lines up with the transcript it answers. + +Both tokens are defined once in `theme.css`; take them as variants rather than hard-coding a `ch` value or a pixel width. -The source reader does **not** read it yet, and the reason is a contract rather -than an oversight: `TextSourceReader` measures its highlight rectangles once from -the laid-out range, so a column that re-centres on resize would strand the -highlight. Make that measurement resize-aware before capping that surface. +The source reader does **not** read `--reading-measure` yet, and the reason is a +contract rather than an oversight: `TextSourceReader` measures its highlight +rectangles once from the laid-out range, so a column that re-centres on resize +would strand the highlight. Make that measurement resize-aware before capping +that surface. ## Accent and states diff --git a/src/renderer/src/assets/theme.css b/src/renderer/src/assets/theme.css index 99816ae..6ded888 100644 --- a/src/renderer/src/assets/theme.css +++ b/src/renderer/src/assets/theme.css @@ -87,10 +87,14 @@ /* * The measure long-form content is set to, in `ch` so it follows the font. - * Every reading surface shares it — the chat transcript and the note editor - * today — so a paragraph is the same width wherever it is read, and widening - * a panel adds margin instead of lengthening the line. 72ch at 14px Inter is - * roughly 600px, inside the 65–75ch band a body copy line wants. + * Every long-form reading surface shares it — the note editor today — so a + * paragraph is the same width wherever it is read, and widening a panel adds + * margin instead of lengthening the line. 72ch at 14px Inter is roughly 600px, + * inside the 65–75ch band a body copy line wants. + * + * The chat transcript is deliberately not one of them: a workspace is wider + * than a reading column, so its canvas is `max-w-5xl` and the answer inside it + * is capped by `--answer-measure`. See DESIGN.md, "Measure". * * The source reader is the one surface that does not read this yet: its * highlight rectangles are measured once from the laid-out range @@ -99,6 +103,14 @@ */ --reading-measure: 72ch; + /* + * The chat answer's measure. Wider than `--reading-measure` because an answer + * carries tables and code as often as prose, and the chat canvas is a workspace + * rather than a page; still capped so a line stays readable when the centre + * panel is dragged wide. 88ch at 14px Inter is roughly 740px. + */ + --answer-measure: 88ch; + --font-sans: 'Inter', sans-serif; --font-serif: 'Lora', serif; --font-mono: 'Fira Code', monospace; diff --git a/src/renderer/src/components/home/Home.tsx b/src/renderer/src/components/home/Home.tsx index d770fd9..a76250d 100644 --- a/src/renderer/src/components/home/Home.tsx +++ b/src/renderer/src/components/home/Home.tsx @@ -95,7 +95,7 @@ export default function Home({ if (notebooks.length === 0) { return ( -
+
{header} @@ -119,7 +119,7 @@ export default function Home({ return ( -
+
{header} - {/* 范围选择(#94):这次问题用哪些来源回答。放在输入框上方,跟在要提问的地方。 */} - {currentSession && ( - void setSessionScope(currentSession.id, next)} + {/* Centred on the same canvas as the transcript: the input and the answers + it produces line up, so a wide panel adds margin to both instead of + stretching the composer past the text it is answering. */} +
+
+ {/* 范围选择(#94):这次问题用哪些来源回答。放在输入框上方,跟在要提问的地方。 */} + {currentSession && ( + void setSessionScope(currentSession.id, next)} + /> + )} + + {/* 多行输入框 */} +