diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md
index 1598809a..55538834 100644
--- a/docs/BUG_HISTORY.md
+++ b/docs/BUG_HISTORY.md
@@ -20741,4 +20741,4 @@
- 防复发:上面的测试。规则:用 `:not(:has(...))` 隐藏一类元素时,要放出的例外必须写到同等或更高优先级,不能靠元素选择器。
- 相关记录:BUG-1470(顶栏高度与两行问题);同一变更是 2026-11-02 顶栏控件统一 44px 与选择星盘改版。
- 复发自:无
-- 修复版本:分支 `codex/chart-polish-1102`(基于 `origin/staging` cb0a6289),待合并。
+- 修复版本:提交 1cd73bc8(分支 `codex/chart-polish-1102`),2026-11-02 推上 staging。
diff --git a/frontend/src/components/credit-balance-button.tsx b/frontend/src/components/credit-balance-button.tsx
index 8b6f6010..86dd656c 100644
--- a/frontend/src/components/credit-balance-button.tsx
+++ b/frontend/src/components/credit-balance-button.tsx
@@ -1,13 +1,12 @@
"use client";
-import { Orbit } from "lucide-react";
import { useEffect, useRef, useState, type MouseEvent } from "react";
import { Button } from "@/components/ui/button";
import { motionPresets } from "@/lib/motion/presets";
/**
- * The top bar's points control (2026-11-02): an orbit, not a money sign, in the action colour,
+ * The top bar's points control (2026-11-02): a ringed planet, not a money sign, in the action colour,
* the balance, then 「点」. As tall as the person chip beside it (globals.css
* `--chat-header-pill`); the hit area is at least 44px.
*/
@@ -22,13 +21,23 @@ export function CreditBalanceButton({
}) {
return (
);
}
+/** Lucide-style stroke icon. Not Lucide's Orbit: that one already means 「星盘」 in the sidebar and chat toggle. */
+function RingedPlanet({ className }: { readonly className?: string }) {
+ return (
+
+ );
+}
+
function RollingValue({ value }: { readonly value: number | null }) {
const [roll, setRoll] = useState({ value, direction: 1 });
const nodeRef = useRef(null);
diff --git a/frontend/tests/chat-header-pills-and-quiet-cards-20261102.test.tsx b/frontend/tests/chat-header-pills-and-quiet-cards-20261102.test.tsx
index fc80cf55..b694c4ff 100644
--- a/frontend/tests/chat-header-pills-and-quiet-cards-20261102.test.tsx
+++ b/frontend/tests/chat-header-pills-and-quiet-cards-20261102.test.tsx
@@ -113,9 +113,12 @@ test("the person chip and the points pill share one top-bar height token, deskto
assert.match(pointsBody, /display:\s*inline-flex/);
assert.match(pointsBody, /align-items:\s*center/);
assert.match(pointsBody, /border-radius:\s*999px/);
- // No money sign on the points pill: an orbit stands in for the coin.
+ // No money sign on the points pill: a ringed planet stands in for the coin.
+ // 原值: ; 新值: ;
+ // 原因: Orbit already marks 星盘 (sidebar, chat chart toggle), so two orbits sat side by side on phones.
const button = read("../src/components/credit-balance-button.tsx");
- assert.match(button, //);
+ assert.match(button, //);
+ assert.doesNotMatch(button, /import \{[^}]*\bOrbit\b/);
assert.doesNotMatch(button, /CircleDollarSign|Coins|DollarSign/);
// Everything in the bar, the 44px sidebar toggle included, sits on the row's centre line.
assert.match(cssDeclarations(".chat-header", globalStyles), /align-items:\s*center/);
diff --git a/frontend/tests/icon-motion-audit.test.ts b/frontend/tests/icon-motion-audit.test.ts
index 138e9f9b..068ba700 100644
--- a/frontend/tests/icon-motion-audit.test.ts
+++ b/frontend/tests/icon-motion-audit.test.ts
@@ -20,9 +20,9 @@ test("the 2026-09-22 icon audit keeps the existing entry icons and adds no loop"
assert.doesNotMatch(starterHome, /Sparkles|thinking-orbs/);
assert.doesNotMatch(css, /\.starter-entry/);
const credits = readFileSync(new URL("../src/components/credit-balance-button.tsx", import.meta.url), "utf8");
- // 原值(3): `` 新值(3): ``,仍无循环动画
- // 原因(3): 2026-11-02 产品要求点数按钮不用钱币图标
- assert.match(credits, //);
+ // 原值(3): `` 新值(3): ``(自绘带环行星),仍无循环动画
+ // 原因(3): 2026-11-02 产品要求点数按钮不用钱币图标、换成行星;Orbit 已是「星盘」入口图标,不复用
+ assert.match(credits, //);
assert.doesNotMatch(css.slice(css.indexOf(".credit-balance .credit-icon {"), css.indexOf("}", css.indexOf(".credit-balance .credit-icon {"))), /animation:/);
assert.doesNotMatch(css, /thinking-orbs/);
assert.match(css, /@media \(prefers-reduced-motion:\s*reduce\)[\s\S]*transition-duration:\s*\.01ms !important/);
diff --git a/frontend/tests/starter-home-polish-20260926.test.tsx b/frontend/tests/starter-home-polish-20260926.test.tsx
index 3c68257e..ea0a2165 100644
--- a/frontend/tests/starter-home-polish-20260926.test.tsx
+++ b/frontend/tests/starter-home-polish-20260926.test.tsx
@@ -123,10 +123,10 @@ test("D3: the points button is a single coin in the action colour and says how m
const credits = readFileSync(new URL("../src/components/credit-balance-button.tsx", import.meta.url), "utf8");
const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
// 原值(2):`import { CircleDollarSign }`、``(硬币)
- // 新值(2):`import { Orbit }`、``,大小、主色、对齐不变
- // 原因(2):2026-11-02 产品要求点数按钮不用钱币图标,改成像行星的 Orbit
- assert.match(credits, /import \{ Orbit \} from "lucide-react";/);
- assert.match(credits, //);
+ // 新值(2):自绘 ``(带环行星),大小、主色、对齐不变
+ // 原因(2):2026-11-02 产品要求点数按钮不用钱币图标、换成行星;Lucide 的 Orbit 已是「星盘」入口图标,不复用
+ assert.match(credits, /function RingedPlanet\(/);
+ assert.match(credits, //);
assert.doesNotMatch(credits, /CircleDollarSign|Coins|DollarSign/);
assert.match(credits, /点<\/span>/);
assert.match(css, /\.credit-balance \.credit-icon \{[^}]*color: var\(--color-action\);/);