diff --git a/assets/css/routes/user-center/vip.css b/assets/css/routes/user-center/vip.css index 2e9e4be6..070c4db7 100644 --- a/assets/css/routes/user-center/vip.css +++ b/assets/css/routes/user-center/vip.css @@ -1,41 +1,10 @@ /** - * User Center — compact membership summary. + * User Center — VIP page UX/UI. * - * The VIP tab keeps one thin status surface; personal profile chrome and - * decorative stacked-card layers belong to the user-center header, not here. + * The summary card is the membership status thesis: one calm surface, + * one state accent, and a quiet crown watermark behind the four key lines. */ -.uc-vip-summary { - position: relative; - min-width: 0; - margin: 0 0 16px; - padding: 12px 16px; - overflow: hidden; - border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.08)); - border-radius: var(--main-radius, var(--radius, 8px)); - background: var(--surface-1, #fff); - box-shadow: none; - isolation: isolate; -} - -.uc-vip-summary__watermark { - position: absolute; - top: 50%; - right: -10px; - z-index: 0; - color: currentColor; - font-size: 160px; - line-height: 1; - opacity: 0.15; - pointer-events: none; - transform: translateY(-50%); -} - -.uc-vip-summary__watermark i { - font-size: inherit; - line-height: 1; -} - .uc-content #panel-vip.dashboard-panel { margin: 0; padding: 0; @@ -45,64 +14,383 @@ box-shadow: none; } +.uc-vip-summary { + --vip-state: var(--color-primary); + --vip-state-soft: var(--color-primary-soft); + --vip-level: var(--color-ink-2); + position: relative; + isolation: isolate; + min-width: 0; + margin: 0 0 var(--space-5, 20px); + padding: clamp(18px, 2.8vw, 28px) clamp(18px, 3vw, 30px); + padding-inline-end: clamp(110px, 19vw, 180px); + overflow: hidden; + border: 1px solid var(--color-line-soft); + border-inline-start: 3px solid var(--vip-state); + border-radius: var(--radius-lg, var(--radius, 8px)); + background-color: var(--surface-1); + background-image: linear-gradient(135deg, var(--vip-state-soft), transparent 52%); + box-shadow: var(--shadow-sm); + transition: border-color var(--dur, 0.25s) var(--ease, ease), box-shadow var(--dur, 0.25s) var(--ease, ease); +} + +.uc-vip-summary[data-vip-state="active"] { + --vip-state: var(--color-success); + --vip-state-soft: color-mix(in srgb, var(--color-success) 12%, transparent); +} + +.uc-vip-summary[data-vip-state="permanent"] { + --vip-state: var(--color-accent); + --vip-state-soft: var(--color-accent-soft); +} + +.uc-vip-summary[data-vip-state="expired"] { + --vip-state: var(--color-error); + --vip-state-soft: color-mix(in srgb, var(--color-error) 10%, transparent); +} + +.uc-vip-summary[data-vip-state="unopened"] { + --vip-state: var(--color-info); + --vip-state-soft: color-mix(in srgb, var(--color-info) 10%, transparent); +} + +.uc-vip-summary[data-vip-level="1"] { + --vip-level: var(--aksrt-vip-gold-2, var(--color-warning)); +} + +.uc-vip-summary[data-vip-level="2"] { + --vip-level: var(--aksrt-indigo, var(--color-info)); +} + +.uc-vip-summary__watermark { + position: absolute; + inset-inline-end: -0.08em; + top: 50%; + z-index: 0; + color: var(--vip-state); + font-size: clamp(96px, 10vw, 160px); + line-height: 1; + opacity: 0.1; + pointer-events: none; + transform: translateY(-50%); +} + +.uc-vip-summary__watermark i { + display: block; + font-size: inherit; + line-height: 1; +} + .uc-vip-status { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: flex-start; - gap: 4px; + gap: var(--space-2, 8px); min-width: 0; + max-width: 48rem; text-align: left; } +.uc-vip-status__heading { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: var(--space-2, 8px); + min-width: 0; +} + .uc-vip-status__label { - color: var(--color-ink, var(--main-color, #172033)); - font-size: 14px; + margin: 0; + color: var(--color-ink); + font-size: var(--text-lg, 1.25rem); + font-weight: 750; + letter-spacing: -0.02em; + line-height: var(--leading-tight, 1.2); +} + +.uc-vip-status__state { + display: inline-flex; + align-items: center; + min-height: var(--aksrt-badge-h, 22px); + padding: 3px 9px; + border: 1px solid color-mix(in srgb, var(--vip-state) 24%, transparent); + border-radius: var(--radius-pill, 100px); + background: var(--vip-state-soft); + color: var(--vip-state); + font-size: var(--text-xs, 0.75rem); font-weight: 700; - line-height: 1.4; + line-height: 1; + white-space: nowrap; } .uc-vip-status__main { display: inline-flex; align-items: center; - gap: 7px; + gap: var(--space-2, 8px); min-width: 0; - font-size: 1.15em; - line-height: 1.3; + color: var(--vip-level); + font-size: var(--text-lg, 1.25rem); + line-height: var(--leading-tight, 1.2); } -.uc-vip-status__main > i { - color: var(--focus-color, var(--color-primary, #f04494)); - font-size: 0.95em; +.uc-vip-status__icon { + display: inline-grid; + place-items: center; + width: 34px; + height: 34px; + flex: 0 0 auto; + border: 1px solid color-mix(in srgb, var(--vip-level) 32%, transparent); + border-radius: var(--radius-xl, 12px); + background: color-mix(in srgb, var(--vip-level) 12%, transparent); + color: var(--vip-level); + font-size: 15px; +} + +.uc-vip-status__level { + min-width: 0; + overflow-wrap: anywhere; + font-weight: 750; } .uc-vip-status__desc, .uc-vip-status__expiry { min-width: 0; - font-size: 0.9em; - line-height: 1.4; + overflow-wrap: anywhere; + font-size: var(--text-sm, 0.875rem); + line-height: var(--leading-snug, 1.4); } .uc-vip-status__desc { - margin-top: 1px; + color: var(--color-ink-3); } .uc-vip-status__expiry { - margin-top: 1px; + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--vip-state); + font-weight: 600; +} + +.uc-vip-status__expiry i { + font-size: 0.9em; +} + +/* Level purchase cards: one spacing system, no .zib-widget margin stacking. */ +.uc-vip-level-cards { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--space-4, 16px); + align-items: stretch; + margin: 0 0 var(--space-5, 20px); +} + +.uc-vip-tab .uc-vip-level-card.zib-widget, +.uc-vip-tab .uc-vip-level-card.pay-vip-info { + position: relative; + display: block; + min-width: 0; + height: 100%; + margin: 0; + padding: 22px 20px 20px; + overflow: hidden; + border: 1px solid var(--color-line-soft); + border-top: 3px solid var(--vip-card-accent, var(--color-primary)); + border-radius: var(--radius-lg, var(--radius, 8px)); + background-color: var(--surface-1) !important; + background-image: linear-gradient(145deg, var(--vip-card-soft), transparent 68%) !important; + box-shadow: var(--shadow-sm); + transition: transform var(--dur-fast, 0.15s) var(--ease, ease), box-shadow var(--dur-fast, 0.15s) var(--ease, ease), border-color var(--dur-fast, 0.15s) var(--ease, ease); +} + +.uc-vip-tab .uc-vip-level-card.level-1 { + --vip-card-accent: var(--aksrt-vip-gold-2, var(--color-warning)); + --vip-card-soft: color-mix(in srgb, var(--aksrt-vip-gold-1, var(--color-warning)) 15%, transparent); +} + +.uc-vip-tab .uc-vip-level-card.level-2 { + --vip-card-accent: var(--aksrt-indigo, var(--color-info)); + --vip-card-soft: color-mix(in srgb, var(--aksrt-indigo, var(--color-info)) 12%, transparent); +} + +.uc-vip-tab .uc-vip-level-card.zib-widget:hover, +.uc-vip-tab .uc-vip-level-card.pay-vip-info:hover { + border-color: color-mix(in srgb, var(--vip-card-accent) 42%, var(--color-line-soft)); + box-shadow: var(--shadow); + transform: translateY(-2px); +} + +.uc-vip-tab .uc-vip-level-card .vip-baicon { + color: var(--vip-card-accent); + opacity: 0.1; +} + +.uc-vip-level-card__inner { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + align-items: stretch; + min-height: 100%; +} + +.uc-vip-tab .uc-vip-level-card .v-iconbox { + justify-content: flex-start; + gap: var(--space-3, 12px); + margin-bottom: var(--space-4, 16px); +} + +.uc-vip-tab .uc-vip-level-card .v-icon { + width: 40px; + height: 40px; + flex: 0 0 auto; + border: 1px solid color-mix(in srgb, var(--vip-card-accent) 28%, transparent); + border-radius: var(--radius-xl, 12px); + background: color-mix(in srgb, var(--vip-card-accent) 14%, transparent); + color: var(--vip-card-accent); +} + +.uc-vip-tab .uc-vip-level-card.level-1 .v-name, +.uc-vip-tab .uc-vip-level-card.level-2 .v-name { + color: var(--vip-card-accent); +} + +.uc-vip-tab .uc-vip-level-card .v-name { + font-size: var(--text-md, 1.125rem); + line-height: var(--leading-tight, 1.2); +} + +.uc-vip-tab .uc-vip-level-card .v-desc { + margin-top: 4px; + color: var(--color-ink-3); + line-height: var(--leading-snug, 1.4); +} + +.uc-vip-tab .uc-vip-level-card .v-equity { + flex: 1 1 auto; + max-width: none; + margin: 0 0 var(--space-5, 20px) !important; + color: var(--color-ink-3); +} + +.uc-vip-tab .uc-vip-level-card .v-equity > li { + margin-bottom: var(--space-2, 8px) !important; +} + +.uc-vip-tab .uc-vip-cta { + display: flex !important; + align-items: center; + justify-content: center; + gap: var(--space-2, 8px); + width: 100%; + min-width: 0; + min-height: var(--btn-lg-h, 44px); + margin-top: auto; + padding: 10px 16px !important; + border: 0; + border-radius: var(--radius, 8px); + font-weight: 700; + line-height: 1.2; + text-align: center; + text-decoration: none; + transition: filter var(--dur-fast, 0.15s) var(--ease, ease), box-shadow var(--dur-fast, 0.15s) var(--ease, ease), transform var(--dur-fast, 0.15s) var(--ease, ease); +} + +.uc-vip-tab .uc-vip-cta:hover { + filter: brightness(0.97) saturate(1.08); + box-shadow: var(--shadow-sm); + opacity: 1; + transform: translateY(-1px); +} + +.uc-vip-tab .uc-vip-cta:focus-visible { + outline: 3px solid var(--color-primary); + outline-offset: 3px; + box-shadow: var(--focus-ring); +} + +.uc-vip-tab .uc-vip-cta--current { + cursor: default; + background: var(--surface-3) !important; + color: var(--color-ink-3) !important; + filter: none; + opacity: 1; +} + +.uc-vip-tab .uc-vip-cta--current:hover { + box-shadow: none; + transform: none; +} + +.uc-vip-tab .uc-vip-points-link.zib-widget { + margin: 0 0 var(--space-5, 20px); + border: 1px solid color-mix(in srgb, var(--color-warning) 22%, var(--color-line-soft)); + border-radius: var(--radius-lg, var(--radius, 8px)); + background-color: var(--surface-1); + background-image: linear-gradient(135deg, color-mix(in srgb, var(--color-warning) 8%, transparent), transparent 70%); + box-shadow: none; +} + +.uc-vip-tab > .muted-box { + margin-top: 0; + border: 1px solid var(--color-line-soft); + background: var(--surface-4); } @media (max-width: 767px) { .uc-vip-summary { - padding: 10px 12px; + padding: 18px 14px; + padding-inline-end: 76px; } .uc-vip-summary__watermark { - font-size: 110px; - opacity: 0.12; + inset-inline-end: -0.14em; + font-size: clamp(82px, 27vw, 112px); + opacity: 0.08; } .uc-vip-status { - column-gap: 12px; + gap: var(--space-2, 8px); + } + + .uc-vip-status__label { + font-size: var(--text-md, 1.125rem); + } + + .uc-vip-level-cards { + grid-template-columns: 1fr; + gap: var(--space-3, 12px); + } + + .uc-vip-tab .uc-vip-level-card.zib-widget, + .uc-vip-tab .uc-vip-level-card.pay-vip-info { + padding: 20px 16px 16px; + } +} + +@media (max-width: 420px) { + .uc-vip-summary { + padding-inline-end: 62px; + } + + .uc-vip-summary__watermark { + font-size: 86px; + } +} + +@media (prefers-reduced-motion: reduce) { + .uc-vip-summary, + .uc-vip-tab .uc-vip-level-card.zib-widget, + .uc-vip-tab .uc-vip-level-card.pay-vip-info, + .uc-vip-tab .uc-vip-cta { + transition: none; + } + + .uc-vip-tab .uc-vip-level-card.zib-widget:hover, + .uc-vip-tab .uc-vip-level-card.pay-vip-info:hover, + .uc-vip-tab .uc-vip-cta:hover { + transform: none; } } diff --git a/inc/helpers/user-center-renderers/vip-tab.php b/inc/helpers/user-center-renderers/vip-tab.php index a2226560..73a97f07 100644 --- a/inc/helpers/user-center-renderers/vip-tab.php +++ b/inc/helpers/user-center-renderers/vip-tab.php @@ -26,55 +26,62 @@ $levels = is_array($vip_settings['levels'] ?? null) ? $vip_settings['levels'] : $desc_top = (string) ($vip_settings['desc'] ?? ''); // Membership summary: title → level → intro → expiry. -$status_html = ''; -$btn_type = 'pay'; +$vip_state = 'unopened'; +$vip_state_label = __('未开通', 'aksrt'); +$vip_level_number = 0; +$vip_level_name = __('未开通会员', 'aksrt'); +$vip_description = $desc_top !== '' ? $desc_top : __('开通会员,尊享专属特权', 'aksrt'); +$vip_expiry_text = __('到期时间:未开通', 'aksrt'); +$vip_is_permanent = false; +$btn_type = 'pay'; + if ($level > 0) { - $lv_name = (string) ($levels[$level]['name'] ?? ('VIP' . $level)); - $lv_desc = (string) ($levels[$level]['desc'] ?? ''); + $vip_level_number = $level; + $vip_level_name = (string) ($levels[$level]['name'] ?? ('VIP' . $level)); + $level_desc = (string) ($levels[$level]['desc'] ?? ''); + $vip_description = $level_desc !== '' ? $level_desc : __('尊享专属特权', 'aksrt'); + if ($expires <= 0) { - $expiry_text = __('到期时间:永久会员', 'aksrt'); - $expiry_class = 'c-green'; + $vip_state = 'permanent'; + $vip_state_label = __('永久有效', 'aksrt'); + $vip_expiry_text = __('到期时间:永久会员', 'aksrt'); + $vip_is_permanent = true; if ($level < 2) { $btn_type = 'upgrade'; } } else { - $expiry_text = sprintf(__('到期时间:%s', 'aksrt'), wp_date('Y年m月d日', $expires)); - $expiry_class = 'c-yellow'; - $btn_type = 'renew_' . $level; + $vip_state = 'active'; + $vip_state_label = __('生效中', 'aksrt'); + $vip_expiry_text = sprintf(__('到期时间:%s', 'aksrt'), wp_date('Y年m月d日', $expires)); + $btn_type = 'renew_' . $level; } - $status_html = '
' - . '
' . esc_html__('我的会员', 'aksrt') . '
' - . '
' . esc_html($lv_name) . '
' - . '
' . esc_html($lv_desc !== '' ? $lv_desc : __('尊享专属特权', 'aksrt')) . '
' - . '
' . esc_html($expiry_text) . '
' - . '
'; } elseif ($expired_level > 0) { - $expired_name = (string) ($levels[$expired_level]['name'] ?? ('VIP' . $expired_level)); - $expired_desc = (string) ($levels[$expired_level]['desc'] ?? ''); - if ($expired_desc === '') { - $expired_desc = $desc_top !== '' ? $desc_top : __('会员已过期', 'aksrt'); - } - $expiry_text = $expires > 0 + $vip_state = 'expired'; + $vip_state_label = __('已过期', 'aksrt'); + $vip_level_number = $expired_level; + $vip_level_name = (string) ($levels[$expired_level]['name'] ?? ('VIP' . $expired_level)); + $expired_desc = (string) ($levels[$expired_level]['desc'] ?? ''); + $vip_description = $expired_desc !== '' + ? $expired_desc + : ($desc_top !== '' ? $desc_top : __('会员已过期', 'aksrt')); + $vip_expiry_text = $expires > 0 ? sprintf(__('到期时间:%s', 'aksrt'), wp_date('Y年m月d日', $expires)) : __('到期时间:已过期', 'aksrt'); - $status_html = '
' - . '
' . esc_html__('我的会员', 'aksrt') . '
' - . '
' . esc_html($expired_name) . '
' - . '
' . esc_html($expired_desc) . '
' - . '
' . esc_html($expiry_text) . '
' - . '
'; - $btn_type = 'pay'; -} else { - // Never opened VIP: keep the same four-line summary shape. - $status_html = '
' - . '
' . esc_html__('我的会员', 'aksrt') . '
' - . '
' . esc_html__('未开通会员', 'aksrt') . '
' - . '
' . esc_html($desc_top !== '' ? $desc_top : __('开通会员,尊享专属特权', 'aksrt')) . '
' - . '
' . esc_html__('到期时间:未开通', 'aksrt') . '
' - . '
'; - $btn_type = 'pay'; } +$status_html = '
' + . '
' + . '

' . esc_html__('我的会员', 'aksrt') . '

' + . '' . esc_html($vip_state_label) . '' + . '
' + . '
' + . '' + . '' . esc_html($vip_level_name) . '' + . '
' + . '
' . esc_html($vip_description) . '
' + . '
' . esc_html($vip_expiry_text) . '
' + . '
'; + // Level cards. $cards = ''; foreach ([1, 2] as $lv) { @@ -88,8 +95,9 @@ foreach ([1, 2] as $lv) { $equity = function_exists('aksrt_format_vip_equity_html') ? aksrt_format_vip_equity_html($equity_raw) : ''; - $cta = sprintf(__('开通%s', 'aksrt'), $lv_name); - $vip_attr = $lv; + $cta = sprintf(__('开通%s', 'aksrt'), $lv_name); + $vip_attr = $lv; + $cta_is_current = false; if (str_starts_with($btn_type, 'renew_')) { $renew_lv = (int) substr($btn_type, 6); if ($lv === $renew_lv) { @@ -108,7 +116,12 @@ foreach ([1, 2] as $lv) { } elseif ($level > 0 && $lv < $level) { continue; } elseif ($level > 0 && $lv === $level) { - $cta = sprintf(__('续费%s', 'aksrt'), $lv_name); + if ($vip_is_permanent) { + $cta = __('当前等级', 'aksrt'); + $cta_is_current = true; + } else { + $cta = sprintf(__('续费%s', 'aksrt'), $lv_name); + } } $cards .= '
'; @@ -123,9 +136,14 @@ foreach ([1, 2] as $lv) { } $cards .= '
'; $cards .= $equity; - $cards .= '' - . '' . esc_html($cta) . '' - . ' '; + if ($cta_is_current) { + $cards .= '' + . '' . esc_html($cta) . ''; + } else { + $cards .= '' + . '' . esc_html($cta) . '' + . ' '; + } $cards .= ''; } @@ -134,13 +152,13 @@ $points_html = ''; if ($level <= 0 && !empty($vip_settings['points_exchange']['enabled'])) { $points_html = ''; } ?>
-
+