Files
veilix.app/design/handoff/project/MassApp.dc.html
T
2026-10-21 03:30:38 +02:00

985 lines
80 KiB
HTML
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.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="icon" type="image/svg+xml" href="favicon-mass.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Commissioner:wght@300;400;500;600&family=Unbounded:wght@500;600&display=swap" rel="stylesheet" />
<script>(function(){if(window.__veilixI18nSrc)return;window.__veilixI18nSrc="./i18n.js?v="+Date.now().toString(36)+Math.random().toString(36).slice(2,8);var s=document.createElement("script");s.src=window.__veilixI18nSrc;document.head.appendChild(s);})();</script>
<style>
:root{
--bg: oklch(99.6% 0.0015 215);
--surface: oklch(100% 0 0);
--surface-2: oklch(98.4% 0.003 215);
--ink: oklch(24% 0.04 204);
--ink-2: oklch(45% 0.03 204);
--ink-3: oklch(60% 0.025 204);
--border: oklch(92% 0.014 200);
--accent: oklch(48% 0.105 178);
--accent-hover: oklch(41% 0.1 178);
--accent-soft: oklch(95.5% 0.032 180);
--sel: oklch(96.5% 0.016 190);
--on-accent: oklch(99% 0.01 180);
--glow-1: oklch(86% 0.085 190);
--glow-2: oklch(88% 0.075 205);
--glow-3: oklch(89% 0.07 172);
--veil: oklch(100% 0 0 / 0.55);
--warn: oklch(62% 0.14 62);
--shadow: 0 1px 2px oklch(24% 0.04 204 / 0.05), 0 12px 32px -12px oklch(24% 0.04 204 / 0.14);
}
:root[data-veilix-theme="dark"]{
--bg: oklch(23% 0.026 210);
--surface: oklch(26.5% 0.028 210);
--surface-2: oklch(30% 0.03 210);
--ink: oklch(96% 0.012 196);
--ink-2: oklch(80% 0.02 196);
--ink-3: oklch(65% 0.025 196);
--border: oklch(36% 0.04 204);
--accent: oklch(76% 0.105 190);
--accent-hover: oklch(83% 0.09 190);
--accent-soft: oklch(31% 0.05 190);
--sel: oklch(30% 0.03 195);
--on-accent: oklch(20% 0.04 204);
--glow-1: oklch(52% 0.09 200);
--glow-2: oklch(47% 0.085 215);
--glow-3: oklch(50% 0.08 180);
--veil: oklch(100% 0 0 / 0.07);
--warn: oklch(78% 0.13 62);
--shadow: 0 1px 2px oklch(12% 0.03 204 / 0.4), 0 16px 40px -16px oklch(9% 0.03 204 / 0.7);
}
*{ box-sizing: border-box; }
input, textarea, select{ font-size: 16px; }
[hidden]{ display: none !important; }
body{ margin:0; background: var(--bg); color: var(--ink); font-family:"Commissioner", system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
a{ color: var(--accent); text-decoration: none; }
a:hover{ color: var(--accent-hover); }
input::placeholder{ color: var(--ink-3); }
</style>
</helmet>
<template id="__bundler_thumbnail" data-bg-color="#e3f4f1">
<svg viewBox="0 0 1200 800" xmlns="http://www.w3.org/2000/svg">
<rect x="480" y="290" width="150" height="150" rx="48" fill="#00705e" />
<rect x="570" y="360" width="150" height="150" rx="48" fill="#ffffff" fill-opacity="0.62" stroke="#00705e" stroke-width="6" />
</svg>
</template>
<div style="background: var(--bg); color: var(--ink); font-family: 'Commissioner', system-ui, sans-serif; letter-spacing: -0.01em; min-height: 100vh;">
<div hidden="{{ appOff }}" style="display: grid; grid-template-rows: 1fr auto; min-height: 100vh;">
<div style="display: flex; align-items: center; justify-content: center; padding: 24px;">
<div style="width: 100%; max-width: 420px; padding: 36px; border-radius: 24px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 26px;">
<span style="position: relative; width: 26px; height: 26px; display: block; flex: none;">
<span style="position: absolute; left: 0; top: 3px; width: 19px; height: 19px; border-radius: 6px; background: linear-gradient(140deg, var(--accent), color-mix(in oklab, var(--accent) 55%, var(--glow-3))); display: block;"></span>
<span style="position: absolute; right: 0; bottom: 3px; width: 19px; height: 19px; border-radius: 6px; background: var(--veil); border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent); display: block;"></span>
</span>
<span style="font-family: 'Unbounded', 'Commissioner', sans-serif; font-weight: 600; font-size: 16px; letter-spacing: -0.02em;">ВейликсВПН</span>
</div>
<h1 style="margin: 0 0 10px; font-size: 26px; font-weight: 600; letter-spacing: -0.03em;">Вход в кабинет</h1>
<p style="margin: 0 0 22px; font-size: 15px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Введите почту, пришлём одноразовый код. Отдельной регистрации нет — кабинет создастся сам, если вы здесь впервые.</p>
<div hidden="{{ otpSent }}" style="display: grid; gap: 10px;">
<input type="email" placeholder="you@example.com" style="height: 50px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; width: 100%;" />
<button type="button" onClick="{{ sendOtp }}" style="height: 50px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 16px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">Прислать код</button>
</div>
<div hidden="{{ otpNotSent }}" style="display: grid; gap: 10px;">
<input type="text" inputmode="numeric" placeholder="6 цифр" style="height: 50px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 17px; letter-spacing: 0.28em; font-variant-numeric: tabular-nums; width: 100%;" />
<button type="button" onClick="{{ signIn }}" style="height: 50px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 16px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">Войти</button>
<button type="button" onClick="{{ backToEmail }}" style="justify-self: start; border: 0; background: transparent; color: var(--ink-3); font-family: inherit; font-size: 14px; cursor: pointer; padding: 4px 0;">Другая почта</button>
</div>
</div>
</div>
<footer style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; padding: 14px 24px; border-top: 1px solid var(--border); font-size: 13px; color: var(--ink-3);">
<span>© 2026 ВейликсВПН</span>
<a href="#legal" style="color: var(--ink-3);" style-hover="color: var(--ink);">Условия</a>
<a href="#legal" style="color: var(--ink-3);" style-hover="color: var(--ink);">Конфиденциальность</a>
<a href="MassSupport.dc.html" style="color: var(--ink-3);" style-hover="color: var(--ink);">Поддержка</a>
<div style="margin-left: auto; display: flex; align-items: center; gap: 8px;">
<div style="display: flex; width: max-content; padding: 3px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface);">
<button type="button" onClick="{{ setRu }}" style="padding: 6px 11px; border: 0; border-radius: 7px; background: {{ ruBg }}; color: {{ ruInk }}; font-family: inherit; font-size: 12px; cursor: pointer;">RU</button>
<button type="button" onClick="{{ setEn }}" style="padding: 6px 11px; border: 0; border-radius: 7px; background: {{ enBg }}; color: {{ enInk }}; font-family: inherit; font-size: 12px; cursor: pointer;">EN</button>
</div>
<div style="display: flex; width: max-content; padding: 3px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface);">
<button type="button" onClick="{{ setLight }}" title="Светлая тема" style="display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: 7px; background: {{ lightBg }}; color: {{ lightInk }}; cursor: pointer;">
<span style="position: relative; width: 16px; height: 16px; display: block;">
<span style="position: absolute; left: 3.5px; top: 3.5px; width: 9px; height: 9px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 0; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; opacity: 0.45; display: block;"></span>
</span>
</button>
<button type="button" onClick="{{ setDark }}" title="Тёмная тема" style="display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: 7px; background: {{ darkBg }}; color: {{ darkInk }}; cursor: pointer;">
<span style="width: 16px; height: 16px; border-radius: 50%; box-shadow: inset -5px -2px 0 0 currentColor; display: block;"></span>
</button>
<button type="button" onClick="{{ setSystem }}" title="Как в системе" style="display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: 7px; background: {{ systemBg }}; color: {{ systemInk }}; cursor: pointer;">
<span style="width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; background: linear-gradient(90deg, currentColor 50%, transparent 50%); display: block;"></span>
</button>
</div>
</div>
</footer>
</div>
<div hidden="{{ loginOff }}" style="display: grid; grid-template-columns: {{ shellCols }}; min-height: 100vh;">
<div hidden="{{ topbarOff }}" style="position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: color-mix(in oklab, var(--bg) 85%, transparent); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); border-bottom: 1px solid var(--border);">
<a href="MassMain.dc.html" style="display: flex; align-items: center; gap: 10px; color: var(--ink);">
<span style="position: relative; width: 24px; height: 24px; display: block; flex: none;">
<span style="position: absolute; left: 0; top: 3px; width: 18px; height: 18px; border-radius: 6px; background: linear-gradient(140deg, var(--accent), color-mix(in oklab, var(--accent) 55%, var(--glow-3))); display: block;"></span>
<span style="position: absolute; right: 0; bottom: 3px; width: 18px; height: 18px; border-radius: 6px; background: var(--veil); border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent); display: block;"></span>
</span>
<span style="font-family: 'Unbounded', 'Commissioner', sans-serif; font-weight: 600; font-size: 15px; letter-spacing: -0.02em;">ВейликсВПН</span>
</a>
</div>
<aside hidden="{{ asideOff }}" style="display: flex; flex-direction: column; gap: 24px; padding: 22px 16px; border-right: 1px solid var(--border); background: var(--surface-2); position: sticky; top: 0; height: 100vh;">
<a href="MassMain.dc.html" style="display: flex; align-items: center; gap: 10px; padding: 4px 8px; color: var(--ink);">
<span style="position: relative; width: 24px; height: 24px; display: block; flex: none;">
<span style="position: absolute; left: 0; top: 3px; width: 18px; height: 18px; border-radius: 6px; background: linear-gradient(140deg, var(--accent), color-mix(in oklab, var(--accent) 55%, var(--glow-3))); display: block;"></span>
<span style="position: absolute; right: 0; bottom: 3px; width: 18px; height: 18px; border-radius: 6px; background: var(--veil); border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent); display: block;"></span>
</span>
<span style="font-family: 'Unbounded', 'Commissioner', sans-serif; font-weight: 600; font-size: 15px; letter-spacing: -0.02em;">ВейликсВПН</span>
</a>
<nav style="display: grid; gap: 4px;">
<button type="button" onClick="{{ goHome }}" style="display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 12px; border: 0; background: {{ homeBg }}; color: {{ homeInk }}; font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;" style-hover="background: var(--surface);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 0; top: 0; width: 8px; height: 8px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; right: 0; top: 0; width: 8px; height: 8px; border-radius: 2px; background: currentColor; opacity: 0.45; display: block;"></span>
<span style="position: absolute; left: 0; bottom: 0; width: 8px; height: 8px; border-radius: 2px; background: currentColor; opacity: 0.45; display: block;"></span>
<span style="position: absolute; right: 0; bottom: 0; width: 8px; height: 8px; border-radius: 2px; background: currentColor; display: block;"></span>
</span>
Главная
</button>
<button type="button" onClick="{{ goKeys }}" style="display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 12px; border: 0; background: {{ keysBg }}; color: {{ keysInk }}; font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;" style-hover="background: var(--surface);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 0; top: 2px; width: 18px; height: 4px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 8px; width: 18px; height: 4px; border-radius: 2px; background: currentColor; opacity: 0.6; display: block;"></span>
<span style="position: absolute; left: 0; top: 14px; width: 18px; height: 4px; border-radius: 2px; background: currentColor; opacity: 0.3; display: block;"></span>
</span>
Подключения
</button>
<button type="button" onClick="{{ goBuy }}" style="display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 12px; border: 0; background: {{ buyBg }}; color: {{ buyInk }}; font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;" style-hover="background: var(--surface);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 7px; top: 0; width: 4px; height: 18px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 7px; width: 18px; height: 4px; border-radius: 2px; background: currentColor; display: block;"></span>
</span>
Выбрать страну
</button>
<button type="button" onClick="{{ goBilling }}" style="display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 12px; border: 0; background: {{ billingBg }}; color: {{ billingInk }}; font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;" style-hover="background: var(--surface);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 0; top: 2px; width: 18px; height: 14px; border-radius: 4px; border: 2px solid currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 6px; width: 18px; height: 3px; background: currentColor; display: block;"></span>
</span>
Счёт и платежи
</button>
<button type="button" onClick="{{ goRef }}" style="display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 12px; border: 0; background: {{ refBg }}; color: {{ refInk }}; font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;" style-hover="background: var(--surface);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 0; top: 5px; width: 8px; height: 8px; border-radius: 50%; border: 2px solid currentColor; display: block;"></span>
<span style="position: absolute; right: 0; top: 0; width: 8px; height: 8px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; right: 2px; bottom: 0; width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: 0.45; display: block;"></span>
</span>
Реферальная программа
</button>
</nav>
<div style="margin-top: auto; display: grid; gap: 14px; padding: 0 4px;">
<a href="MassSupport.dc.html" style="display: flex; align-items: center; gap: 12px; padding: 11px 8px; border-radius: 12px; color: var(--ink-2); font-size: 15px;" style-hover="background: var(--surface); color: var(--ink);">
<span style="position: relative; width: 18px; height: 18px; flex: none; display: block;">
<span style="position: absolute; left: 1px; top: 1px; width: 16px; height: 16px; border-radius: 8px 8px 0 0; border: 2px solid currentColor; border-bottom: 0; display: block;"></span>
<span style="position: absolute; left: 0; top: 8px; width: 5px; height: 9px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; right: 0; top: 8px; width: 5px; height: 9px; border-radius: 2px; background: currentColor; display: block;"></span>
</span>
Поддержка
</a>
<div>
<div style="font-size: 12px; color: var(--ink-3); margin-bottom: 6px; padding: 0 4px;">Тема</div>
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 6px; width: max-content; max-width: 100%; align-self: start; padding: 3px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface);">
<button type="button" onClick="{{ setLight }}" title="Светлая тема" style="display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 0; border-radius: 9px; background: {{ lightBg }}; color: {{ lightInk }}; cursor: pointer;">
<span style="position: relative; width: 18px; height: 18px; display: block;">
<span style="position: absolute; left: 4px; top: 4px; width: 10px; height: 10px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 0; width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid currentColor; opacity: 0.45; display: block;"></span>
</span>
</button>
<button type="button" onClick="{{ setDark }}" title="Тёмная тема" style="display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 0; border-radius: 9px; background: {{ darkBg }}; color: {{ darkInk }}; cursor: pointer;">
<span style="width: 18px; height: 18px; border-radius: 50%; box-shadow: inset -6px -2px 0 0 currentColor; display: block;"></span>
</button>
<button type="button" onClick="{{ setSystem }}" title="Как в системе" style="display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 0; border-radius: 9px; background: {{ systemBg }}; color: {{ systemInk }}; cursor: pointer;">
<span style="width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid currentColor; background: linear-gradient(90deg, currentColor 50%, transparent 50%); display: block;"></span>
</button>
</div>
</div>
<div>
<div style="font-size: 12px; color: var(--ink-3); margin-bottom: 6px; padding: 0 4px;">Язык</div>
<div style="display: flex; flex-wrap: wrap; width: max-content; max-width: 100%; align-self: start; padding: 3px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface);">
<button type="button" onClick="{{ setRu }}" style="padding: 8px 14px; border: 0; border-radius: 9px; background: {{ ruBg }}; color: {{ ruInk }}; font-family: inherit; font-size: 13px; cursor: pointer;">RU</button>
<button type="button" onClick="{{ setEn }}" style="padding: 8px 14px; border: 0; border-radius: 9px; background: {{ enBg }}; color: {{ enInk }}; font-family: inherit; font-size: 13px; cursor: pointer;">EN</button>
</div>
</div>
<button type="button" onClick="{{ signOut }}" style="justify-self: start; border: 0; background: transparent; color: var(--ink-3); font-family: inherit; font-size: 13px; cursor: pointer; padding: 4px 8px;">Выйти · anna@example.com</button>
</div>
</aside>
<main style="padding: {{ mainPad }}; max-width: 960px;">
<div hidden="{{ homeOff }}" style="display: grid; gap: 28px;">
<div>
<h1 style="margin: 0 0 6px; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">Ваша подписка</h1>
<p style="margin: 0; font-size: 15px; color: var(--ink-2); font-weight: 300;">Тридцать стран и российский адрес, до пяти устройств.</p>
</div>
<div style="display: grid; gap: 12px;">
<sc-for list="{{ keys }}" as="key" hint-placeholder-count="2">
<button type="button" onClick="{{ key.open }}" style="display: grid; gap: 16px; padding: 24px; border-radius: 20px; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow); color: var(--ink); font-family: inherit; text-align: left; cursor: pointer; width: 100%;" style-hover="border-color: var(--accent);">
<span style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px;">
<span style="font-size: 19px; font-weight: 500; letter-spacing: -0.02em;">{{ key.title }}</span>
<span style="padding: 4px 10px; border-radius: 8px; background: {{ key.badgeBg }}; color: {{ key.badgeInk }}; font-size: 12px;">{{ key.badge }}</span>
<span style="margin-left: auto; font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums;">{{ key.ip }}</span>
</span>
<span style="display: flex; flex-wrap: wrap; gap: 8px 28px; font-size: 14px; color: var(--ink-2);">
<span>Действует до {{ key.until }}</span>
<span>{{ key.devices }}</span>
<span>{{ key.payment }}</span>
</span>
</button>
</sc-for>
</div>
<div style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; padding: 24px; border-radius: 20px; background: var(--surface-2); border: 1px dashed var(--border);">
<div style="display: grid; gap: 4px;">
<div style="font-size: 17px; font-weight: 500;">Хотите другую страну</div>
<div style="font-size: 14px; color: var(--ink-2); font-weight: 300;">Все локации уже в подписке, переключение бесплатное.</div>
</div>
<button type="button" onClick="{{ goBuy }}" style="height: 46px; padding: 0 22px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 15px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">Сменить страну</button>
</div>
<div style="display: grid; gap: 10px;">
<h2 style="margin: 0 0 4px; font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">Короткие ответы</h2>
<sc-for list="{{ faq }}" as="item" hint-placeholder-count="3">
<div style="border: 1px solid var(--border); border-radius: 16px; background: var(--surface); overflow: hidden;">
<button type="button" onClick="{{ item.toggle }}" style="display: flex; align-items: center; gap: 16px; width: 100%; padding: 17px 20px; background: transparent; border: 0; color: var(--ink); font-family: inherit; font-size: 16px; font-weight: 500; text-align: left; cursor: pointer;">
<span style="flex: 1;">{{ item.q }}</span>
<span style="flex: none; width: 9px; height: 9px; border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3); transform: {{ item.rot }}; transition: transform 180ms ease; display: block;"></span>
</button>
<div hidden="{{ item.off }}" style="padding: 0 20px 20px; font-size: 15px; line-height: 1.6; color: var(--ink-2); font-weight: 300; max-width: 62ch;">{{ item.a }}</div>
</div>
</sc-for>
</div>
</div>
<div hidden="{{ keysOff }}" style="display: grid; gap: 20px;">
<h1 style="margin: 0; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">Подключения</h1>
<div style="display: grid; gap: 12px;">
<sc-for list="{{ allKeys }}" as="key" hint-placeholder-count="3">
<button type="button" onClick="{{ key.open }}" style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; padding: 20px 24px; border-radius: 18px; border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-family: inherit; text-align: left; cursor: pointer; width: 100%;" style-hover="border-color: var(--accent);">
<span style="font-size: 17px; font-weight: 500;">{{ key.title }}</span>
<span style="padding: 4px 10px; border-radius: 8px; background: {{ key.badgeBg }}; color: {{ key.badgeInk }}; font-size: 12px;">{{ key.badge }}</span>
<span style="margin-left: auto; font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums;">{{ key.ip }}</span>
<span style="font-size: 14px; color: var(--ink-2); font-variant-numeric: tabular-nums;">{{ key.untilLine }}</span>
</button>
</sc-for>
</div>
</div>
<div hidden="{{ keyOff }}" style="display: grid; gap: 22px;">
<button type="button" onClick="{{ goKeys }}" style="justify-self: start; border: 0; background: transparent; color: var(--ink-3); font-family: inherit; font-size: 14px; cursor: pointer; padding: 0;">← Все подключения</button>
<div style="display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px 20px;">
<h1 style="margin: 0; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">{{ cur.title }}</h1>
<span style="font-size: 15px; color: var(--ink-3); font-variant-numeric: tabular-nums;">{{ cur.ip }}</span>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px;">
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Действует до</div>
<div style="font-size: 24px; font-weight: 600; letter-spacing: -0.025em;">{{ cur.until }}</div>
<div style="margin-top: 8px; font-size: 14px; color: {{ cur.leftInk }};">{{ cur.left }}</div>
</div>
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Оплата</div>
<div style="font-size: 18px; font-variant-numeric: tabular-nums;">{{ cur.card }}</div>
<div style="margin-top: 8px; font-size: 14px; color: var(--ink-2);">699 ₽ в месяц · карта аккаунта</div>
<button type="button" onClick="{{ goBilling }}" style="margin-top: 14px; height: 40px; padding: 0 16px; border-radius: 10px; border: 1px solid var(--border); background: transparent; color: var(--ink); font-family: inherit; font-size: 14px; cursor: pointer;" style-hover="border-color: var(--ink-3);">Счёт и платежи</button>
</div>
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Устройства</div>
<div style="font-size: 24px; font-weight: 600; letter-spacing: -0.025em;">{{ cur.devices }}</div>
<div style="margin-top: 8px; font-size: 14px; color: var(--ink-2);">Каждое в своей стране</div>
</div>
</div>
<div style="padding: 26px; border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px;">
<h2 style="margin: 0; font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">Конфигурации XRAY</h2>
<span style="font-size: 13px; color: var(--ink-3);">5 конфигураций — по одной на устройство</span>
</div>
<p style="margin: 0 0 18px; font-size: 14px; color: var(--ink-2); font-weight: 300; max-width: 60ch;">На компьютере скачайте файл и откройте его в клиенте XRAY. На телефоне — отсканируйте QR-код.</p>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px;">
<sc-for list="{{ configs }}" as="cfg" hint-placeholder-count="5">
<div style="display: grid; gap: 12px; padding: 16px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--border);">
<div style="display: flex; align-items: center; justify-content: space-between; gap: 10px;">
<span style="font-size: 15px; font-weight: 500;">{{ cfg.name }}</span>
<span style="font-size: 12px; color: var(--ink-3);">{{ cfg.state }}</span>
</div>
<div style="display: flex; gap: 8px;">
<button type="button" style="flex: 1; height: 38px; border-radius: 10px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 14px; cursor: pointer;" style-hover="background: var(--accent-hover);">Скачать</button>
<button type="button" onClick="{{ cfg.showQr }}" style="height: 38px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 14px; cursor: pointer;" style-hover="border-color: var(--ink-3);">QR</button>
</div>
</div>
</sc-for>
</div>
</div>
<div style="padding: 26px; border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px;">
<h2 style="margin: 0; font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">Ссылка подключения</h2>
<span style="font-size: 13px; color: var(--ink-3);">Для Happ и других клиентов XRAY</span>
</div>
<p style="margin: 0 0 18px; font-size: 14px; color: var(--ink-2); font-weight: 300; max-width: 60ch;">Быстрый способ подключить новое устройство. Скопируйте ссылку или отсканируйте код — настройки те же.</p>
<div style="display: flex; flex-wrap: wrap; gap: 10px; align-items: center;">
<div style="flex: 1; min-width: 240px; padding: 14px 16px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border); font-size: 13px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums;">{{ cur.xray }}</div>
<button type="button" onClick="{{ copyXray }}" style="height: 46px; padding: 0 20px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 15px; cursor: pointer;" style-hover="background: var(--accent-hover);">{{ copyLabel }}</button>
<button type="button" onClick="{{ showXrayQr }}" style="height: 46px; padding: 0 18px; border-radius: 12px; border: 1px solid var(--border); background: transparent; color: var(--ink); font-family: inherit; font-size: 15px; cursor: pointer;" style-hover="border-color: var(--ink-3);">QR</button>
</div>
</div>
</div>
<div hidden="{{ buyOff }}" style="display: grid; gap: 22px;">
<div>
<h1 style="margin: 0 0 6px; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">Выбрать страну</h1>
<p style="margin: 0; font-size: 15px; color: var(--ink-2); font-weight: 300;">Все тридцать локаций входят в подписку. Переключение бесплатное и занимает пару секунд.</p>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px;">
<sc-for list="{{ locations }}" as="loc" hint-placeholder-count="12">
<div role="button" tabindex="0" onClick="{{ loc.pick }}" style="display: grid; align-content: start; gap: 14px; padding: 20px; border-radius: 18px; border: 1px solid {{ loc.border }}; background: {{ loc.bg }}; color: var(--ink); cursor: pointer;" style-hover="border-color: var(--ink-3);">
<span style="display: flex; align-items: center; justify-content: space-between; gap: 14px;">
{{ loc.flag }}
<span style="display: flex; align-items: center; gap: 12px; flex: none; min-height: 32px;">
<span hidden="{{ loc.buyOff }}" style="display: flex; align-items: center; justify-content: center; height: 32px; padding: 0 16px; border-radius: 10px; background: var(--accent); color: var(--on-accent); font-size: 14px; font-weight: 500; cursor: pointer;">Выбрать</span>
</span>
</span>
<span style="display: grid; gap: 5px;">
<span style="font-size: 17px; font-weight: 500; letter-spacing: -0.02em;">{{ loc.country }}</span>
<span style="font-size: 14px; color: var(--ink-3);">{{ loc.city }}</span>
</span>
</div>
</sc-for>
</div>
<div style="padding: 24px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border);">
<h2 id="lead" style="margin: 0 0 8px; font-size: 19px; font-weight: 600; letter-spacing: -0.02em; scroll-margin-top: 24px;">Нужны особые условия</h2>
<p style="margin: 0 0 18px; max-width: 60ch; font-size: 14px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Подписки на команду, оплата по счёту или редкая страна. Оставьте заявку — ответим в течение дня.</p>
<button type="button" onClick="{{ openLead }}" hidden="{{ leadOpen }}" style="display: inline-flex; align-items: center; height: 46px; padding: 0 20px; border-radius: 12px; border: 1px solid var(--accent); background: transparent; color: var(--accent); font-family: inherit; font-size: 15px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-soft);">Оставить заявку</button>
<div hidden="{{ leadClosed }}" style="display: grid; gap: 10px; max-width: 460px;">
<input type="text" placeholder="Имя" style="height: 48px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; width: 100%;" />
<input type="email" placeholder="Email" style="height: 48px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; width: 100%;" />
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;">
<input type="text" placeholder="Telegram" style="height: 48px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; width: 100%;" />
<input type="text" placeholder="WhatsApp" style="height: 48px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; width: 100%;" />
</div>
<textarea rows="3" placeholder="Коротко о задаче" style="padding: 12px 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); font-family: inherit; font-size: 15px; resize: vertical; width: 100%;"></textarea>
<button type="button" onClick="{{ sendLead }}" style="display: inline-flex; align-items: center; justify-content: center; height: 48px; padding: 0 22px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 15px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">{{ leadButton }}</button>
</div>
</div>
</div>
<div hidden="{{ billingOff }}" style="display: grid; gap: 22px;">
<div>
<h1 style="margin: 0 0 6px; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">Счёт и платежи</h1>
<p style="margin: 0; max-width: 62ch; font-size: 15px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Карта привязана к аккаунту. Подписка списывается с неё — или с баланса, если на нём есть деньги.</p>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px;">
<div style="display: grid; align-content: start; gap: 8px; padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3);">Баланс</div>
<div style="font-size: 30px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">1 250 ₽</div>
<div style="font-size: 14px; color: var(--ink-2);">Списывается в первую очередь</div>
<button type="button" onClick="{{ openTopup }}" style="justify-self: start; margin-top: 6px; height: 40px; padding: 0 16px; border-radius: 10px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 14px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">Пополнить</button>
</div>
<div style="display: grid; align-content: start; gap: 8px; padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3);">Способ оплаты</div>
<div style="font-size: 20px; font-weight: 500; font-variant-numeric: tabular-nums;">Карта ···· 4242</div>
<div style="font-size: 14px; color: var(--ink-2);">Основная для аккаунта</div>
<button type="button" style="justify-self: start; margin-top: 6px; height: 40px; padding: 0 16px; border-radius: 10px; border: 1px solid var(--border); background: transparent; color: var(--ink); font-family: inherit; font-size: 14px; cursor: pointer;" style-hover="border-color: var(--ink-3);">Изменить карту</button>
</div>
<div style="display: grid; align-content: start; gap: 8px; padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3);">Следующее списание</div>
<div style="font-size: 30px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">699 ₽</div>
<div style="font-size: 14px; color: var(--ink-2);">14 октября · подписка на месяц</div>
<div style="font-size: 13px; color: var(--ink-3);">Год выгоднее: 6 990 ₽ за 12 месяцев</div>
</div>
</div>
<div hidden="{{ topupOff }}" style="display: grid; gap: 16px; padding: 26px; border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px;">
<h2 style="margin: 0; font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">Пополнить баланс</h2>
<button type="button" onClick="{{ closeTopup }}" style="border: 0; background: transparent; color: var(--ink-3); font-family: inherit; font-size: 14px; cursor: pointer; padding: 0;">Свернуть</button>
</div>
<div style="display: grid; gap: 8px;">
<div style="font-size: 13px; color: var(--ink-3);">Сумма</div>
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
<sc-for list="{{ sums }}" as="sum" hint-placeholder-count="4">
<button type="button" onClick="{{ sum.pick }}" style="height: 44px; padding: 0 18px; border-radius: 12px; border: 1px solid {{ sum.border }}; background: {{ sum.bg }}; color: var(--ink); font-family: inherit; font-size: 15px; font-variant-numeric: tabular-nums; cursor: pointer;">{{ sum.label }}</button>
</sc-for>
</div>
</div>
<div style="display: grid; gap: 8px;">
<div style="font-size: 13px; color: var(--ink-3);">Способ</div>
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
<sc-for list="{{ methods }}" as="m" hint-placeholder-count="3">
<button type="button" onClick="{{ m.pick }}" style="height: 44px; padding: 0 18px; border-radius: 12px; border: 1px solid {{ m.border }}; background: {{ m.bg }}; color: var(--ink); font-family: inherit; font-size: 15px; cursor: pointer;">{{ m.label }}</button>
</sc-for>
</div>
</div>
<div hidden="{{ cryptoOff }}" style="display: grid; gap: 10px; padding: 18px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--border);">
<div style="font-size: 15px; font-weight: 500;">USDT (TRC-20), BTC, ETH</div>
<p style="margin: 0; max-width: 60ch; font-size: 14px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Покажем адрес и сумму в выбранной монете. Курс фиксируется на 15 минут, баланс пополнится после одного подтверждения сети.</p>
</div>
<button type="button" onClick="{{ sendTopup }}" style="justify-self: start; height: 48px; padding: 0 22px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 15px; font-weight: 500; cursor: pointer;" style-hover="background: var(--accent-hover);">{{ topupButton }}</button>
</div>
<div style="display: grid; gap: 10px;">
<h2 style="margin: 0 0 4px; font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">История платежей</h2>
<sc-for list="{{ payments }}" as="p" hint-placeholder-count="5">
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; padding: 18px 20px; border-radius: 16px; background: var(--surface); border: 1px solid var(--border);">
<span style="width: 116px; flex: none; font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums;">{{ p.date }}</span>
<span style="flex: 1; min-width: 180px; display: grid; gap: 3px;">
<span style="font-size: 15px;">{{ p.title }}</span>
<span style="font-size: 13px; color: var(--ink-3);">{{ p.method }}</span>
</span>
<span style="font-size: 13px; color: var(--ink-3);">{{ p.status }}</span>
<span style="width: 104px; flex: none; text-align: right; font-size: 16px; font-weight: 500; color: {{ p.ink }}; font-variant-numeric: tabular-nums;">{{ p.amount }}</span>
</div>
</sc-for>
</div>
</div>
<div hidden="{{ refOff }}" style="display: grid; gap: 20px;">
<div>
<h1 style="margin: 0 0 6px; font-size: 30px; font-weight: 600; letter-spacing: -0.03em;">Реферальная программа</h1>
<p style="margin: 0; max-width: 62ch; font-size: 15px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Приведите друга — вы оба получите по месяцу в подарок.</p>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px;">
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Приглашено</div>
<div style="font-size: 30px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">3</div>
</div>
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Месяцев начислено</div>
<div style="font-size: 30px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">2</div>
</div>
<div style="padding: 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 10px;">Ожидает подтверждения</div>
<div style="font-size: 30px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">1</div>
</div>
</div>
<div style="display: grid; gap: 14px; padding: 26px; border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 16px; font-weight: 500;">Ваша ссылка</div>
<div style="display: flex; flex-wrap: wrap; gap: 10px; align-items: center;">
<div style="flex: 1; min-width: 220px; padding: 14px 16px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border); font-size: 14px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">veilix.com/r/anna-7f2c</div>
<button type="button" onClick="{{ copyRef }}" style="height: 46px; padding: 0 20px; border-radius: 12px; border: 0; background: var(--accent); color: var(--on-accent); font-family: inherit; font-size: 15px; cursor: pointer;" style-hover="background: var(--accent-hover);">{{ refLabel }}</button>
</div>
<div style="font-size: 13px; color: var(--ink-3); line-height: 1.5;">Месяц начисляется вам и другу после его первой оплаты и применяется к ближайшему списанию.</div>
</div>
<div style="display: grid; gap: 10px;">
<div style="font-size: 16px; font-weight: 500;">Приглашённые</div>
<div style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-radius: 16px; background: var(--surface); border: 1px solid var(--border);">
<span style="font-size: 15px;">m···@gmail.com</span>
<span style="font-size: 14px; color: var(--accent);">Месяц начислен</span>
</div>
<div style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-radius: 16px; background: var(--surface); border: 1px solid var(--border);">
<span style="font-size: 15px;">d···@yandex.ru</span>
<span style="font-size: 14px; color: var(--accent);">Месяц начислен</span>
</div>
<div style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-radius: 16px; background: var(--surface); border: 1px solid var(--border);">
<span style="font-size: 15px;">k···@icloud.com</span>
<span style="font-size: 14px; color: var(--ink-3);">Ждём оплаты</span>
</div>
</div>
</div>
<div hidden="{{ moreOff }}" style="display: grid; gap: 16px;">
<h1 style="margin: 0; font-size: 26px; font-weight: 600; letter-spacing: -0.03em;">Ещё</h1>
<button type="button" onClick="{{ goBilling }}" style="display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 14px 18px; border-radius: 16px; border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-family: inherit; font-size: 16px; text-align: left; cursor: pointer;">
<span>Счёт и платежи</span>
<span style="color: var(--ink-3);">›</span>
</button>
<button type="button" onClick="{{ goRef }}" style="display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 14px 18px; border-radius: 16px; border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-family: inherit; font-size: 16px; text-align: left; cursor: pointer;">
<span>Реферальная программа</span>
<span style="color: var(--ink-3);">›</span>
</button>
<a href="MassSupport.dc.html" style="display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 14px 18px; border-radius: 16px; border: 1px solid var(--border); background: var(--surface); color: var(--ink); font-size: 16px;">
<span>Поддержка</span>
<span style="color: var(--ink-3);">›</span>
</a>
<div style="display: grid; gap: 12px; padding: 14px 18px; border-radius: 16px; border: 1px solid var(--border); background: var(--surface);">
<div style="display: flex; align-items: center; justify-content: space-between; gap: 12px;">
<div style="font-size: 15px;">Тема</div>
<div style="display: flex; padding: 3px; border-radius: 11px; border: 1px solid var(--border); flex: none;">
<button type="button" onClick="{{ setLight }}" title="Светлая тема" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 34px; border: 0; border-radius: 8px; background: {{ lightBg }}; color: var(--ink); cursor: pointer;">
<span style="position: relative; width: 16px; height: 16px; display: block;">
<span style="position: absolute; left: 4px; top: 4px; width: 8px; height: 8px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 0; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; opacity: 0.45; display: block;"></span>
</span>
</button>
<button type="button" onClick="{{ setDark }}" title="Тёмная тема" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 34px; border: 0; border-radius: 8px; background: {{ darkBg }}; color: var(--ink); cursor: pointer;">
<span style="width: 16px; height: 16px; border-radius: 50%; box-shadow: inset -5px -2px 0 0 currentColor; display: block;"></span>
</button>
<button type="button" onClick="{{ setSystem }}" title="Как в системе" style="display: flex; align-items: center; justify-content: center; width: 40px; height: 34px; border: 0; border-radius: 8px; background: {{ systemBg }}; color: var(--ink); cursor: pointer;">
<span style="width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; background: linear-gradient(90deg, currentColor 50%, transparent 50%); display: block;"></span>
</button>
</div>
</div>
<div style="display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
<div style="font-size: 15px;">Язык</div>
<div style="display: flex; padding: 3px; border-radius: 11px; border: 1px solid var(--border); flex: none;">
<button type="button" onClick="{{ setRu }}" style="height: 34px; padding: 0 16px; border: 0; border-radius: 8px; background: {{ ruBg }}; color: {{ ruInk }}; font-family: inherit; font-size: 14px; cursor: pointer;">RU</button>
<button type="button" onClick="{{ setEn }}" style="height: 34px; padding: 0 16px; border: 0; border-radius: 8px; background: {{ enBg }}; color: {{ enInk }}; font-family: inherit; font-size: 14px; cursor: pointer;">EN</button>
</div>
</div>
</div>
<button type="button" onClick="{{ signOut }}" style="justify-self: start; min-height: 48px; padding: 0 16px; border-radius: 12px; border: 1px solid var(--border); background: transparent; color: var(--ink-2); font-family: inherit; font-size: 15px; cursor: pointer;">Выйти · anna@example.com</button>
</div>
</main>
</div>
<div hidden="{{ pillOff }}" style="position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 50; display: flex; gap: 4px; padding: 6px; border-radius: 999px; background: color-mix(in oklab, var(--surface) 62%, transparent); backdrop-filter: blur(24px) saturate(1.8); -webkit-backdrop-filter: blur(24px) saturate(1.8); border: 1px solid color-mix(in oklab, var(--ink) 8%, transparent); box-shadow: 0 10px 30px -10px color-mix(in oklab, var(--ink) 40%, transparent);">
<button type="button" onClick="{{ goHome }}" style="display: grid; justify-items: center; gap: 4px; min-width: 76px; min-height: 52px; padding: 8px 12px; border: 0; border-radius: 999px; background: {{ tabHomeBg }}; color: {{ tabHomeInk }}; font-family: inherit; font-size: 11px; cursor: pointer;">
<span style="position: relative; width: 20px; height: 20px; display: block;">
<span style="position: absolute; left: 0; top: 0; width: 9px; height: 9px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; right: 0; top: 0; width: 9px; height: 9px; border-radius: 2px; background: currentColor; opacity: 0.45; display: block;"></span>
<span style="position: absolute; left: 0; bottom: 0; width: 9px; height: 9px; border-radius: 2px; background: currentColor; opacity: 0.45; display: block;"></span>
<span style="position: absolute; right: 0; bottom: 0; width: 9px; height: 9px; border-radius: 2px; background: currentColor; display: block;"></span>
</span>
Главная
</button>
<button type="button" onClick="{{ goKeys }}" style="display: grid; justify-items: center; gap: 4px; min-width: 76px; min-height: 52px; padding: 8px 12px; border: 0; border-radius: 999px; background: {{ tabKeysBg }}; color: {{ tabKeysInk }}; font-family: inherit; font-size: 11px; cursor: pointer;">
<span style="position: relative; width: 20px; height: 20px; display: block;">
<span style="position: absolute; left: 0; top: 2px; width: 20px; height: 4px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 9px; width: 20px; height: 4px; border-radius: 2px; background: currentColor; opacity: 0.6; display: block;"></span>
<span style="position: absolute; left: 0; top: 16px; width: 20px; height: 4px; border-radius: 2px; background: currentColor; opacity: 0.3; display: block;"></span>
</span>
Подписка
</button>
<button type="button" onClick="{{ goBuy }}" style="display: grid; justify-items: center; gap: 4px; min-width: 76px; min-height: 52px; padding: 8px 12px; border: 0; border-radius: 999px; background: {{ tabBuyBg }}; color: {{ tabBuyInk }}; font-family: inherit; font-size: 11px; cursor: pointer;">
<span style="position: relative; width: 20px; height: 20px; display: block;">
<span style="position: absolute; left: 8px; top: 0; width: 4px; height: 20px; border-radius: 2px; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 0; top: 8px; width: 20px; height: 4px; border-radius: 2px; background: currentColor; display: block;"></span>
</span>
Купить
</button>
<button type="button" onClick="{{ goMore }}" style="display: grid; justify-items: center; gap: 4px; min-width: 76px; min-height: 52px; padding: 8px 12px; border: 0; border-radius: 999px; background: {{ tabMoreBg }}; color: {{ tabMoreInk }}; font-family: inherit; font-size: 11px; cursor: pointer;">
<span style="position: relative; width: 20px; height: 20px; display: block;">
<span style="position: absolute; left: 0; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 8px; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 16px; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: currentColor; display: block;"></span>
</span>
Ещё
</button>
</div>
<div hidden="{{ qrOff }}" onClick="{{ closeQr }}" style="position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 24px; background: color-mix(in oklab, var(--ink) 45%, transparent); backdrop-filter: blur(6px);">
<div style="display: grid; gap: 16px; justify-items: center; padding: 28px; border-radius: 22px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 16px; font-weight: 500;">{{ qrTitle }}</div>
{{ qrImage }}
<div style="max-width: 260px; text-align: center; font-size: 13px; line-height: 1.5; color: var(--ink-3);">Откройте приложение на телефоне и наведите камеру на код.</div>
</div>
</div>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props="{&quot;defaultTheme&quot;:{&quot;editor&quot;:&quot;enum&quot;,&quot;options&quot;:[&quot;light&quot;,&quot;dark&quot;,&quot;system&quot;],&quot;default&quot;:&quot;light&quot;,&quot;tsType&quot;:&quot;'light' | 'dark' | 'system'&quot;,&quot;section&quot;:&quot;Тема&quot;}}">
class Component extends DCLogic {
state = { theme: null, sysDark: false, view: "home", key: 0, faq: 0, loc: 0, lead: false, leadSent: false, qr: null, copied: false, signedIn: true, otp: false, lang: "ru", narrow: false, refCopied: false, topup: false, sum: 1, method: 0, topupSent: false };
data() {
const base = { setup: "4 900 ₽", month: "2 499 ₽" };
const rare = { setup: "6 900 ₽", month: "3 499 ₽" };
const far = { setup: "9 900 ₽", month: "4 999 ₽" };
const L = (country, city, code, lng, lat, ready, tier) => ({ country, city, code, lng, lat, ready, setup: tier.setup, month: tier.month, rare: tier !== base });
return [
L("Нидерланды", "Амстердам", "nl", 4.9, 52.37, true, base),
L("Германия", "Франкфурт", "de", 8.68, 50.11, true, base),
L("США", "Нью-Йорк", "us", -74.01, 40.71, true, base),
L("Великобритания", "Лондон", "gb", -0.13, 51.51, true, base),
L("Франция", "Париж", "fr", 2.35, 48.86, true, base),
L("Финляндия", "Хельсинки", "fi", 24.94, 60.17, true, base),
L("Швеция", "Стокгольм", "se", 18.07, 59.33, true, base),
L("Норвегия", "Осло", "no", 10.75, 59.91, false, base),
L("Дания", "Копенгаген", "dk", 12.57, 55.68, false, base),
L("Швейцария", "Цюрих", "ch", 8.54, 47.37, true, rare),
L("Австрия", "Вена", "at", 16.37, 48.21, true, base),
L("Испания", "Мадрид", "es", -3.7, 40.42, true, base),
L("Италия", "Милан", "it", 9.19, 45.46, true, base),
L("Польша", "Варшава", "pl", 21.01, 52.23, true, base),
L("Чехия", "Прага", "cz", 14.44, 50.08, true, base),
L("Румыния", "Бухарест", "ro", 26.1, 44.43, false, base),
L("Литва", "Вильнюс", "lt", 25.28, 54.69, true, base),
L("Латвия", "Рига", "lv", 24.11, 56.95, true, base),
L("Эстония", "Таллин", "ee", 24.75, 59.44, false, base),
L("Турция", "Стамбул", "tr", 28.98, 41.01, true, base),
L("Казахстан", "Алматы", "kz", 76.89, 43.24, false, base),
L("Армения", "Ереван", "am", 44.51, 40.18, false, base),
L("Грузия", "Тбилиси", "ge", 44.8, 41.72, false, base),
L("ОАЭ", "Дубай", "ae", 55.27, 25.2, true, rare),
L("Сингапур", "Сингапур", "sg", 103.82, 1.35, true, rare),
L("Япония", "Токио", "jp", 139.69, 35.69, true, rare),
L("Южная Корея", "Сеул", "kr", 126.98, 37.57, false, rare),
L("Канада", "Торонто", "ca", -79.38, 43.65, true, base),
L("Австралия", "Сидней", "au", 151.21, -33.87, false, far),
L("Бразилия", "Сан-Паулу", "br", -46.63, -23.55, false, far)
];
}
flagSpecs() {
return {
nl: { rows: ["#AE1C28", "#FFFFFF", "#21468B"] },
de: { rows: ["#000000", "#DD0000", "#FFCE00"] },
us: { rows: ["#B22234", "#FFFFFF", "#B22234", "#FFFFFF", "#B22234", "#FFFFFF"], marks: [{ l: 0, t: 0, w: 22, h: 17, bg: "#3C3B6E" }] },
gb: { bg: "#012169", marks: [{ l: 17, t: 0, w: 12, h: 32, bg: "#FFFFFF" }, { l: 0, t: 10, w: 46, h: 12, bg: "#FFFFFF" }, { l: 20, t: 0, w: 6, h: 32, bg: "#C8102E" }, { l: 0, t: 13, w: 46, h: 6, bg: "#C8102E" }] },
fr: { cols: ["#002395", "#FFFFFF", "#ED2939"] },
fi: { bg: "#FFFFFF", marks: [{ l: 13, t: 0, w: 8, h: 32, bg: "#003580" }, { l: 0, t: 12, w: 46, h: 8, bg: "#003580" }] },
se: { bg: "#006AA7", marks: [{ l: 13, t: 0, w: 6, h: 32, bg: "#FECC00" }, { l: 0, t: 13, w: 46, h: 6, bg: "#FECC00" }] },
no: { bg: "#BA0C2F", marks: [{ l: 12, t: 0, w: 10, h: 32, bg: "#FFFFFF" }, { l: 0, t: 11, w: 46, h: 10, bg: "#FFFFFF" }, { l: 15, t: 0, w: 4, h: 32, bg: "#00205B" }, { l: 0, t: 14, w: 46, h: 4, bg: "#00205B" }] },
dk: { bg: "#C8102E", marks: [{ l: 13, t: 0, w: 6, h: 32, bg: "#FFFFFF" }, { l: 0, t: 13, w: 46, h: 6, bg: "#FFFFFF" }] },
ch: { bg: "#D52B1E", marks: [{ l: 20, t: 8, w: 6, h: 16, bg: "#FFFFFF" }, { l: 15, t: 13, w: 16, h: 6, bg: "#FFFFFF" }] },
at: { rows: ["#ED2939", "#FFFFFF", "#ED2939"] },
es: { rows: ["#AA151B", "#F1BF00", "#AA151B"], sizes: "1fr 2fr 1fr" },
it: { cols: ["#008C45", "#F4F5F0", "#CD212A"] },
pl: { rows: ["#FFFFFF", "#DC143C"] },
cz: { rows: ["#FFFFFF", "#D7141A"], marks: [{ l: 0, t: 0, w: 18, h: 32, bg: "#11457E", clip: "polygon(0 0, 100% 50%, 0 100%)" }] },
ro: { cols: ["#002B7F", "#FCD116", "#CE1126"] },
lt: { rows: ["#FDB913", "#006A44", "#C1272D"] },
lv: { rows: ["#9E3039", "#FFFFFF", "#9E3039"], sizes: "2fr 1fr 2fr" },
ee: { rows: ["#0072CE", "#000000", "#FFFFFF"] },
tr: { bg: "#E30A17", marks: [{ l: 11, t: 8, w: 16, h: 16, r: "50%", bg: "#FFFFFF" }, { l: 16, t: 8, w: 16, h: 16, r: "50%", bg: "#E30A17" }] },
kz: { bg: "#00AFCA", marks: [{ l: 16, t: 8, w: 15, h: 15, r: "50%", bg: "#FEC50C" }] },
am: { rows: ["#D90012", "#0033A0", "#F2A800"] },
ge: { bg: "#FFFFFF", marks: [{ l: 20, t: 0, w: 6, h: 32, bg: "#FF0000" }, { l: 0, t: 13, w: 46, h: 6, bg: "#FF0000" }] },
ae: { rows: ["#00732F", "#FFFFFF", "#000000"], marks: [{ l: 0, t: 0, w: 11, h: 32, bg: "#FF0000" }] },
sg: { rows: ["#EF3340", "#FFFFFF"], marks: [{ l: 5, t: 3, w: 11, h: 11, r: "50%", bg: "#FFFFFF" }, { l: 9, t: 3, w: 11, h: 11, r: "50%", bg: "#EF3340" }] },
jp: { bg: "#FFFFFF", marks: [{ l: 16, t: 9, w: 14, h: 14, r: "50%", bg: "#BC002D" }] },
kr: { bg: "#FFFFFF", marks: [{ l: 16, t: 9, w: 14, h: 14, r: "50%", bg: "#CD2E3A" }, { l: 16, t: 9, w: 14, h: 14, r: "50%", bg: "#0047A0", clip: "polygon(0 50%, 100% 50%, 100% 100%, 0 100%)" }] },
ca: { cols: ["#D80621", "#FFFFFF", "#D80621"], sizes: "1fr 2fr 1fr", marks: [{ l: 20, t: 9, w: 7, h: 13, bg: "#D80621", clip: "polygon(50% 0, 100% 100%, 0 100%)" }] },
au: { bg: "#00247D", marks: [{ l: 9, t: 0, w: 4, h: 16, bg: "#FFFFFF" }, { l: 0, t: 6, w: 22, h: 4, bg: "#FFFFFF" }, { l: 30, t: 19, w: 7, h: 7, r: "50%", bg: "#FFFFFF" }] },
br: { bg: "#009739", marks: [{ l: 9, t: 4, w: 28, h: 24, bg: "#FEDD00", clip: "polygon(50% 0, 100% 50%, 50% 100%, 0 50%)" }, { l: 18, t: 11, w: 10, h: 10, r: "50%", bg: "#012169" }] }
};
}
flag(code) {
const h = React.createElement;
const spec = this.flagSpecs()[code] || {};
const style = {
width: "46px", height: "32px", borderRadius: "6px", overflow: "hidden",
display: "grid", border: "1px solid var(--border)", position: "relative", flex: "none"
};
let bands = [];
if (spec.rows) {
bands = spec.rows;
style.gridTemplateRows = spec.sizes || "repeat(" + bands.length + ", 1fr)";
} else if (spec.cols) {
bands = spec.cols;
style.gridAutoFlow = "column";
style.gridTemplateColumns = spec.sizes || "repeat(" + bands.length + ", 1fr)";
} else {
style.background = spec.bg || "var(--surface-2)";
}
const kids = bands.map((c, i) => h("span", { key: "b" + i, style: { background: c, display: "block" } }));
(spec.marks || []).forEach((m, i) => kids.push(h("span", {
key: "m" + i,
style: {
position: "absolute", left: m.l + "px", top: m.t + "px", width: m.w + "px", height: m.h + "px",
borderRadius: m.r || 0, background: m.bg, clipPath: m.clip || "none", display: "block"
}
})));
return h("span", { style: style }, kids);
}
componentDidMount() {
const mq = window.matchMedia("(prefers-color-scheme: dark)");
this.mq = mq;
this.onSys = () => this.setState({ sysDark: mq.matches });
mq.addEventListener("change", this.onSys);
this.onResize = () => {
const n = window.innerWidth < 900;
if (n !== this.state.narrow) this.setState({ narrow: n, view: this.state.view === "more" && !n ? "home" : this.state.view });
if (!n && this.state.view === "more") this.setState({ view: "home" });
};
window.addEventListener("resize", this.onResize);
this.onResize();
let saved = null;
try { saved = localStorage.getItem("veilix.theme"); } catch (e) {}
let savedLang = null;
try { savedLang = localStorage.getItem("veilix.lang"); } catch (e) {}
this.setState({ sysDark: mq.matches, theme: saved || this.props.defaultTheme || "light", lang: savedLang || "ru" }, () => { this.apply(); this.applyLang(); });
}
applyLang() {
const lang = this.state.lang || "ru";
if (window.VEILIX_APPLY_LANG) window.VEILIX_APPLY_LANG(document.body, lang);
else setTimeout(() => this.applyLang(), 150);
}
setLang(l) {
try { localStorage.setItem("veilix.lang", l); } catch (e) {}
this.setState({ lang: l }, () => this.applyLang());
}
componentWillUnmount() {
if (this.mq) this.mq.removeEventListener("change", this.onSys);
if (this.onResize) window.removeEventListener("resize", this.onResize);
}
componentDidUpdate() { this.apply(); this.applyLang(); }
apply() {
const theme = this.state.theme || this.props.defaultTheme || "light";
const dark = theme === "dark" || (theme === "system" && this.state.sysDark);
document.documentElement.setAttribute("data-veilix-theme", dark ? "dark" : "light");
}
setTheme(t) {
try { localStorage.setItem("veilix.theme", t); } catch (e) {}
this.setState({ theme: t }, () => this.apply());
}
qrImage(seed) {
const n = 21;
let h = 0;
for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) >>> 0;
const cells = [];
const finder = (r, c) => (r < 7 && c < 7) || (r < 7 && c >= n - 7) || (r >= n - 7 && c < 7);
for (let r = 0; r < n; r++) {
for (let c = 0; c < n; c++) {
let on;
if (finder(r, c)) {
const rr = r < 7 ? r : n - 1 - r;
const cc = c < 7 ? c : n - 1 - c;
const d = Math.max(Math.abs(rr - 3), Math.abs(cc - 3));
on = d !== 2;
} else {
h = (h * 1103515245 + 12345) >>> 0;
on = ((h >>> 16) & 1) === 1;
}
cells.push(React.createElement("span", {
key: r + "-" + c,
style: { background: on ? "var(--ink)" : "transparent", display: "block" }
}));
}
}
return React.createElement("div", {
style: {
display: "grid",
gridTemplateColumns: "repeat(" + n + ", 1fr)",
width: "220px",
height: "220px",
padding: "12px",
borderRadius: "14px",
background: "var(--bg)",
border: "1px solid var(--border)"
}
}, cells);
}
renderVals() {
const s = this.state;
const sel = "var(--sel)";
const theme = s.theme || this.props.defaultTheme || "light";
const keyData = [
{ title: "Нидерланды · Амстердам", ip: "текущая локация", until: s.lang === "en" ? "14 October 2026" : "14 октября 2026", badge: "Активна", warn: false, devices: "3 из 5 устройств", payment: "Карта ···· 4242", card: "···· 4242", left: "Продлится автоматически через 31 день", xray: "vless://8f2a…@nl1.veilixvpn.net:443?type=xhttp#VeilixVPN-NL" },
{ title: "США · Нью-Йорк", ip: "запасная локация", until: s.lang === "en" ? "14 October 2026" : "14 октября 2026", badge: "Готова", warn: false, devices: "1 из 5 устройств", payment: "Карта ···· 4242", card: "···· 4242", left: "Переключиться можно в любой момент", xray: "vless://c41d…@us1.veilixvpn.net:443?type=xhttp#VeilixVPN-US" }
];
const cur = keyData[s.key];
const mk = (i) => ({
title: keyData[i].title,
ip: keyData[i].ip,
until: keyData[i].until,
untilLine: (s.lang === "en" ? "until " : "до ") + keyData[i].until,
badge: keyData[i].badge,
devices: keyData[i].devices,
payment: keyData[i].payment,
badgeBg: keyData[i].warn ? "color-mix(in oklab, var(--warn) 18%, transparent)" : sel,
badgeInk: keyData[i].warn ? "var(--warn)" : "var(--accent)",
open: () => this.setState({ view: "key", key: i })
});
const faqData = [
["Как подключить новое устройство?", "Откройте подключение, скачайте любую свободную конфигурацию XRAY или отсканируйте её QR-код. Каждая конфигурация рассчитана на одно устройство."],
["Что делать, если подключение перестало работать?", "Обновите конфигурацию в кабинете или смените локацию — это занимает пару секунд. Если не помогло, напишите в поддержку, ответим в течение часа."],
["Как отменить продление?", "В разделе оплаты нажмите «Изменить карту» и отвяжите её. Подписка доработает оплаченный период."]
];
const locData = [
["Нидерланды", "Амстердам", true],
["Германия", "Франкфурт", true],
["США", "Нью-Йорк", true],
["Финляндия", "Хельсинки", false],
["Турция", "Стамбул", false],
["Япония", "Токио", false]
];
const cfgNames = [
["Ноутбук", "подключено"],
["Телефон", "подключено"],
["Планшет", "подключено"],
["Рабочий ноутбук", "не занят"],
["Свободный слот", "не занят"]
];
return {
appOff: s.signedIn,
loginOff: !s.signedIn,
otpSent: s.otp,
otpNotSent: !s.otp,
sendOtp: () => this.setState({ otp: true }),
signIn: () => this.setState({ signedIn: true, otp: false, view: "home" }),
backToEmail: () => this.setState({ otp: false }),
signOut: () => this.setState({ signedIn: false, otp: false }),
goHome: () => this.setState({ view: "home" }),
goKeys: () => this.setState({ view: "keys" }),
goBuy: () => this.setState({ view: "buy" }),
goMore: () => this.setState({ view: "more" }),
goBilling: () => this.setState({ view: "billing" }),
billingOff: s.view !== "billing",
billingBg: s.view === "billing" ? sel : "transparent",
billingInk: s.view === "billing" ? "var(--accent)" : "var(--ink-2)",
openTopup: () => this.setState({ topup: true }),
closeTopup: () => this.setState({ topup: false }),
topupOff: !s.topup,
sums: ["700 ₽", "2 100 ₽", "6 990 ₽", "Своя сумма"].map((label, i) => ({
label: label,
bg: s.sum === i ? sel : "transparent",
border: s.sum === i ? "var(--accent)" : "var(--border)",
pick: () => this.setState({ sum: i })
})),
methods: ["Карта ···· 4242", "СБП", "Криптовалюта"].map((label, i) => ({
label: label,
bg: s.method === i ? sel : "transparent",
border: s.method === i ? "var(--accent)" : "var(--border)",
pick: () => this.setState({ method: i })
})),
cryptoOff: s.method !== 2,
sendTopup: () => this.setState({ topupSent: true }),
topupButton: s.topupSent ? "Счёт выставлен" : "Пополнить",
payments: [
{ date: "14 сентября", title: "Подписка на месяц", method: "Карта ···· 4242", status: "Оплачено", amount: "−699 ₽", ink: "var(--ink)" },
{ date: "6 сентября", title: "Пополнение баланса", method: "USDT (TRC-20)", status: "Зачислено", amount: "+2 100 ₽", ink: "var(--accent)" },
{ date: "14 августа", title: "Подписка на месяц", method: "С баланса", status: "Оплачено", amount: "−699 ₽", ink: "var(--ink)" },
{ date: "14 июля", title: "Подписка на месяц", method: "Карта ···· 4242", status: "Оплачено", amount: "−699 ₽", ink: "var(--ink)" },
{ date: "2 июля", title: "Реферальный бонус", method: "Месяц в подарок", status: "Начислено", amount: "+699 ₽", ink: "var(--accent)" }
],
goRef: () => this.setState({ view: "ref" }),
refOff: s.view !== "ref",
refBg: s.view === "ref" ? sel : "transparent",
refInk: s.view === "ref" ? "var(--accent)" : "var(--ink-2)",
setRu: () => this.setLang("ru"),
setEn: () => this.setLang("en"),
ruBg: s.lang === "en" ? "transparent" : sel,
enBg: s.lang === "en" ? sel : "transparent",
ruInk: s.lang === "en" ? "var(--ink-3)" : "var(--ink)",
enInk: s.lang === "en" ? "var(--ink)" : "var(--ink-3)",
homeOff: s.view !== "home",
keysOff: s.view !== "keys",
keyOff: s.view !== "key",
buyOff: s.view !== "buy",
moreOff: s.view !== "more",
shellCols: s.narrow ? "minmax(0, 1fr)" : "248px minmax(0, 1fr)",
mainPad: s.narrow ? "20px 16px 110px" : "36px 40px 64px",
asideOff: s.narrow,
topbarOff: !s.narrow,
pillOff: !s.narrow,
tabHomeBg: s.view === "home" ? sel : "transparent",
tabKeysBg: (s.view === "keys" || s.view === "key") ? sel : "transparent",
tabBuyBg: s.view === "buy" ? sel : "transparent",
tabMoreBg: s.view === "more" ? sel : "transparent",
tabHomeInk: s.view === "home" ? "var(--accent)" : "var(--ink-2)",
tabKeysInk: (s.view === "keys" || s.view === "key") ? "var(--accent)" : "var(--ink-2)",
tabBuyInk: s.view === "buy" ? "var(--accent)" : "var(--ink-2)",
tabMoreInk: s.view === "more" ? "var(--accent)" : "var(--ink-2)",
homeBg: s.view === "home" ? sel : "transparent",
keysBg: (s.view === "keys" || s.view === "key") ? sel : "transparent",
buyBg: s.view === "buy" ? sel : "transparent",
homeInk: s.view === "home" ? "var(--accent)" : "var(--ink-2)",
keysInk: (s.view === "keys" || s.view === "key") ? "var(--accent)" : "var(--ink-2)",
buyInk: s.view === "buy" ? "var(--accent)" : "var(--ink-2)",
keys: [mk(0), mk(1)],
allKeys: [mk(0), mk(1)],
cur: {
title: cur.title,
ip: cur.ip,
until: cur.until,
card: cur.card,
devices: cur.devices,
left: cur.left,
leftInk: cur.warn ? "var(--warn)" : "var(--ink-2)",
xray: cur.xray
},
configs: cfgNames.map((c, i) => ({
name: c[0],
state: c[1],
showQr: () => this.setState({ qr: { title: "XRAY · " + c[0], seed: cur.ip + c[0] } })
})),
refStats: s.lang === "en" ? "Invited: 3 · Months earned: 2" : "Приглашено: 3 · Месяцев начислено: 2",
copyRef: () => this.setState({ refCopied: true }),
refLabel: s.refCopied ? "Ссылка скопирована" : "Копировать ссылку",
copyXray: () => this.setState({ copied: true }),
copyLabel: s.copied ? "Скопировано" : "Копировать",
showXrayQr: () => this.setState({ qr: { title: "XRAY · Happ", seed: cur.xray } }),
qrOff: !s.qr,
qrTitle: s.qr ? s.qr.title : "",
qrImage: s.qr ? this.qrImage(s.qr.seed) : null,
closeQr: () => this.setState({ qr: null }),
faq: faqData.map((row, i) => ({
q: row[0],
a: row[1],
off: s.faq !== i,
rot: s.faq === i ? "rotate(-135deg) translateY(2px)" : "rotate(45deg) translateY(-2px)",
toggle: () => this.setState(st => ({ faq: st.faq === i ? -1 : i }))
})),
locations: this.data().map((d, i) => ({
country: d.country,
city: d.city,
flag: this.flag(d.code),
status: d.ready ? "Доступно в подписке" : "Скоро",
statusInk: d.ready ? "var(--accent)" : "var(--ink-3)",
bg: s.loc === i ? sel : "var(--surface)",
border: s.loc === i ? "var(--accent)" : "var(--border)",
dot: s.loc === i ? "var(--accent)" : "transparent",
dotOff: s.loc === i,
setup: d.setup,
month: d.month,
buyOff: s.loc !== i,
pick: () => this.setState({ loc: i })
})),
openLead: () => this.setState({ lead: true }),
sendLead: () => this.setState({ leadSent: true }),
leadOpen: s.lead,
leadClosed: !s.lead,
leadButton: s.leadSent ? "Заявка отправлена" : "Отправить",
pickedTitle: locData[s.loc][0] + " · " + locData[s.loc][1],
pickedHint: "Локация доступна сразу, переключение бесплатное",
toggleLang: () => this.setLang(s.lang === "ru" ? "en" : "ru"),
langTitle: s.lang === "ru" ? "Язык: русский" : "Язык: английский",
langLabel: s.lang === "ru" ? "RU" : "EN",
setLight: () => this.setTheme("light"),
setDark: () => this.setTheme("dark"),
setSystem: () => this.setTheme("system"),
lightBg: theme === "light" ? sel : "transparent",
darkBg: theme === "dark" ? sel : "transparent",
systemBg: theme === "system" ? sel : "transparent",
lightInk: theme === "light" ? "var(--ink)" : "var(--ink-3)",
darkInk: theme === "dark" ? "var(--ink)" : "var(--ink-3)",
systemInk: theme === "system" ? "var(--ink)" : "var(--ink-3)"
};
}
}
</script>
</body>
</html>