feat(subscription): add VIP subscription page

Add a new /subscription route showing three VIP membership plans (Monthly,
Quarterly, Annual) with a pink→peach banner, per-plan gradient price bars,
a benefits card, a mock activate CTA, and an agreement checkbox.

- New reusable <Checkbox /> in src/app/_components/core for the legal
  agreement toggle
- Hardcoded SUBSCRIPTION_PLANS constant in src/data/constants
- New SubscriptionScreen composed of 7 colocated components (back link,
  user row, banner, plan card, benefits card, CTA button) with CSS
  Modules matching the existing design-token system
- Route registered as protected and reached from /sidebar "Membership"
- Mock CTA: window.alert + router.push(/chat) — no payment calls

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-06-15 17:48:41 +08:00
committed by chenhang
parent b9315c9f8b
commit e88a99626d
23 changed files with 1001 additions and 0 deletions
@@ -0,0 +1,65 @@
.shell {
display: flex;
flex-direction: column;
min-height: 100dvh;
background: var(--color-page-background);
padding: 0 var(--spacing-lg) var(--spacing-xxl);
}
.header {
display: flex;
align-items: center;
height: 40px;
padding-top: var(--spacing-sm);
}
.backSlot {
display: inline-flex;
}
.userSlot {
margin-top: var(--spacing-md);
padding: 0 var(--spacing-xs);
}
.bannerSlot {
margin-top: var(--spacing-lg);
}
.plansRow {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing-sm);
margin-top: var(--spacing-xl);
}
.autoRenewCaption {
margin: var(--spacing-md) 0 0;
padding: 0 var(--spacing-xs);
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
line-height: 1.5;
}
.benefitsSlot {
margin-top: var(--spacing-lg);
}
.ctaSlot {
margin-top: var(--spacing-xl);
}
.agreementSlot {
margin-top: var(--spacing-md);
padding: 0 var(--spacing-xs);
}
.agreementLink {
color: var(--color-auth-text-primary);
font-weight: 700;
text-decoration: none;
}
.agreementLink:hover {
text-decoration: underline;
}