feat(settings): 表单分区收窄到 440px,套餐卡收敛成两种互斥状态
任务书 TASK-cend-surfaces-claude-alignment-20260916 §R8(T8.1 / T8.2)。 T8.1(E13):880px 弹窗里「个人资料」「通用设置」的一列表单铺满约 690px, 字段与标签被拉断。表单分区的内容区加 `settings-dialog-content--form`, 子元素上限 440px 并左对齐;「星盘资料」「账户与点数」两个列表分区保持铺满。 上限只挂在滚动容器的子元素上,不挂 `.settings-modal` / `.account-settings-shell`, 因此传不到固定尺寸的弹窗(BUG-554 / BUG-698 的现象无法复现)。 T8.2(D13):套餐卡的三个修饰符可同时命中,叠出没有设计定义的边框与底色。 收敛成两种互斥状态 `is-current`(当前套餐)与 `is-recommended`(推荐), 「推荐且当前」判给当前套餐(该卡的动作是续费)。 `highlighted` 不再进 className,删掉 `--highlighted` 那条描边规则, 定位交给 use-billing-panel 里已有的 scrollIntoView + focus。 手机端「月卡置顶」改挂 `[data-plan-alias="monthly"]`——版位不是状态, 月卡成为当前套餐后排序不变。 测试:3350 → 3354(+4),fail 31 → 31 且失败清单与基线逐条一致。 6 处既有断言改动均就地写了「原值/新值/原因」,另有 3 次破坏性验证。 tsc 0 错;lint 0 error / 118 warning(持平);干净 next build 后 `/` 仍 `○ Static`, 产物 CSS gzip 39,034 → 38,882 B(−0.39%),三条新规则在产物里逐条取证。 环境缺口(未记为通过):四个分区切换不跳尺寸、支付下单流程、`?plan=` 滚动定位的 视觉确认——无 Chrome、无受控账号,见 PROGRESS 的环境缺口段。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
This commit is contained in:
co-authored by
Claude Opus 5
parent
50ce02c837
commit
34628ecb67
@@ -1739,6 +1739,12 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.settings-dialog-nav-item > svg { width: 18px; height: 18px; color: var(--color-ink-tertiary); }
|
||||
.settings-dialog-nav-item > svg:last-child { width: 15px; height: 15px; margin-left: auto; }
|
||||
.settings-dialog-content { min-width: 0; min-height: 0; overflow-y: auto; }
|
||||
/* Form panes (个人资料 / 通用设置) read as one column, so they are capped and left
|
||||
aligned instead of stretching across the ~690px content area. The cap lives on the
|
||||
children, never on the scroll container or the dialog box: .settings-modal keeps its
|
||||
fixed width/height, so the four panes still cannot change the dialog size (BUG-554 /
|
||||
BUG-698). List panes (星盘资料 / 账户与点数) stay full-bleed. */
|
||||
.settings-dialog-content--form > * { max-width: 440px; margin-right: auto; }
|
||||
.settings-dialog-copy { margin: 0 0 var(--space-5); color: var(--color-ink-secondary); font-size: var(--type-body-sm); line-height: 1.6; }
|
||||
.avatar-section { padding-top: 0; }
|
||||
.avatar-editor { display: grid; grid-template-columns: 48px minmax(0, 1fr); align-items: center; gap: var(--space-5); margin-top: var(--space-5); }
|
||||
@@ -4298,8 +4304,12 @@ button.nav-rail-identity:hover { background: var(--sidebar-accent); }
|
||||
|
||||
.membership-plan-grid, .membership-credit-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
|
||||
.membership-plan-card, .membership-credit-card { min-width: 0; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-canvas); box-shadow: none; }
|
||||
.membership-plan-card--recommended { border-color: var(--color-border-strong); background: var(--color-canvas); }
|
||||
.membership-plan-card--current { border-color: var(--color-action); }
|
||||
/* Two mutually exclusive card states (D13). The markup emits at most one of them, so
|
||||
borders and backgrounds can never stack the way the three old BEM modifiers
|
||||
(recommended / current / URL highlight) did. Plan order on mobile is keyed off the
|
||||
plan identity below, not off a state, so it survives the card becoming 当前套餐. */
|
||||
.membership-plan-card.is-recommended { border-color: var(--color-border-strong); background: var(--color-canvas); }
|
||||
.membership-plan-card.is-current { border-color: var(--color-action); }
|
||||
.membership-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
|
||||
.membership-card-header h3, .membership-credit-copy h3 { margin: 0; color: var(--color-ink); font-family: var(--font-body); font-size: var(--type-title-md); font-weight: 600; letter-spacing: -.01em; }
|
||||
.membership-card-meta { margin: 4px 0 0; color: var(--color-ink-tertiary); font-size: var(--type-caption); }
|
||||
@@ -4332,7 +4342,9 @@ button.nav-rail-identity:hover { background: var(--sidebar-accent); }
|
||||
.membership-tab:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
|
||||
.membership-tab[data-active] { border-bottom-color: var(--color-action); background: transparent; color: var(--color-action); box-shadow: none; }
|
||||
.membership-panel { min-width: 0; }
|
||||
.membership-plan-card--highlighted { border-color: var(--color-action); outline: 2px solid color-mix(in srgb, var(--color-action) 38%, transparent); outline-offset: 2px; }
|
||||
/* The ?plan= entry point no longer repaints the card (it used to add a third border +
|
||||
outline on top of the recommended / current states). It scrolls the card into view
|
||||
and focuses it instead; see useBillingPanel's highlight effect. */
|
||||
.membership-payment-error { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); padding: var(--space-3) 0; border-top: 1px solid color-mix(in srgb, var(--color-danger) 48%, var(--color-border)); border-bottom: 1px solid color-mix(in srgb, var(--color-danger) 32%, var(--color-border)); background: transparent; }
|
||||
.membership-payment-error p { margin: 0; color: var(--color-danger); font-size: var(--type-body-sm); line-height: 1.55; }
|
||||
|
||||
@@ -4343,7 +4355,7 @@ button.nav-rail-identity:hover { background: var(--sidebar-accent); }
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.membership-plan-card--recommended { order: -1; }
|
||||
.membership-plan-card[data-plan-alias="monthly"] { order: -1; }
|
||||
.membership-payment-error { align-items: flex-start; flex-direction: column; }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user