Files
cozsweet-frontend-nextjs/src/app/subscription/components/subscription-cta-button.module.css
T
Claude e88a99626d 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>
2026-06-15 17:49:15 +08:00

68 lines
1.4 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 视觉规格:
* - 全宽,52px 高
* - 粉渐变(#f96ADE → #f657A0
* - 半径 24,白字 16px/600
* - 阴影 0 3px 5px rgba(208,12,65,0.20)
*/
.button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
height: 52px;
padding: 0 var(--spacing-lg);
border: none;
border-radius: var(--radius-xxxl);
background: linear-gradient(
90deg,
var(--color-auth-primary-gradient-start),
var(--color-auth-primary-gradient-end)
);
box-shadow: 0 3px 5px var(--color-auth-primary-button-shadow);
color: #ffffff;
font-size: var(--font-size-lg);
font-weight: 600;
cursor: pointer;
transition: filter 0.15s ease, transform 0.05s ease, opacity 0.15s ease;
}
.button:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
.button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.button:not(:disabled):active {
transform: scale(0.98);
}
.label {
display: inline-flex;
align-items: center;
gap: var(--spacing-sm);
flex: 1 1 auto;
justify-content: center;
text-align: center;
}
.spinner {
display: inline-block;
width: 18px;
height: 18px;
border-width: 2px;
border-style: solid;
border-color: #ffffff transparent transparent transparent;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}