<xf:title>{{ phrase('account_upgrades') }}</xf:title>
<xf:wrap template="account_wrapper" />
<xf:js src="xf/payment.js" min="1" />
<xf:css>
/* ============= ПЕРЕМЕННЫЕ ============= */
:root {
--background: 220 15% 8%;
--foreground: 0 0% 95%;
--card: 220 15% 12%;
--card-hover: 220 15% 14%;
--border: 220 15% 20%;
--muted: 220 15% 15%;
--muted-foreground: 220 10% 60%;
--premium-color: 330 74% 67%;
--premium-shadow: 327 80% 51%;
--upgrade: 160 84% 39%;
--upgrade-foreground: 0 0% 100%;
--prime: 270 80% 60%;
--accent-glow: 0 0% 100% / 0.1;
}
/* ============= АНИМАЦИИ ============= */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 40px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@keyframes pulseGlow {
0%, 100% {
box-shadow: 0 0 20px rgba(16, 185, 129, 0.4);
}
50% {
box-shadow: 0 0 30px rgba(16, 185, 129, 0.8);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translate3d(-50px, 0, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-20px) rotate(5deg);
}
}
/* ============= ОСНОВНЫЕ СТИЛИ ============= */
.account-upgrades-container {
position: relative;
min-height: 100vh;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
overflow: hidden;
}
.animated-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
pointer-events: none;
}
.animated-background-overlay {
position: absolute;
inset: 0;
background:
radial-gradient(circle at 20% 80%, rgba(16, 185, 129, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(168, 85, 247, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(232, 125, 203, 0.05) 0%, transparent 50%);
}
.glow-orb {
position: absolute;
border-radius: 50%;
filter: blur(80px);
animation: float 8s ease-in-out infinite;
opacity: 0.6;
}
.glow-orb-1 {
width: 30rem;
height: 30rem;
background: radial-gradient(circle, rgba(16, 185, 129, 0.3) 0%, rgba(16, 185, 129, 0.1) 50%, transparent 100%);
top: 10%;
left: 15%;
animation-delay: 0s;
}
.glow-orb-2 {
width: 25rem;
height: 25rem;
background: radial-gradient(circle, rgba(168, 85, 247, 0.25) 0%, rgba(168, 85, 247, 0.1) 50%, transparent 100%);
top: 30%;
right: 20%;
animation-delay: 2s;
}
.glow-orb-3 {
width: 20rem;
height: 20rem;
background: radial-gradient(circle, rgba(232, 125, 203, 0.2) 0%, rgba(232, 125, 203, 0.05) 50%, transparent 100%);
bottom: 20%;
left: 25%;
animation-delay: 4s;
}
/* ============= VIP BADGE & PREMIUM TEXT ============= */
.vip-badge {
margin-left: 5px;
color: white;
background: linear-gradient(135deg, #e87dcb, #d926a9, #e87dcb);
background-size: 400% 400%;
border-radius: 8px;
border: none;
padding: 6px 12px;
display: inline-flex;
align-items: center;
gap: 4px;
margin: 0 6px -2px;
font-size: 11px;
font-weight: 800;
line-height: 1.2;
letter-spacing: 0.5px;
animation: pulseGlow 2s ease-in-out infinite;
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
font-family: 'Segoe UI', sans-serif;
box-shadow: 0 2px 8px rgba(217, 38, 169, 0.3);
}
.text-premium {
color: #e87dcb;
text-shadow: 0 0 10px rgba(217, 38, 169, 0.5);
font-weight: 600;
}
.forum-banner-premium {
position: relative;
overflow: hidden;
width: 100%;
max-width: 14rem;
margin: 0 auto;
padding: 1rem 1.5rem;
border-radius: 12px;
border: 2px solid rgba(232, 125, 203, 0.3);
background: linear-gradient(135deg, rgba(232, 125, 203, 0.9) 0%, rgba(217, 38, 169, 0.7) 100%);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 2px 8px rgba(255, 255, 255, 0.2), 0 0 20px rgba(232, 125, 203, 0.3);
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
cursor: pointer;
text-align: center;
font-weight: 700;
color: white;
text-transform: uppercase;
letter-spacing: 1px;
animation: pulseGlow 3s ease-in-out infinite;
}
/* ============= КАРТОЧКИ ТАРИФОВ ============= */
.pricing-card {
position: relative;
overflow: hidden;
border: 1px solid hsl(var(--border));
background: linear-gradient(135deg, hsl(var(--card)) 0%, hsl(var(--card-hover)) 100%);
padding: 2rem;
border-radius: 16px;
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
z-index: 1;
animation: fadeInUp 0.8s ease-out;
max-width: 450px;
margin: 0 auto 2rem;
}
.pricing-card:hover {
border-color: hsl(var(--upgrade) / 0.6);
transform: translateY(-8px) scale(1.02);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), 0 0 30px rgba(16, 185, 129, 0.2);
}
.badge-upgrade {
padding: 8px 16px;
border-radius: 8px;
font-size: 0.8rem;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 600;
background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.1) 100%);
color: #10b981;
border: 1px solid rgba(16, 185, 129, 0.3);
animation: slideInLeft 0.6s ease-out;
}
/* ============= КНОПКИ ============= */
.btn-upgrade {
background: linear-gradient(135deg, #10b981 0%, #0d9668 100%);
color: white;
padding: 12px 24px;
border-radius: 8px;
border: none;
font-weight: 600;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
text-decoration: none;
font-size: 0.9rem;
position: relative;
overflow: hidden;
width: 100%;
}
.btn-upgrade:hover {
background: linear-gradient(135deg, #0d9668 0%, #0a7c55 100%);
text-decoration: none;
color: white;
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(16, 185, 129, 0.4);
}
/* ============= СЕТКА И МАКЕТ ============= */
.upgrade-hero {
position: relative;
padding: 2rem 0;
}
.upgrade-hero-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.upgrade-header {
text-align: center;
margin-bottom: 3rem;
animation: fadeInUp 0.8s ease-out 0.2s both;
}
.upgrade-title {
font-size: 3rem;
font-weight: 800;
margin-bottom: 1rem;
line-height: 1.1;
background: linear-gradient(135deg, #f3f4f6 0%, #10b981 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.upgrade-description {
color: #9ca3af;
font-size: 1.1rem;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.pricing-grid {
display: flex;
justify-content: center;
gap: 2rem;
max-width: 500px;
margin: 0 auto;
}
/* ============= КОМПОНЕНТЫ КАРТОЧЕК ============= */
.pricing-badge {
margin-bottom: 1.5rem;
display: flex;
justify-content: center;
}
.pricing-title {
font-size: 2rem;
font-weight: 800;
color: #f3f4f6;
margin-bottom: 1.5rem;
text-align: center;
background: linear-gradient(135deg, #e87dcb 0%, #10b981 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.premium-banner-container {
text-align: center;
margin-bottom: 2rem;
}
.pricing-section {
margin-bottom: 2rem;
text-align: center;
}
.price-display {
display: flex;
align-items: baseline;
justify-content: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.price-amount {
font-size: 3rem;
font-weight: 800;
color: #f3f4f6;
line-height: 1;
}
.price-currency {
color: #9ca3af;
font-size: 1.5rem;
font-weight: 600;
}
.price-duration {
color: #10b981;
margin-top: 0.5rem;
margin-bottom: 0;
font-size: 1rem;
font-weight: 600;
}
.action-buttons {
margin-bottom: 2rem;
}
.features-section {
margin-bottom: 2rem;
padding: 1.5rem;
background: rgba(255, 255, 255, 0.03);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.feature-row {
display: grid;
grid-template-columns: 1fr auto;
gap: 1rem;
align-items: center;
margin-bottom: 1rem;
font-size: 0.9rem;
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.feature-row:last-child {
border-bottom: none;
margin-bottom: 0;
}
.feature-label {
color: #9ca3af;
font-weight: 500;
}
/* ============= ПРЕДПРОСМОТР ПРОФИЛЯ ============= */
.preview-section {
margin-bottom: 2rem;
padding: 1.5rem;
background: rgba(255, 255, 255, 0.03);
border-radius: 12px;
border: 2px dashed rgba(16, 185, 129, 0.3);
text-align: center;
}
.preview-label {
display: block;
color: #10b981;
font-size: 0.8rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 1rem;
opacity: 0.8;
}
.user-preview {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
padding: 1rem;
}
.user-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid rgba(232, 125, 203, 0.5);
box-shadow: 0 0 15px rgba(232, 125, 203, 0.3);
}
.user-info-preview {
display: flex;
align-items: center;
gap: 0.75rem;
}
.user-name {
font-weight: 600;
color: #e87dcb;
font-size: 1.1rem;
text-shadow: 0 0 10px rgba(232, 125, 203, 0.5);
}
.votes-section {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
font-size: 0.9rem;
justify-content: center;
}
.vote-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border-radius: 6px;
background: rgba(255, 255, 255, 0.05);
}
.vote-up {
color: #10b981;
border: 1px solid rgba(16, 185, 129, 0.3);
}
.vote-down {
color: #ef4444;
border: 1px solid rgba(239, 68, 68, 0.3);
}
.vote-count {
font-weight: 700;
font-size: 1rem;
}
.bonus-section {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 2rem;
padding: 1rem 1.5rem;
background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(16, 185, 129, 0.05) 100%);
border-radius: 12px;
border: 1px solid rgba(16, 185, 129, 0.2);
}
.bonus-label {
color: #9ca3af;
font-size: 0.9rem;
flex: 1;
font-weight: 500;
}
.bonus-amount {
color: #10b981;
font-weight: 800;
font-size: 1.25rem;
}
.benefits-section {
margin-top: 2rem;
}
.benefits-title {
font-size: 1rem;
font-weight: 700;
color: #f3f4f6;
margin-bottom: 1rem;
text-align: center;
padding-bottom: 0.5rem;
border-bottom: 2px solid rgba(16, 185, 129, 0.3);
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.benefit-item {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin-bottom: 0.75rem;
font-size: 0.9rem;
color: #d1d5db;
padding: 0.5rem;
border-radius: 6px;
transition: all 0.3s ease;
}
.benefit-item:hover {
background: rgba(255, 255, 255, 0.05);
transform: translateX(5px);
}
/* ============= КАСТОМНАЯ ОШИБКА ============= */
.upgrade-error {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, rgba(239, 68, 68, 0.05) 100%);
border: 1px solid rgba(239, 68, 68, 0.3);
color: #fca5a5;
padding: 1.5rem;
border-radius: 12px;
text-align: center;
margin-bottom: 2rem;
animation: fadeInUp 0.8s ease-out;
}
.upgrade-error-icon {
font-size: 3rem;
margin-bottom: 1rem;
color: #ef4444;
}
.upgrade-error-title {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: #fecaca;
}
.upgrade-error-message {
color: #fca5a5;
font-size: 1rem;
line-height: 1.5;
}
/* ============= SVG ИКОНКИ ============= */
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.125em;
fill: currentColor;
}
.svg-icon-sm {
width: 0.875em;
height: 0.875em;
}
.svg-icon-lg {
width: 1.25em;
height: 1.25em;
}
/* ============= АДАПТИВНОСТЬ ============= */
@media (max-width: 768px) {
.upgrade-title {
font-size: 2rem !important;
}
.pricing-grid {
grid-template-columns: 1fr;
max-width: 100%;
}
.pricing-card {
padding: 1.5rem;
margin: 0 1rem;
}
.price-amount {
font-size: 2.5rem;
}
}
@media (max-width: 480px) {
.upgrade-hero {
padding: 1rem 0;
}
.upgrade-title {
font-size: 1.75rem !important;
}
.upgrade-description {
font-size: 1rem !important;
padding: 0 1rem;
}
.pricing-title {
font-size: 1.75rem;
}
.feature-row {
grid-template-columns: 1fr;
gap: 0.5rem;
text-align: center;
}
.user-preview {
flex-direction: column;
gap: 0.75rem;
}
}
</xf:css>
<xf:if contentcheck="true">
<xf:contentcheck>
<div class="account-upgrades-container">
<!-- Анимированный фон -->
<div class="animated-background">
<div class="animated-background-overlay"></div>
<div class="glow-orb glow-orb-1"></div>
<div class="glow-orb glow-orb-2"></div>
<div class="glow-orb glow-orb-3"></div>
</div>
<!-- Hero секция -->
<div class="upgrade-hero">
<div class="upgrade-hero-container">
<!-- Заголовок -->
<div class="upgrade-header">
<h1 class="upgrade-title">
Выведите свой опыт<br>на новый уровень
</h1>
<p class="upgrade-description">
Обновите свой аккаунт, чтобы получить доступ к эксклюзивным преимуществам и специальным привилегиям
</p>
</div>
<!-- Проверка на уже имеющееся повышение -->
<xf:if is="$purchased is not empty">
<div class="upgrade-error">
<div class="upgrade-error-icon">
<svg class="svg-icon-lg" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10"/>
<path d="m15 9-6 6m0-6 6 6"/>
</svg>
</div>
<h3 class="upgrade-error-title">У вас уже есть активное повышение!</h3>
<p class="upgrade-error-message">
Вы не можете приобрести новое повышение, пока у вас активно текущее.
Дождитесь окончания срока действия текущего повышения или отмените его.
</p>
</div>
</xf:if>
<!-- Доступные повышения -->
<xf:if is="$available is not empty">
<div class="pricing-grid">
<xf:foreach loop="$available" value="$upgrade">
<div class="pricing-card">
<!-- Бейдж -->
<div class="pricing-badge">
<span class="badge-upgrade">
<svg class="svg-icon" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
Премиум обновление
</span>
</div>
<!-- Заголовок -->
<h3 class="pricing-title">PREMIUM</h3>
<!-- Premium баннер -->
<div class="premium-banner-container">
<div class="forum-banner-premium">
<svg class="svg-icon" viewBox="0 0 24 24" style="margin-right: 8px;">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
PREMIUM
</div>
</div>
<!-- Цена -->
<div class="pricing-section">
<div class="price-display">
<span class="price-amount">150</span>
<span class="price-currency">₽</span>
</div>
<p class="price-duration">Навсегда</p>
</div>
<!-- Кнопка обновления -->
<div class="action-buttons">
<xf:form action="{{ link('purchase', $upgrade, {'user_upgrade_id': $upgrade.user_upgrade_id}) }}" ajax="true" data-xf-init="payment-provider-container">
<xf:if is="{{ count($upgrade.payment_profile_ids) > 1 }}">
<xf:select name="payment_profile_id" class="inputGroup">
<xf:option>{{ phrase('(choose_payment_method)') }}</xf:option>
<xf:foreach loop="$upgrade.payment_profile_ids" value="$profileId">
<xf:if is="{$profiles.{$profileId}}">
<xf:set var="$profileTitle" value="{$profiles.{$profileId}.display_title}" />
<xf:if is="!{$profileTitle}">
<xf:set var="$profileTitle" value="{$profiles.{$profileId}.title}" />
</xf:if>
<xf:option value="{$profileId}">{$profileTitle}</xf:option>
</xf:if>
</xf:foreach>
</xf:select>
<xf:button type="submit" class="btn-upgrade" icon="purchase">
<svg class="svg-icon" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
Обновить
</xf:button>
<xf:else />
<xf:button type="submit" class="btn-upgrade" icon="purchase">
<svg class="svg-icon" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
Обновить
</xf:button>
<xf:hiddenval name="payment_profile_id">{$upgrade.payment_profile_ids|first}</xf:hiddenval>
</xf:if>
<div class="js-paymentProviderReply-user_upgrade{$upgrade.user_upgrade_id}"></div>
</xf:form>
</div>
<!-- Предпросмотр профиля -->
<div class="preview-section">
<span class="preview-label">Предпросмотр вашего профиля</span>
<div class="user-preview">
<xf:avatar user="$xf.visitor" size="m" class="user-avatar" />
<div class="user-info-preview">
<span class="user-name">{$xf.visitor.username}</span>
<span class="vip-badge">
<svg class="svg-icon-sm" viewBox="0 0 24 24">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
VIP
</span>
</div>
</div>
<div class="votes-section">
<div class="vote-item vote-up">
<svg class="svg-icon-sm" viewBox="0 0 24 24">
<path d="M7 10v12M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z"/>
</svg>
<span class="vote-count">+1</span>
</div>
<div class="vote-item vote-down">
<svg class="svg-icon-sm" viewBox="0 0 24 24">
<path d="M17 14V2M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22h0a3.13 3.13 0 0 1-3-3.88Z"/>
</svg>
<span class="vote-count">-1</span>
</div>
</div>
</div>
<!-- Бонусные баллы -->
<div class="bonus-section">
<span class="bonus-label">Бонусные биты</span>
<svg class="svg-icon-lg" viewBox="0 0 24 24" style="color: #10b981;">
<circle cx="12" cy="12" r="10"/>
<path d="m9 12 2 2 4-4"/>
</svg>
<span class="bonus-amount">1500</span>
</div>
<!-- Преимущества -->
<div class="benefits-section">
<h4 class="benefits-title">
<svg class="svg-icon" viewBox="0 0 24 24">
<path d="m9 12 2 2 4-4"/>
<circle cx="12" cy="12" r="10"/>
</svg>
Преимущества PREMIUM
</h4>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Создание собственной гильдии</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Загрузка фона форума</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Загрузка GIF баннеров и аватарок</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Редактор box-VIP</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Редактор пользовательского CSS</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Нет ограничений на темы и сообщения</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Убраны проверки на флуд</span>
</div>
<div class="benefit-item">
<svg class="svg-icon" viewBox="0 0 24 24" style="color: #10b981;">
<polyline points="20 6 9 17 4 12"/>
</svg>
<span>Доступ ко всем наградам и значкам</span>
</div>
</div>
</div>
</xf:foreach>
</div>
</xf:if>
<!-- Приобретенные повышения -->
<xf:if is="$purchased is not empty">
<div class="block">
<div class="block-container">
<h2 class="block-header">{{ phrase('purchased_upgrades') }}</h2>
<ul class="block-body listPlain">
<xf:foreach loop="$purchased" value="$upgrade">
<li>
<div class="pricing-card">
<h3 class="pricing-title">{$upgrade.title}</h3>
<div class="features-section">
<xf:set var="$active" value="{$upgrade.Active.{$xf.visitor.user_id}}" />
<div class="feature-row">
<span class="feature-label">Статус:</span>
<xf:if is="$active.end_date">
<span>Истекает: <xf:date time="{$active.end_date}" /></span>
<xf:else />
<span>{{ phrase('expires_never') }}</span>
</xf:if>
</div>
</div>
</div>
</li>
</xf:foreach>
</ul>
</div>
</div>
</xf:if>
</div>
</div>
</div>
</xf:contentcheck>
<xf:else />
<div class="blockMessage">{{ phrase('there_currently_no_purchasable_user_upgrades') }}</div>
</xf:if>