fix(home): split starter fine print, show hints only when actionable (BUG-1041)

TASK-starter-home-polish-20260926:
- D1 today's trend moves to a sub-line under the greeting
  (.starter-greeting-sub), read from the same dailyStarlanguage state the
  warm snapshot seeds; static sentence until ready, hidden without a minute.
- D2 the line under the pills appears only for a resumable case or a
  non-self subject; the first-run and redo sentences are removed.
- BUG-1041 entrySummaryFromResponse read snake_case keys while the
  entry-summary route returns camelCase, so every account parsed as a
  first run; the parser now reads the route's shape (snake_case still ok).
- D3 daily entry icon MoonStar, credits icon Coins; D4 boundary line kept.
- Records: CHANGELOG, DESIGN, VOICE, BUG_HISTORY, PROGRESS, testing list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-26 08:47:53 +08:00
co-authored by Claude Opus 5.5
parent 6d371d82a7
commit b5a02ca861
16 changed files with 427 additions and 68 deletions
+28 -11
View File
@@ -533,7 +533,7 @@ The empty state is the composer. It used to be a bordered hero card at
sitting on top of the input, so the primary action was the last thing on the
page. Three parts now, in reading order:
- **Greeting** (`.starter-greeting-block`): one line, no subtitle — a single h1
- **Greeting** (`.starter-greeting-block`): one line — a single h1
at `clamp(24px, 2.8vw, 30px)`, weight 500, `line-height: 1.25`, centred. The
salutation line above the question is gone; so is the question, which is the
composer placeholder's job now («想聊什么都可以»). The line is drawn per visit
@@ -543,6 +543,14 @@ page. Three parts now, in reading order:
`{名字}` entries dropped when no name is set. It lives in the conversation area
with `align-content: end`, so it sits directly above the composer rather than
floating in the middle of the row.
- **Daily sub-line** (`.starter-greeting-sub`, 2026-09-26): today's trend sits
under the greeting as one quiet paragraph — `--color-ink-secondary`,
`--type-body-sm`, `line-height: 1.55`, `max-width: 560px`, clamped to two
lines with an ellipsis. It reads the same `dailyStarlanguage` state the warm
snapshot seeds (BUG-1040), so a warm return shows it on the first frame. Until
the card is ready it shows the existing static sentence「今天的星语还没写出来。」
with `role="status"` and no `aria-busy`, spinner or placeholder; the reveal
rule does not change. Without a natal minute it is not rendered at all.
- **Composer**: unchanged, and *in the same DOM position it occupies during a
live session*. Nothing remounts when the first message lands, so an in-flight
draft, focus, or queued card survives the transition. Its width is
@@ -552,9 +560,14 @@ page. Three parts now, in reading order:
- **Entry pills** (`.starter-entry`): the two product entrances, rendered inside
`.composer-wrap` *below* the composer. The visual pill is 36px tall
(`min-height: 36px`). The transparent hit area is the `::after` box with
`inset: -4px`, so the touch target is 44px. One word each, accent icon 15px.
Below them one line merges the daily trend with the rectification hint, and
an accuracy-boundary line appears when no natal minute is available.
`inset: -4px`, so the touch target is 44px. One word each, accent icon 15px:
lucide `MoonStar` for 今日星语 (was `Sparkles`, the same glyph as the credits
button) and `Clock3` for 生时校正. The header credits button uses lucide
`Coins`; its accessible name is unchanged. Below the pills there is normally
**nothing**: a hint line (`.starter-entry-hint`) appears only when the user has
something to do, and an accuracy-boundary line appears when no natal minute is
available. The daily trend and the rectification hint are no longer joined
with「·」.
- **States, measured:**
- Default border is `1px solid var(--starter-entry-border)`, and that token is
@@ -585,15 +598,19 @@ page. Three parts now, in reading order:
entrypoint identifier and expanded only on the server. There is no
“从一个主题开始” grid; leftover `guided_topic` values in stored sessions still
pin domains when replayed.
- **Rectification hint** keeps three server-driven branches — an unfinished case,
a finished one that can be redone (`rectificationCardAction === "restart"`),
and a first run. The branch comes from the entry summary, never the session
list.
- **Rectification hint** (`rectificationEntryHint`, 2026-09-26) has two
visible branches and reads the entry summary itself, never the session list
and never the derived start/restart label: a non-self current person →
「生时校正暂时只支持本人。」; otherwise `hasResumableCase` →
「上次那次校正还没完成,可以接着做。」. First runs and finished cases show no
hint. The old first-run and "redo" sentences are gone. (The summary parser had
been reading the wrong key casing since 2026-08-11, so every account looked
like a first run — BUG-1041.)
- **Responsive:** the pill row wraps and stays centred; there is no
phone-specific layout, because there is no fixed-height card to collapse.
- **Accessibility:** each pill is one native button with a descriptive accessible
name (the full action label, not the one-word face). The daily hint keeps
`role="status"` while the trend is still arriving.
name (the full action label, not the one-word face). The daily sub-line keeps
`role="status"` while the trend has not arrived.
### Account popover
@@ -703,7 +720,7 @@ Agent 的 live 标记只有 `InlineSpinner` 一种。曾经并存的 canvas 小
**每次打开网页只揭幕一次,客户端返回首页走暖快照(2026-09-26,BUG-1040)。** 整页加载(首次打开、刷新、登录后跳转)照旧放下面这一次加载屏。同一次打开里从星盘 / 星历 / 我的报告 / 星盘档案经侧栏「新建对话」、历史会话行、账户页脚或浏览器返回回到 `/`,不再出现加载环:第一次冷启动成功后,模型目录、校正入口摘要、会话分页游标和今日星语记进模块级暖快照(`lib/home-warm-snapshot.ts`,按账户隔离、只在内存、不落任何存储;账户、资料与会话列表本来就在布局层的会话列表 provider 里跨页存活)。首页重挂时若快照齐全,首帧即可用,落点按冷启动同一套规则同步算出(`?new=1` 新建本地空对话、`?c=` 打开该会话、登录返回存根与其人物范围同 BUG-1038),随后后台刷新模型目录、账户、后台回答恢复、入口摘要与今日星语,结果到了静默替换;消息没缓存的历史会话沿用首页内切换会话的留白方式。快照缺任何一项、落点需要去服务端查、或客户端导航没留下目标地址(Next 先渲染新页面、后写地址栏,`AppLink` 在点击时记下目标),一律回到冷启动,不半揭幕。账户变化、退出、任一 401 清空快照;今日星语跨日或换人按新键重取,卡片先用静态句。
首页只揭幕一次。揭幕前的加载屏先并行取账户 / 会话、模型目录和咨询状态,再等待 lookup、会话详情等依赖数据全部到齐;不设 8 秒硬超时,超过 `HOME_BOOTSTRAP_SLOW_MS = 20_000` 才进入现有全屏错误屏。错误屏的「重试」只取消旧请求、重载 provider 并局部重跑 bootstrap,不调用 `location.reload()`。揭幕后不得再出现任何阻塞等待或组件级 spinner:今日星语未到显示静态文案「今天的星语还没写出来。」(不带 `aria-busy`),校正卡用无摘要文案,内容到达后静默替换。登录后的空首页只剩问候语、今日星语卡、生时校正卡和输入框,没有主题卡。切换到消息尚未缓存的会话时消息区留白并只给 `sr-only` 文案,不转圈;揭幕后按侧栏顺序后台预取最近 5 条会话(`SESSION_PREFETCH_COUNT`)让常见切换零等待。轨道环消失后不得再换一套动效继续等。
首页只揭幕一次。揭幕前的加载屏先并行取账户 / 会话、模型目录和咨询状态,再等待 lookup、会话详情等依赖数据全部到齐;不设 8 秒硬超时,超过 `HOME_BOOTSTRAP_SLOW_MS = 20_000` 才进入现有全屏错误屏。错误屏的「重试」只取消旧请求、重载 provider 并局部重跑 bootstrap,不调用 `location.reload()`。揭幕后不得再出现任何阻塞等待或组件级 spinner:今日星语未到时问候下方副行显示静态文案「今天的星语还没写出来。」(不带 `aria-busy`),校正卡用无摘要文案,内容到达后静默替换。登录后的空首页只剩问候语、今日星语卡、生时校正卡和输入框,没有主题卡。切换到消息尚未缓存的会话时消息区留白并只给 `sr-only` 文案,不转圈;揭幕后按侧栏顺序后台预取最近 5 条会话(`SESSION_PREFETCH_COUNT`)让常见切换零等待。轨道环消失后不得再换一套动效继续等。
### 首屏死屏兜底