diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 6df5d435..5ac010bd 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -481,6 +481,13 @@ button:disabled { cursor: default; opacity: .45; } .product-entrypoint-action .starter-arrow { width: 15px; height: 15px; color: currentColor; } .starter-loading { color: var(--color-ink-secondary); margin-left: 0; padding: var(--space-5); border-radius: var(--radius-lg); background: var(--color-canvas-muted); font-size: 14px; } .starter-note { margin: 10px 0 0; color: var(--color-ink-secondary); line-height: 1.5; grid-column: 1 / -1; font-size: 13px; } +.parameter-freeze-panel { display: grid; grid-column: 1 / -1; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); } +.parameter-freeze-panel > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); color: var(--color-ink-secondary); font-size: var(--type-caption); } +.parameter-freeze-panel b { color: var(--color-ink); font-size: var(--type-title-sm); } +.parameter-freeze-panel dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: var(--space-2); margin: 0; } +.parameter-freeze-panel dl > div { min-width: 0; padding: var(--space-2); border-radius: var(--radius-md); background: var(--color-canvas-soft); } +.parameter-freeze-panel dt { color: var(--color-ink-tertiary); font-size: 11px; } +.parameter-freeze-panel dd { overflow: hidden; margin: 2px 0 0; color: var(--color-ink); text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .message-list { margin: 0 auto; width: min(900px, 100%); padding: var(--space-8) var(--space-8) var(--space-16); } .message { display: flex; animation: message-enter 160ms var(--ease-out) both; padding: var(--space-2) 0; } diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 3867440e..c84fe4de 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -14,6 +14,7 @@ import { BirthTimeIntakeFields } from "@/components/birth-time-intake"; import { ChatMessageContent } from "@/components/chat-message-content"; import { AgentAvatar, ChatMessageRow } from "@/components/chat-message-row"; import { ModelSelector } from "@/components/model-selector"; +import { ParameterFreezePanel, type ParameterFreezeRow } from "@/components/parameter-freeze-panel"; import { Button } from "@/components/ui/button"; import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; import { Textarea } from "@/components/ui/textarea"; @@ -841,6 +842,16 @@ export default function Home() { const profileComplete = isProfileComplete(profile); const birthTimeDisplay = birthTimeDisplayState(profile); + const profileBirthPlace = selectedBirthPlace(profile); + const parameterFreezeRows: ParameterFreezeRow[] = profileComplete && profileBirthPlace ? [ + { label: "出生时间", value: `${profile.date} ${profile.time || "未定"}` }, + { label: "出生地点", value: profileBirthPlace.label }, + { label: "经纬度", value: `${profileBirthPlace.lat.toFixed(4)}, ${profileBirthPlace.lon.toFixed(4)}` }, + { label: "时区", value: `UTC+${profileBirthPlace.tz}` }, + { label: "Ayanamsa", value: "Lahiri / Sidereal" }, + { label: "Node mode", value: "True Node" }, + { label: "出生时间精度", value: birthTimeDisplay?.kind === "candidate" ? "候选时间" : birthTimeDisplay?.kind === "confirmed" ? "已确认" : "待校正" }, + ] : []; const dailyStarlanguage = dailyStarlanguageCard ?? (profileComplete ? buildDailyStarlanguageCard(profile) : null); const onboardingPending = profileComplete && !onboarding && !onboardingError; const currentOnboardingMessage = onboardingJustCompleted @@ -2417,6 +2428,7 @@ export default function Home() {