@@ -47,6 +47,35 @@ interface UsageReadingHintProps {
4747 tone : "ok" | "warn" | "info" ;
4848}
4949
50+ /** 页面级配色:每个 surface 都显式维护 light 与 dark 两套颜色,避免主题切换时只继承单套颜色。 */
51+ const USAGE_PAGE_COLORS = {
52+ shell :
53+ "border-slate-200 bg-white text-slate-950 dark:border-slate-700/80 dark:bg-slate-950/30 dark:text-slate-100" ,
54+ header :
55+ "bg-gradient-to-r from-sky-50 via-white to-emerald-50 dark:from-blue-950/45 dark:via-slate-900 dark:to-emerald-950/30" ,
56+ chip : "border-slate-200 bg-white/80 text-slate-600 dark:border-slate-700/80 dark:bg-slate-950/40 dark:text-slate-300" ,
57+ guide :
58+ "border-sky-200 bg-sky-50/80 text-sky-950 dark:border-blue-700/40 dark:bg-blue-950/15 dark:text-blue-100" ,
59+ guideStep :
60+ "border-sky-200 bg-white/90 text-slate-950 dark:border-blue-700/40 dark:bg-slate-950/40 dark:text-slate-100" ,
61+ card : "border-slate-200 bg-white text-slate-950 dark:border-slate-700/80 dark:bg-slate-950/30 dark:text-slate-100" ,
62+ inset :
63+ "border-slate-200 bg-slate-50 text-slate-950 dark:border-slate-700/70 dark:bg-slate-950/40 dark:text-slate-100" ,
64+ progressTrack : "bg-slate-200 dark:bg-slate-800" ,
65+ warning :
66+ "border-amber-200 bg-amber-50 text-amber-950 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100" ,
67+ warningButton :
68+ "border-amber-300 bg-white text-amber-950 hover:bg-amber-100 dark:border-amber-700 dark:bg-slate-950/40 dark:text-amber-100 dark:hover:bg-amber-900/40" ,
69+ resetSummary : "bg-sky-100 text-sky-800 dark:bg-sky-500/10 dark:text-sky-300" ,
70+ } ;
71+
72+ /** 读数提示卡配色:ok/warn/info 各自维护浅色和深色配色。 */
73+ const READING_HINT_COLORS : Record < UsageReadingHintProps [ "tone" ] , string > = {
74+ ok : "border-emerald-200 bg-emerald-50 text-emerald-950 dark:border-emerald-700/40 dark:bg-emerald-950/20 dark:text-emerald-100" ,
75+ warn : "border-amber-200 bg-amber-50 text-amber-950 dark:border-amber-700/40 dark:bg-amber-950/20 dark:text-amber-100" ,
76+ info : "border-sky-200 bg-sky-50 text-sky-950 dark:border-blue-700/40 dark:bg-blue-950/20 dark:text-blue-100" ,
77+ } ;
78+
5079/** 将百分比限制在进度条可安全渲染的 0-100 区间。 */
5180function clampPercent ( value : number ) : number {
5281 if ( ! Number . isFinite ( value ) ) return 0 ;
@@ -164,8 +193,10 @@ function getVisibleTiers(quota: SubscriptionQuota | undefined): QuotaTier[] {
164193
165194/** 引导步骤条目:说明从哪里进入页面以及读数顺序。 */
166195const GuideStep : React . FC < GuideStepProps > = ( { index, title, detail } ) => (
167- < div className = "flex gap-3 rounded-lg border border-blue-200 bg-card p-3 text-sm dark:border-blue-700/40 dark:bg-slate-950/40" >
168- < div className = "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-blue-600 text-xs font-semibold text-white" >
196+ < div
197+ className = { `flex gap-3 rounded-lg border p-3 text-sm ${ USAGE_PAGE_COLORS . guideStep } ` }
198+ >
199+ < div className = "flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-sky-600 text-xs font-semibold text-white dark:bg-blue-500" >
169200 { index }
170201 </ div >
171202 < div className = "min-w-0" >
@@ -183,15 +214,8 @@ const UsageReadingHint: React.FC<UsageReadingHintProps> = ({
183214 detail,
184215 tone,
185216} ) => {
186- const toneClass =
187- tone === "ok"
188- ? "border-emerald-200 bg-emerald-50/70 text-emerald-900 dark:border-emerald-700/40 dark:bg-emerald-950/20 dark:text-emerald-100"
189- : tone === "warn"
190- ? "border-amber-200 bg-amber-50/70 text-amber-900 dark:border-amber-700/40 dark:bg-amber-950/20 dark:text-amber-100"
191- : "border-blue-200 bg-blue-50/70 text-blue-900 dark:border-blue-700/40 dark:bg-blue-950/20 dark:text-blue-100" ;
192-
193217 return (
194- < div className = { `rounded-lg border px-3 py-2 ${ toneClass } ` } >
218+ < div className = { `rounded-lg border px-3 py-2 ${ READING_HINT_COLORS [ tone ] } ` } >
195219 < div className = "text-xs font-semibold" > { title } </ div >
196220 < div className = "mt-1 text-xs leading-5 opacity-80" > { detail } </ div >
197221 </ div >
@@ -200,8 +224,8 @@ const UsageReadingHint: React.FC<UsageReadingHintProps> = ({
200224
201225/** 页面引导区:补齐入口、刷新和读数判断,避免用户只看到一组静态数字。 */
202226const UsageGuidePanel : React . FC = ( ) => (
203- < section className = " rounded-lg border border-blue-200 bg-blue-50/70 p-4 dark:border-blue-700/40 dark:bg-blue-950/15" >
204- < div className = "mb-3 flex items-center gap-2 text-sm font-semibold text-blue-900 dark:text-blue-100 " >
227+ < section className = { ` rounded-lg border p-4 ${ USAGE_PAGE_COLORS . guide } ` } >
228+ < div className = "mb-3 flex items-center gap-2 text-sm font-semibold" >
205229 < Info className = "h-4 w-4" />
206230 使用引导
207231 </ div >
@@ -249,7 +273,7 @@ const UsageWindowCard: React.FC<UsageWindowCardProps> = ({ tier }) => {
249273 const label = TIER_LABELS [ tier . name ] ?? tier . name ;
250274
251275 return (
252- < section className = " rounded-lg border border-border bg-card p-4 dark:border-slate-700/80 dark:bg-slate-950/30" >
276+ < section className = { ` rounded-lg border p-4 ${ USAGE_PAGE_COLORS . card } ` } >
253277 < div className = "mb-4 flex items-start justify-between gap-3" >
254278 < div >
255279 < div className = "text-sm font-semibold text-foreground" > { label } </ div >
@@ -265,7 +289,9 @@ const UsageWindowCard: React.FC<UsageWindowCardProps> = ({ tier }) => {
265289 </ div >
266290 </ div >
267291
268- < div className = "h-2 overflow-hidden rounded-full bg-muted dark:bg-slate-800" >
292+ < div
293+ className = { `h-2 overflow-hidden rounded-full ${ USAGE_PAGE_COLORS . progressTrack } ` }
294+ >
269295 < div
270296 className = { `h-full rounded-full transition-all ${ capacityBarTone ( used ) } ` }
271297 style = { { width : `${ used } %` } }
@@ -287,7 +313,9 @@ const ResetCreditRow: React.FC<ResetCreditRowProps> = ({ credit, index }) => {
287313 const urgency = resetCreditUrgency ( credit . expiresAt ) ;
288314
289315 return (
290- < div className = "grid grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-3 rounded-lg border border-border bg-background px-3 py-2 text-sm dark:border-slate-700/70 dark:bg-slate-950/40" >
316+ < div
317+ className = { `grid grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-3 rounded-lg border px-3 py-2 text-sm ${ USAGE_PAGE_COLORS . inset } ` }
318+ >
291319 < div className = "min-w-0" >
292320 < div className = "truncate font-medium text-foreground" >
293321 { credit . title || `Reset ${ index + 1 } ` }
@@ -314,7 +342,9 @@ function renderQuotaProblem(
314342) : React . ReactNode {
315343 if ( loading && ! quota ) {
316344 return (
317- < div className = "rounded-lg border border-border bg-card p-6 text-sm text-muted-foreground dark:border-slate-700/80 dark:bg-slate-950/30" >
345+ < div
346+ className = { `rounded-lg border p-6 text-sm text-muted-foreground ${ USAGE_PAGE_COLORS . card } ` }
347+ >
318348 正在读取本机 Codex 登录状态...
319349 </ div >
320350 ) ;
@@ -336,19 +366,21 @@ function renderQuotaProblem(
336366 "请确认 Codex Desktop / CLI 已登录,然后刷新。" ;
337367
338368 return (
339- < section className = "rounded-lg border border-amber-200 bg-amber-50 p-5 text-sm text-amber-900 shadow-sm dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100" >
369+ < section
370+ className = { `rounded-lg border p-5 text-sm shadow-sm ${ USAGE_PAGE_COLORS . warning } ` }
371+ >
340372 < div className = "mb-3 flex items-center gap-2 font-semibold" >
341373 < AlertCircle className = "h-4 w-4" />
342374 { title }
343375 </ div >
344- < p className = "mb-4 text-amber-800 dark:text-amber-200 " > { detail } </ p >
376+ < p className = "mb-4 opacity-90 " > { detail } </ p >
345377 < Button
346378 type = "button"
347379 onClick = { refetch }
348380 disabled = { loading }
349381 size = "sm"
350382 variant = "outline"
351- className = " gap-2 border-amber-300 hover:bg-amber-100 dark:border-amber-700 dark:hover:bg-amber-900/40"
383+ className = { ` gap-2 ${ USAGE_PAGE_COLORS . warningButton } ` }
352384 >
353385 < RefreshCw className = { `h-3.5 w-3.5 ${ loading ? "animate-spin" : "" } ` } />
354386 重新刷新
@@ -377,11 +409,15 @@ export const CodexUsagePage: React.FC = () => {
377409
378410 return (
379411 < div className = "mx-auto flex w-full max-w-6xl flex-col gap-4 px-6 py-6" >
380- < section className = "overflow-hidden rounded-lg border border-border bg-card dark:border-slate-700/80 dark:bg-slate-950/30" >
381- < div className = "flex flex-col gap-4 bg-gradient-to-r from-blue-50 via-background to-emerald-50 px-4 py-3 dark:from-blue-950/45 dark:via-slate-900 dark:to-emerald-950/30 lg:flex-row lg:items-center lg:justify-between" >
412+ < section
413+ className = { `overflow-hidden rounded-lg border ${ USAGE_PAGE_COLORS . shell } ` }
414+ >
415+ < div
416+ className = { `flex flex-col gap-4 px-4 py-3 lg:flex-row lg:items-center lg:justify-between ${ USAGE_PAGE_COLORS . header } ` }
417+ >
382418 < div className = "min-w-0 space-y-2" >
383419 < div className = "flex items-center gap-2 text-base font-semibold" >
384- < Gauge className = "h-4 w-4 text-blue -600 dark:text-blue-300" />
420+ < Gauge className = "h-4 w-4 text-sky -600 dark:text-blue-300" />
385421 Codex 用量与重置额度
386422 </ div >
387423 < p className = "max-w-4xl text-xs leading-5 text-muted-foreground dark:text-slate-400" >
@@ -390,22 +426,30 @@ export const CodexUsagePage: React.FC = () => {
390426 配置。
391427 </ p >
392428 < div className = "flex flex-wrap items-center gap-2 text-xs text-muted-foreground" >
393- < span className = "inline-flex items-center gap-1 rounded-md border border-border bg-background px-2 py-1 dark:border-slate-700/80 dark:bg-slate-950/40" >
429+ < span
430+ className = { `inline-flex items-center gap-1 rounded-md border px-2 py-1 ${ USAGE_PAGE_COLORS . chip } ` }
431+ >
394432 Codex 工具栏
395433 < ArrowRight className = "h-3 w-3" />
396434 柱状图按钮
397435 </ span >
398- < span className = "inline-flex items-center gap-1 rounded-md border border-border bg-background px-2 py-1 dark:border-slate-700/80 dark:bg-slate-950/40" >
436+ < span
437+ className = { `inline-flex items-center gap-1 rounded-md border px-2 py-1 ${ USAGE_PAGE_COLORS . chip } ` }
438+ >
399439 只读查询
400440 </ span >
401- < span className = "inline-flex items-center gap-1 rounded-md border border-border bg-background px-2 py-1 dark:border-slate-700/80 dark:bg-slate-950/40" >
441+ < span
442+ className = { `inline-flex items-center gap-1 rounded-md border px-2 py-1 ${ USAGE_PAGE_COLORS . chip } ` }
443+ >
402444 自动 5 分钟刷新
403445 </ span >
404446 </ div >
405447 </ div >
406448
407449 < div className = "flex flex-wrap items-center gap-3 text-sm" >
408- < div className = "inline-flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2 text-muted-foreground dark:border-slate-700/80 dark:bg-slate-950/40" >
450+ < div
451+ className = { `inline-flex items-center gap-2 rounded-lg border px-3 py-2 ${ USAGE_PAGE_COLORS . chip } ` }
452+ >
409453 < Clock className = "h-4 w-4" />
410454 { formatCheckedAt ( quota ?. queriedAt ) }
411455 </ div >
@@ -414,7 +458,7 @@ export const CodexUsagePage: React.FC = () => {
414458 onClick = { ( ) => void refetch ( ) }
415459 disabled = { isFetching }
416460 size = "sm"
417- className = "gap-2 bg-blue-600 hover:bg-blue-500"
461+ className = "gap-2 bg-sky-600 hover:bg-sky-500 dark:bg- blue-600 dark: hover:bg-blue-500"
418462 >
419463 < RefreshCw
420464 className = { `h-4 w-4 ${ isFetching ? "animate-spin" : "" } ` }
@@ -436,21 +480,27 @@ export const CodexUsagePage: React.FC = () => {
436480 < UsageWindowCard key = { tier . name } tier = { tier } />
437481 ) ) }
438482 { visibleTiers . length === 0 && (
439- < section className = "rounded-lg border border-border bg-card p-5 text-sm text-muted-foreground dark:border-slate-700/80 dark:bg-slate-950/30 lg:col-span-2" >
483+ < section
484+ className = { `rounded-lg border p-5 text-sm text-muted-foreground lg:col-span-2 ${ USAGE_PAGE_COLORS . card } ` }
485+ >
440486 Codex 没有返回 5 小时或每周用量窗口。
441487 </ section >
442488 ) }
443489 </ div >
444490
445- < section className = "rounded-lg border border-border bg-card p-5 dark:border-slate-700/80 dark:bg-slate-950/30" >
491+ < section
492+ className = { `rounded-lg border p-5 ${ USAGE_PAGE_COLORS . card } ` }
493+ >
446494 < div className = "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between" >
447495 < div className = "flex items-center gap-2" >
448496 < RotateCcw className = "h-4 w-4 text-sky-600 dark:text-sky-400" />
449497 < h3 className = "text-base font-semibold text-foreground" >
450498 已存 reset 额度
451499 </ h3 >
452500 </ div >
453- < div className = "inline-flex items-center gap-2 rounded-lg bg-sky-500/10 px-3 py-2 text-sm font-semibold text-sky-700 dark:text-sky-300" >
501+ < div
502+ className = { `inline-flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-semibold ${ USAGE_PAGE_COLORS . resetSummary } ` }
503+ >
454504 < TimerReset className = "h-4 w-4" />
455505 { availableCount } 个可用
456506 </ div >
@@ -466,21 +516,27 @@ export const CodexUsagePage: React.FC = () => {
466516 />
467517 ) ) }
468518 { missingExpiryCount > 0 && (
469- < div className = "rounded-lg border border-dashed border-border bg-background px-3 py-2 text-sm text-muted-foreground dark:border-slate-700/70 dark:bg-slate-950/40" >
519+ < div
520+ className = { `rounded-lg border border-dashed px-3 py-2 text-sm text-muted-foreground ${ USAGE_PAGE_COLORS . inset } ` }
521+ >
470522 还有 { missingExpiryCount } 个可用 reset
471523 没有返回可展示的到期明细。
472524 </ div >
473525 ) }
474526 </ div >
475527 ) : (
476- < div className = "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-3 text-sm text-muted-foreground dark:border-slate-700/70 dark:bg-slate-950/40" >
528+ < div
529+ className = { `flex items-center gap-2 rounded-lg border px-3 py-3 text-sm text-muted-foreground ${ USAGE_PAGE_COLORS . inset } ` }
530+ >
477531 < CheckCircle2 className = "h-4 w-4 text-emerald-600 dark:text-emerald-400" />
478532 当前没有已存 reset 额度。
479533 </ div >
480534 ) }
481535
482536 { quota . resetCreditsError && (
483- < div className = "mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-200" >
537+ < div
538+ className = { `mt-3 rounded-lg border px-3 py-2 text-sm ${ USAGE_PAGE_COLORS . warning } ` }
539+ >
484540 Reset credit 明细读取不完整:{ quota . resetCreditsError }
485541 </ div >
486542 ) }
0 commit comments