style(subscription): polish offer sections

This commit is contained in:
2026-06-29 13:11:48 +08:00
parent 6e51cb7d16
commit b03083bacd
6 changed files with 44 additions and 40 deletions
@@ -2,7 +2,7 @@
overflow: hidden; overflow: hidden;
border: 1px solid rgba(17, 17, 17, 0.12); border: 1px solid rgba(17, 17, 17, 0.12);
border-radius: 28px; border-radius: 28px;
background: #ded4d7; background: #f7dce7;
box-shadow: 0 16px 42px rgba(31, 21, 25, 0.12); box-shadow: 0 16px 42px rgba(31, 21, 25, 0.12);
backdrop-filter: blur(18px); backdrop-filter: blur(18px);
} }
@@ -11,8 +11,8 @@
position: relative; position: relative;
padding: 18px 18px 22px; padding: 18px 18px 22px;
background: background:
linear-gradient(135deg, #ddd4d7 0%, #d3c9cd 58%, #c8bdc2 100%), linear-gradient(135deg, #f3cbd8 0%, #efbacd 58%, #eaa9c3 100%),
#d3c9cd; #efbacd;
} }
.title { .title {
@@ -29,7 +29,7 @@
bottom: -12px; bottom: -12px;
width: 24px; width: 24px;
height: 24px; height: 24px;
background: #d3c9cd; background: #efbacd;
transform: translateX(-50%) rotate(45deg); transform: translateX(-50%) rotate(45deg);
} }
@@ -68,25 +68,31 @@
} }
.selected { .selected {
border-color: rgba(246, 87, 160, 0.45); border: 3px solid #f657a0;
background: #fff4f8; background: linear-gradient(90deg, #fff1f7 0%, #ffffff 100%);
color: #111111; color: #111111;
box-shadow: 0 12px 28px rgba(246, 87, 160, 0.15); box-shadow: 0 14px 30px rgba(246, 87, 160, 0.3);
transform: translateY(-2px);
} }
.coinIcon { .coinIcon {
display: inline-flex; display: inline-flex;
width: 28px; width: 32px;
height: 28px; height: 32px;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
justify-self: center; justify-self: center;
border-radius: 999px; border-radius: 999px;
background: linear-gradient(180deg, #fff 0%, #f5f5f5 100%); background: linear-gradient(180deg, #ffe89c 0%, #f8b83e 100%);
color: #6a5960; color: #8f5400;
font-size: 12px;
line-height: 1; line-height: 1;
text-transform: lowercase; box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.75),
0 5px 12px rgba(216, 132, 22, 0.22);
}
.coinIcon svg {
display: block;
} }
.coins { .coins {
@@ -1,5 +1,7 @@
"use client"; "use client";
import { Coins } from "lucide-react";
import styles from "./subscription-coins-offer-section.module.css"; import styles from "./subscription-coins-offer-section.module.css";
export interface CoinsOfferPlanView { export interface CoinsOfferPlanView {
@@ -39,7 +41,9 @@ export function SubscriptionCoinsOfferSection({
aria-label={`${plan.coins} Coins, ${plan.currency}${plan.price}`} aria-label={`${plan.coins} Coins, ${plan.currency}${plan.price}`}
onClick={() => onSelectPlan(plan.id)} onClick={() => onSelectPlan(plan.id)}
> >
<span className={styles.coinIcon}>coins</span> <span className={styles.coinIcon} aria-hidden="true">
<Coins size={18} strokeWidth={2.4} />
</span>
<span className={styles.coins}>{plan.coins} Coins</span> <span className={styles.coins}>{plan.coins} Coins</span>
<span className={styles.price}> <span className={styles.price}>
{plan.currency} {plan.currency}
@@ -78,8 +78,8 @@
font: inherit; font: inherit;
text-align: center; text-align: center;
box-shadow: 0 8px 22px rgba(26, 16, 20, 0.05); box-shadow: 0 8px 22px rgba(26, 16, 20, 0.05);
transition: background-color 0.18s ease, box-shadow 0.18s ease, transition: background-color 0.18s ease, border-color 0.18s ease,
color 0.18s ease, transform 0.12s ease; box-shadow 0.18s ease, color 0.18s ease, transform 0.12s ease;
} }
.planCard:focus-visible { .planCard:focus-visible {
@@ -92,10 +92,13 @@
} }
.selected { .selected {
border-color: rgba(246, 87, 160, 0.55); border: 3px solid #f657a0;
background: linear-gradient(180deg, #fff 0%, #fff2f8 100%); background:
box-shadow: 0 14px 30px rgba(246, 87, 160, 0.2); linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, #ffeaf4 100%),
#ffffff;
box-shadow: 0 16px 34px rgba(246, 87, 160, 0.34);
color: #111111; color: #111111;
transform: translateY(-3px);
} }
.planTitle { .planTitle {
@@ -25,10 +25,14 @@ export function SubscriptionVipOfferSection({
<section className={styles.section} aria-label="Choose a VIP plan"> <section className={styles.section} aria-label="Choose a VIP plan">
<div className={styles.summary}> <div className={styles.summary}>
<h1 className={styles.title}> <h1 className={styles.title}>
<span className={styles.titleText}>VIP会员</span> <span className={styles.titleText}>VIP Membership</span>
<span className={styles.renewText}></span> <span className={styles.renewText}>
Auto-renews, cancel anytime
</span>
</h1> </h1>
<p className={styles.subtitle}>3000</p> <p className={styles.subtitle}>
Get 3,000 credits monthly and enjoy unlimited daily chats
</p>
<span className={styles.notch} aria-hidden="true" /> <span className={styles.notch} aria-hidden="true" />
</div> </div>
@@ -80,11 +80,11 @@ function formatCoinCurrency(currency: string): string {
function vipOfferTitle(plan: PaymentPlan): string { function vipOfferTitle(plan: PaymentPlan): string {
const key = `${plan.planId} ${plan.orderType} ${plan.planName}`.toLowerCase(); const key = `${plan.planId} ${plan.orderType} ${plan.planName}`.toLowerCase();
if (key.includes("year")) return "连续包年"; if (key.includes("year")) return "Annual";
if (key.includes("quarter")) return "连续包季"; if (key.includes("quarter")) return "Quarterly";
if (key.includes("month")) return "连续包月"; if (key.includes("month")) return "Monthly";
if (plan.vipDays !== null && plan.vipDays >= 300) return "连续包年"; if (plan.vipDays !== null && plan.vipDays >= 300) return "Annual";
if (plan.vipDays !== null && plan.vipDays >= 80) return "连续包季"; if (plan.vipDays !== null && plan.vipDays >= 80) return "Quarterly";
return plan.planName; return plan.planName;
} }
@@ -313,19 +313,6 @@ export function SubscriptionScreen({
</> </>
)} )}
{/* <p className={styles.autoRenewCaption}>{autoRenewCaption}</p>
<section className={styles.benefitsSlot}>
{subscriptionType === "voice" ? (
<div className={styles.benefitsPlaceholder} aria-hidden="true" />
) : (
<SubscriptionBenefitsCard
title="VIP Membership Benefits"
items={VIP_BENEFITS}
/>
)}
</section> */}
<section className={styles.paymentMethodSlot}> <section className={styles.paymentMethodSlot}>
<SubscriptionPaymentMethod <SubscriptionPaymentMethod
value={payment.payChannel} value={payment.payChannel}