feat(ui): optional gender radio in the people form and 个人资料 (T2)

One ProfileGenderField (女 / 男 / 不填, 44px, one hint line) in the
people-archive edit form (saved with the form, 不填 → null) and in
设置 → 个人资料 for the owner (saves on its own PATCH; birth-data saves never
send gender). The detail card shows 性别 (未填 when empty). Not asked in
onboarding. DESIGN/VOICE updated; 390/1280 screenshots with fictional data.

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-27 18:30:58 +08:00
co-authored by Claude Opus 5.5
parent 5caf03844e
commit d79dada970
19 changed files with 318 additions and 3 deletions
+2 -1
View File
@@ -313,6 +313,7 @@ export default function Home() {
openAccountDialog,
closeAccountDialog,
persistAvatar,
persistGender,
saveProfile,
saveOnboardingName,
saveOnboardingBirth,
@@ -1134,7 +1135,7 @@ export default function Home() {
overlayRef: accountDialog,
closeButtonRef: closeButton,
renderProfile: () => (
<ProfilePanel account={account} profile={profile} avatarSaving={avatarSaving} avatarNotice={avatarNotice} accountError={accountError} persistAvatar={persistAvatar} />
<ProfilePanel account={account} profile={profile} avatarSaving={avatarSaving} avatarNotice={avatarNotice} accountError={accountError} persistAvatar={persistAvatar} persistGender={persistGender} />
),
renderChartLibrary() {
return null;
+11
View File
@@ -1882,6 +1882,17 @@ button:disabled { cursor: default; opacity: .45; }
.ayanamsa-preference-option[aria-checked="true"] { border-color: var(--color-action); background: var(--color-action-soft); }
.ayanamsa-preference-option small { display: block; margin-top: var(--space-1); color: var(--color-ink-tertiary); font-size: var(--type-caption); font-weight: 400; }
.ayanamsa-preference-hint { margin: var(--space-3) 0 0; color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.5; }
/* Optional gender (TASK-consult-gender-optional-20260927): three 44px choices
in one row, same look as the birth-time range choices; the title matches the
profile form's field labels, the hint matches the ayanamsa hint. */
.profile-gender-field { display: grid; gap: var(--space-2); }
.profile-gender-title { color: var(--color-ink-secondary); font-size: var(--type-overline); font-weight: 600; }
.profile-gender-options { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.profile-gender-option { min-width: 64px; min-height: 44px; padding: 0 var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-canvas); color: var(--color-ink); font-size: var(--type-body-sm); cursor: pointer; }
.profile-gender-option.is-selected { border-color: var(--color-action); background: var(--color-action-soft); }
.profile-gender-option:disabled { cursor: default; opacity: 0.6; }
.profile-gender-hint { margin: 0; color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.5; }
.people-archive-fact-note { display: block; margin-top: var(--space-1); color: var(--color-ink-tertiary); font-size: var(--type-caption); }
.account-menu-danger, .account-menu-danger > svg { color: var(--color-danger); }
.account-menu-danger[data-highlighted] { background: var(--color-danger-muted); }