Files
2026-10-21 03:30:38 +02:00

282 lines
21 KiB
HTML
Raw Permalink 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.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% 0.005 296);
--surface: oklch(100% 0 0);
--surface-2: oklch(97.5% 0.01 296);
--ink: oklch(24% 0.04 296);
--ink-2: oklch(45% 0.03 296);
--ink-3: oklch(60% 0.025 296);
--border: oklch(92% 0.014 296);
--accent: oklch(45% 0.17 296);
--accent-hover: oklch(38% 0.17 296);
--accent-soft: oklch(95.5% 0.028 296);
--on-accent: oklch(99% 0.01 296);
--glow-1: oklch(86% 0.1 296);
--glow-2: oklch(89% 0.09 266);
--glow-3: oklch(91% 0.08 332);
--veil: oklch(100% 0 0 / 0.55);
--shadow: 0 1px 2px oklch(24% 0.04 296 / 0.05), 0 12px 32px -12px oklch(24% 0.04 296 / 0.14);
}
:root[data-veilix-theme="dark"]{
--bg: oklch(17% 0.022 296);
--surface: oklch(21% 0.026 296);
--surface-2: oklch(24% 0.03 296);
--ink: oklch(96% 0.01 296);
--ink-2: oklch(79% 0.02 296);
--ink-3: oklch(63% 0.025 296);
--border: oklch(31% 0.032 296);
--accent: oklch(74% 0.15 296);
--accent-hover: oklch(80% 0.13 296);
--accent-soft: oklch(27% 0.05 296);
--on-accent: oklch(17% 0.03 296);
--glow-1: oklch(45% 0.16 296);
--glow-2: oklch(40% 0.14 266);
--glow-3: oklch(42% 0.13 332);
--veil: oklch(100% 0 0 / 0.07);
--shadow: 0 1px 2px oklch(10% 0.02 296 / 0.4), 0 16px 40px -16px oklch(8% 0.02 296 / 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, textarea::placeholder{ color: var(--ink-3); }
</style>
</helmet>
<template id="__bundler_thumbnail" data-bg-color="#efeaf8">
<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="#5b32c9" />
<rect x="570" y="360" width="150" height="150" rx="48" fill="#ffffff" fill-opacity="0.62" stroke="#5b32c9" stroke-width="6" />
</svg>
</template>
<div style="background: var(--bg); color: var(--ink); font-family: 'Commissioner', system-ui, sans-serif; font-weight: 400; letter-spacing: -0.01em; min-height: 100vh;">
<header style="border-bottom: 1px solid var(--border); background: var(--bg);">
<div style="max-width: 1080px; margin: 0 auto; padding: 16px 24px; display: flex; flex-wrap: wrap; align-items: center; gap: 14px 24px;">
<a href="Main.dc.html" style="display: flex; align-items: center; gap: 10px; color: var(--ink); flex: none;">
<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>
</a>
<div style="margin-left: auto; display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--ink-3);">
<button type="button" onClick="{{ toggleLang }}" title="{{ langTitle }}" style="display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--border); background: transparent; color: var(--ink-2); font-family: inherit; font-size: 14px; cursor: pointer;" style-hover="color: var(--ink); border-color: var(--ink-3);">
<span style="position: relative; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; display: block; flex: none;">
<span style="position: absolute; left: -1.5px; top: 5.75px; width: 16px; height: 1.5px; background: currentColor; display: block;"></span>
<span style="position: absolute; left: 3.25px; top: -1.5px; width: 8px; height: 16px; border-radius: 50%; border: 1.5px solid currentColor; display: block;"></span>
</span>
<span style="font-variant-numeric: tabular-nums;">{{ langLabel }}</span>
</button>
<span>Оформление заказа</span>
<a href="Price.dc.html" style="color: var(--ink-2);" style-hover="color: var(--ink);">Отменить</a>
</div>
</div>
</header>
<main style="max-width: 1080px; margin: 0 auto; padding: 40px 24px 80px; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 32px; align-items: start;">
<div style="display: grid; gap: 16px;">
<div style="border: 1px solid {{ step1Border }}; border-radius: 20px; background: var(--surface); box-shadow: var(--shadow); overflow: hidden;">
<div style="display: flex; align-items: center; gap: 14px; padding: 22px 24px;">
<span style="display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: {{ step1Dot }}; color: {{ step1DotInk }}; font-size: 13px; font-weight: 500; flex: none;">1</span>
<span style="flex: 1; font-size: 18px; font-weight: 500; letter-spacing: -0.02em;">Почта</span>
<span hidden="{{ emailNotDone }}" style="font-size: 14px; color: var(--ink-2);">{{ emailValue }}</span>
<button type="button" hidden="{{ emailNotDone }}" onClick="{{ editEmail }}" style="border: 0; background: transparent; color: var(--accent); font-family: inherit; font-size: 14px; cursor: pointer; padding: 0;">Изменить</button>
</div>
<div hidden="{{ step1Off }}" style="padding: 0 24px 24px;">
<p style="margin: 0 0 16px; max-width: 46em; font-size: 15px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">Введите почту — пришлём одноразовый код. Отдельной регистрации нет: если вы у нас уже были, попадёте в свой кабинет, если нет — он создастся сам.</p>
<div hidden="{{ codeSent }}" style="display: flex; flex-wrap: wrap; gap: 10px;">
<input type="email" value="{{ emailValue }}" onInput="{{ onEmail }}" placeholder="you@example.com" style="flex: 1; min-width: 220px; 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;" />
<button type="button" onClick="{{ sendCode }}" style="height: 50px; 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 hidden="{{ codeNotSent }}" style="display: grid; gap: 12px;">
<div style="font-size: 14px; color: var(--ink-2);">{{ codeLine }}</div>
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<input type="text" inputmode="numeric" placeholder="6 цифр" style="flex: 1; min-width: 180px; 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;" />
<button type="button" onClick="{{ confirmCode }}" style="height: 50px; 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>
<button type="button" onClick="{{ editEmail }}" style="justify-self: start; border: 0; background: transparent; color: var(--ink-3); font-family: inherit; font-size: 14px; cursor: pointer; padding: 0;">Другая почта</button>
</div>
</div>
</div>
<div style="border: 1px solid {{ step2Border }}; border-radius: 20px; background: var(--surface); box-shadow: var(--shadow); overflow: hidden;">
<div style="display: flex; align-items: center; gap: 14px; padding: 22px 24px;">
<span style="display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: {{ step2Dot }}; color: {{ step2DotInk }}; font-size: 13px; font-weight: 500; flex: none;">2</span>
<span style="flex: 1; font-size: 18px; font-weight: 500; letter-spacing: -0.02em;">Оплата</span>
</div>
<div hidden="{{ step2Off }}" style="padding: 0 24px 24px; display: grid; gap: 16px;">
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
<button type="button" onClick="{{ payCard }}" style="flex: 1; min-width: 140px; padding: 14px 16px; border-radius: 14px; border: 1px solid {{ cardBorder }}; background: {{ cardBg }}; color: var(--ink); font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;">Карта</button>
<button type="button" onClick="{{ payMir }}" style="flex: 1; min-width: 140px; padding: 14px 16px; border-radius: 14px; border: 1px solid {{ mirBorder }}; background: {{ mirBg }}; color: var(--ink); font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;">Карта МИР</button>
<button type="button" onClick="{{ payCrypto }}" style="flex: 1; min-width: 140px; padding: 14px 16px; border-radius: 14px; border: 1px solid {{ cryptoBorder }}; background: {{ cryptoBg }}; color: var(--ink); font-family: inherit; font-size: 15px; text-align: left; cursor: pointer;">Криптовалюта</button>
</div>
<div hidden="{{ cryptoChosen }}" style="display: grid; gap: 10px;">
<input type="text" placeholder="Номер карты" 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%; font-variant-numeric: tabular-nums;" />
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<input type="text" placeholder="ММ / ГГ" style="flex: 1; min-width: 120px; 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; font-variant-numeric: tabular-nums;" />
<input type="text" placeholder="CVC" style="flex: 1; min-width: 120px; 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; font-variant-numeric: tabular-nums;" />
</div>
<div style="font-size: 13px; color: var(--ink-3); line-height: 1.5;">Карта сохранится для продления. Отменить или заменить её можно в кабинете в любой момент.</div>
</div>
<div hidden="{{ cardChosen }}" style="display: grid; gap: 10px; padding: 18px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--border);">
<div style="font-size: 15px;">USDT, BTC или ETH</div>
<div style="font-size: 14px; line-height: 1.55; color: var(--ink-2); font-weight: 300;">После нажатия покажем адрес и сумму. При оплате криптой продление не автоматическое — пришлём напоминание за три дня до конца месяца.</div>
</div>
<label style="display: flex; align-items: flex-start; gap: 10px; font-size: 14px; color: var(--ink-2); font-weight: 300; line-height: 1.5; cursor: pointer;">
<input type="checkbox" style="margin-top: 3px; width: 16px; height: 16px; accent-color: var(--accent);" />
<span>Согласен с условиями использования и политикой конфиденциальности</span>
</label>
</div>
</div>
</div>
<aside style="position: sticky; top: 24px; display: grid; gap: 16px;">
<div style="padding: clamp(20px, 4.6vw, 26px); border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);">
<div style="font-size: 13px; color: var(--ink-3); margin-bottom: 16px;">Ваш заказ</div>
<div style="display: grid; gap: 6px; margin-bottom: 20px;">
<div style="font-size: 20px; font-weight: 600; letter-spacing: -0.025em;">Персональный VPN</div>
<div style="font-size: 15px; color: var(--ink-2);">Нидерланды · Амстердам</div>
<div style="display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--accent);">
<span style="width: 6px; height: 6px; border-radius: 50%; background: var(--accent); display: block;"></span>
Сервер свободен, доступ сразу после оплаты
</div>
</div>
<div style="display: grid; gap: 10px; padding-top: 18px; border-top: 1px solid var(--border); font-size: 15px;">
<div style="display: flex; justify-content: space-between; gap: 12px; color: var(--ink-2);"><span>Первый месяц</span><span style="font-variant-numeric: tabular-nums;">4 900 ₽</span></div>
<div style="display: flex; justify-content: space-between; gap: 12px; color: var(--ink-2);"><span>RU-адрес</span><span>включён</span></div>
<div style="display: flex; justify-content: space-between; gap: 12px; color: var(--ink-2);"><span>Устройств</span><span>до 5</span></div>
</div>
<div style="display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--border);">
<span style="font-size: 16px; font-weight: 500;">К оплате сегодня</span>
<span style="font-size: 26px; font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;">4 900 ₽</span>
</div>
<div style="margin-top: 8px; font-size: 13px; color: var(--ink-3);">{{ nextChargeLine }}</div>
<button type="button" onClick="{{ pay }}" disabled="{{ payDisabled }}" style="margin-top: 20px; width: 100%; height: 52px; border-radius: 14px; border: 0; background: {{ payBg }}; color: {{ payInk }}; font-family: inherit; font-size: 16px; font-weight: 500; cursor: {{ payCursor }};">{{ payLabel }}</button>
<div hidden="{{ paidOff }}" style="margin-top: 14px; padding: 14px; border-radius: 12px; background: var(--accent-soft); font-size: 14px; line-height: 1.5; color: var(--ink);">Оплачено. Ключ уже в кабинете — <a href="App.dc.html">открыть</a>.</div>
</div>
</aside>
</main>
</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, email: "", sent: false, authed: false, method: "card", paid: false, lang: "ru" };
componentDidMount() {
const mq = window.matchMedia("(prefers-color-scheme: dark)");
this.mq = mq;
this.onSys = () => this.setState({ sysDark: mq.matches });
mq.addEventListener("change", this.onSys);
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); }
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");
}
renderVals() {
const s = this.state;
const authed = s.authed;
const nd = new Date();
nd.setMonth(nd.getMonth() + 1);
const months = ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"];
const monthsEn = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const en = s.lang === "en";
const sel = "var(--accent-soft)";
return {
emailValue: s.email,
toggleLang: () => this.setLang(s.lang === "en" ? "ru" : "en"),
langLabel: s.lang === "en" ? "EN" : "RU",
langTitle: s.lang === "en" ? "Язык: английский" : "Язык: русский",
onEmail: (e) => this.setState({ email: e.target.value }),
sendCode: () => this.setState({ sent: true }),
confirmCode: () => this.setState({ authed: true }),
editEmail: () => this.setState({ sent: false, authed: false }),
codeSent: s.sent,
codeNotSent: !s.sent,
emailNotDone: !authed,
step1Off: authed,
step1Border: authed ? "var(--border)" : "var(--accent)",
step1Dot: authed ? "var(--accent)" : "var(--accent-soft)",
step1DotInk: authed ? "var(--on-accent)" : "var(--accent)",
step2Off: !authed,
step2Border: authed ? "var(--accent)" : "var(--border)",
step2Dot: authed ? "var(--accent-soft)" : "var(--surface-2)",
step2DotInk: authed ? "var(--accent)" : "var(--ink-3)",
payCard: () => this.setState({ method: "card" }),
payMir: () => this.setState({ method: "mir" }),
payCrypto: () => this.setState({ method: "crypto" }),
cardBg: s.method === "card" ? sel : "transparent",
mirBg: s.method === "mir" ? sel : "transparent",
cryptoBg: s.method === "crypto" ? sel : "transparent",
cardBorder: s.method === "card" ? "var(--accent)" : "var(--border)",
mirBorder: s.method === "mir" ? "var(--accent)" : "var(--border)",
cryptoBorder: s.method === "crypto" ? "var(--accent)" : "var(--border)",
cardChosen: s.method !== "crypto",
cryptoChosen: s.method === "crypto",
nextCharge: "первое списание " + nd.getDate() + " " + months[nd.getMonth()],
nextChargeLine: en
? "Then $24 per month, first charge on " + nd.getDate() + " " + monthsEn[nd.getMonth()]
: "Далее 2 499 ₽ в месяц, первое списание " + nd.getDate() + " " + months[nd.getMonth()],
codeLine: en
? "The code has been sent to " + s.email + ". It is valid for 10 minutes."
: "Код отправлен на " + s.email + ". Он действует 10 минут.",
pay: () => { if (authed) this.setState({ paid: true }); },
payDisabled: !authed,
payBg: authed ? "var(--accent)" : "var(--surface-2)",
payInk: authed ? "var(--on-accent)" : "var(--ink-3)",
payCursor: authed ? "pointer" : "not-allowed",
payLabel: s.paid ? "Оплачено" : (s.method === "crypto" ? "Показать адрес для оплаты" : "Оплатить 4 900 ₽"),
paidOff: !s.paid
};
}
}
</script>
</body>
</html>