This commit is contained in:
2026-08-10 12:01:03 +07:00
commit 265b1202ad
95 changed files with 27718 additions and 0 deletions

467
.ref/landing.html Normal file
View File

@@ -0,0 +1,467 @@
<html lang="ru"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Malenia — Свобода в сети</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&amp;family=Tenor+Sans&amp;display=swap" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<style>
:root {
--gold: #C9A84C;
--gold-light: #E8CA7A;
--gold-dim: #8B6914;
--cream: #FAF7F2;
--warm-white: #F5F0E8;
--ink: #1A1610;
--ink-soft: #3D3428;
--ink-muted: #7A6E5F;
--border: rgba(201,168,76,0.25);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { cursor: none; }
body {
font-family: 'Tenor Sans', sans-serif;
background: var(--cream);
color: var(--ink);
min-height: 100vh;
overflow-x: hidden;
cursor: none;
}
/* ── Custom cursor ─────────────────────────────────── */
#cursor-dot,
#cursor-ring {
position: fixed;
top: 0; left: 0;
pointer-events: none;
z-index: 9999;
transform: translate(-50%, -50%);
transition: opacity .3s;
}
#cursor-dot {
width: 6px; height: 6px;
background: var(--gold);
border-radius: 50%;
}
#cursor-ring {
width: 32px; height: 32px;
border: 1px solid var(--gold);
border-radius: 50%;
transition: width .25s cubic-bezier(.4,0,.2,1),
height .25s cubic-bezier(.4,0,.2,1),
opacity .3s;
}
body.hovering #cursor-ring {
width: 48px; height: 48px;
border-color: var(--gold-light);
}
/* ── Noise overlay ─────────────────────────────────── */
body::before {
content: '';
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
opacity: .035;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
background-repeat: repeat;
background-size: 180px;
}
/* ── Layout ────────────────────────────────────────── */
.page {
position: relative;
z-index: 1;
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}
/* ── Header ────────────────────────────────────────── */
header {
padding: 2.5rem 4rem;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--border);
}
.logo {
font-family: 'Cormorant Garamond', serif;
font-weight: 300;
font-size: 1.5rem;
letter-spacing: .35em;
text-transform: uppercase;
color: var(--ink);
text-decoration: none;
}
.logo span { color: var(--gold); }
.header-rule {
flex: 1;
height: 1px;
background: var(--border);
margin: 0 2rem;
}
.header-tag {
font-size: .65rem;
letter-spacing: .25em;
text-transform: uppercase;
color: var(--ink-muted);
}
/* ── Hero ──────────────────────────────────────────── */
.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 6rem 2rem;
gap: 3.5rem;
}
.emblem {
position: relative;
width: 90px;
height: 90px;
opacity: 0;
animation: fadeUp .9s .1s forwards;
}
.emblem svg { width: 100%; height: 100%; }
.quote-block {
max-width: 640px;
opacity: 0;
animation: fadeUp .9s .25s forwards;
}
.quote-text {
font-family: 'Cormorant Garamond', serif;
font-size: clamp(2rem, 5vw, 3.4rem);
font-weight: 300;
line-height: 1.25;
color: var(--ink);
letter-spacing: .01em;
}
.quote-text em {
font-style: italic;
color: var(--gold-dim);
}
.quote-author {
margin-top: 1.25rem;
font-size: .7rem;
letter-spacing: .3em;
text-transform: uppercase;
color: var(--ink-muted);
}
/* ── Divider ───────────────────────────────────────── */
.divider {
display: flex;
align-items: center;
gap: 1rem;
width: 100%;
max-width: 480px;
opacity: 0;
animation: fadeUp .9s .4s forwards;
}
.divider::before,
.divider::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.divider-diamond {
width: 6px; height: 6px;
background: var(--gold);
transform: rotate(45deg);
flex-shrink: 0;
}
/* ── Buttons ───────────────────────────────────────── */
.cta-group {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
justify-content: center;
opacity: 0;
animation: fadeUp .9s .55s forwards;
}
.btn {
position: relative;
display: inline-flex;
align-items: center;
gap: .75rem;
padding: .85rem 2rem;
font-family: 'Tenor Sans', sans-serif;
font-size: .78rem;
letter-spacing: .18em;
text-transform: uppercase;
text-decoration: none;
border-radius: 0;
cursor: none;
transition: color .25s, background .25s, border-color .25s;
overflow: hidden;
}
.btn::after {
content: '';
position: absolute;
inset: 0;
background: var(--gold);
transform: scaleX(0);
transform-origin: left;
transition: transform .35s cubic-bezier(.4,0,.2,1);
z-index: 0;
}
.btn:hover::after { transform: scaleX(1); }
.btn > * { position: relative; z-index: 1; }
.btn-primary {
background: var(--ink);
color: var(--cream);
border: 1px solid var(--ink);
}
.btn-primary:hover { color: var(--ink); border-color: var(--gold); }
.btn-secondary {
background: transparent;
color: var(--ink);
border: 1px solid var(--gold);
}
.btn-secondary::after { background: var(--ink); }
.btn-secondary:hover { color: var(--cream); }
.btn-icon {
width: 18px; height: 18px;
fill: currentColor;
flex-shrink: 0;
}
/* ── Footer ────────────────────────────────────────── */
footer {
padding: 2rem 4rem;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
}
.footer-copy {
font-size: .65rem;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--ink-muted);
}
.footer-dot {
width: 4px; height: 4px;
background: var(--gold);
border-radius: 50%;
}
/* ── Animations ────────────────────────────────────── */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(22px); }
to { opacity: 1; transform: translateY(0); }
}
/* ── Responsive ────────────────────────────────────── */
@media (max-width: 640px) {
header { padding: 1.75rem 1.5rem; }
.header-rule { display: none; }
.header-tag { display: none; }
.hero { padding: 4rem 1.5rem; gap: 2.5rem; }
footer { padding: 1.5rem; flex-direction: column; align-items: flex-start; }
.btn { padding: .8rem 1.5rem; font-size: .72rem; }
.cta-group { flex-direction: column; align-items: stretch; }
.btn { justify-content: center; }
}
</style>
</head>
<body>
<!-- Cursor -->
<div id="cursor-dot" style="left: 233px; top: 539px;"></div>
<div id="cursor-ring" style="left: 233px; top: 539px;"></div>
<div class="page">
<!-- Header -->
<header>
<a class="logo" href="#">Mal<span>e</span>nia</a>
<div class="header-rule"></div>
<span class="header-tag">Свобода. Практика. Простота.</span>
</header>
<!-- Hero -->
<main class="hero">
<!-- Emblem -->
<div class="emblem" aria-hidden="true">
<svg viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- outer ring -->
<circle cx="45" cy="45" r="42" stroke="#C9A84C" stroke-width=".8" stroke-dasharray="3 4"></circle>
<!-- inner ring -->
<circle cx="45" cy="45" r="32" stroke="#C9A84C" stroke-width=".5" opacity=".5"></circle>
<!-- diamond -->
<path d="M45 18 L72 45 L45 72 L18 45 Z" stroke="#C9A84C" stroke-width=".9" fill="none"></path>
<!-- center dot -->
<circle cx="45" cy="45" r="3.5" fill="#C9A84C"></circle>
<!-- cardinal marks -->
<line x1="45" y1="3" x2="45" y2="12" stroke="#C9A84C" stroke-width=".8"></line>
<line x1="45" y1="78" x2="45" y2="87" stroke="#C9A84C" stroke-width=".8"></line>
<line x1="3" y1="45" x2="12" y2="45" stroke="#C9A84C" stroke-width=".8"></line>
<line x1="78" y1="45" x2="87" y2="45" stroke="#C9A84C" stroke-width=".8"></line>
</svg>
</div>
<!-- Quote -->
<div class="quote-block">
<p class="quote-text" id="quote-text">Верните себе<br><em>свободный интернет.</em></p>
<p class="quote-author">malenia.space</p>
</div>
<!-- Divider -->
<div class="divider" aria-hidden="true">
<div class="divider-diamond"></div>
</div>
<!-- CTA Buttons -->
<div class="cta-group">
<a class="btn btn-primary" href="https://t.me/maleniavpn" target="_blank" rel="noopener">
<!-- Telegram icon -->
<svg class="btn-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M22.265 2.428a1.523 1.523 0 0 0-1.547-.232L1.91 9.9a1.523 1.523 0 0 0 .089 2.844l4.498 1.498 1.815 5.784a.761.761 0 0 0 1.295.3l2.617-2.818 4.898 3.674a1.523 1.523 0 0 0 2.389-.98l3.047-16.762a1.523 1.523 0 0 0-.293-1.012zM9.94 13.88l-.98 3.267-.98-3.143L18.5 6.04z"></path>
</svg>
<span>Канал</span>
</a>
<a class="btn btn-secondary" href="https://t.me/maleniasupportbot" target="_blank" rel="noopener">
<!-- Bot icon -->
<svg class="btn-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2a2 2 0 0 1 2 2 2 2 0 0 1-1 1.732V7h3a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3v-8a3 3 0 0 1 3-3h3V5.732A2 2 0 0 1 10 4a2 2 0 0 1 2-2zm-3 9a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm6 0a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z"></path>
</svg>
<span>Поддержка</span>
</a>
</div>
</main>
<!-- Footer -->
<footer>
<span class="footer-copy">© 2026 Malenia</span>
<div class="footer-dot"></div>
<span class="footer-copy">malenia.space</span>
</footer>
</div>
<script>
/* ── Quotes ─────────────────────────────────────────── */
const quotes = [
"Верните себе\nсвободный интернет.",
"Свобода должна\nбыть доступной.",
"Интернет без границ —\nне привилегия, а норма.",
"Ваш трафик.\nВаши правила.",
"Тишина в сети —\nэто тоже выбор.",
"Открытый мир\nначинается здесь.",
"Без цензуры.\nБез компромиссов.",
"Простота —\nлучшая форма свободы.",
"Один клик\nмежду вами и миром.",
"Malenia —\nсвобода в форме привычки.",
"Будьте везде.\nОставайтесь невидимым.",
"Приватность — это право,\nа не роскошь.",
"Интернет таким,\nкаким он задумывался.",
"Ваши данные —\nтолько ваше дело.",
"Закрытых дверей\nбольше не существует.",
"Любой сайт.\nИз любой точки мира.",
"Оставьте след в истории,\nа не в браузере.",
"Malenia —\nключ к открытой сети.",
"Фильтры придумали они.\nРешение выбрали вы.",
"Безопасность, которую\nвы не замечаете.",
"Сотрите цифровые границы.\nОстаньтесь собой.",
"Скорость без компромиссов.\nСеть без преград.",
"Включили и забыли.\nВы в безопасности.",
"Блокировки иллюзорны.\nСвобода реальна.",
"Никакой слежки.\nТолько вы и интернет.",
"Доступ к информации —\nваше базовое право.",
"Malenia.\nИнтернет снова ваш.",
"Контроль над сетью\nв ваших руках.",
"Невидимый щит\nдля вашей свободы.",
"Весь мир на экране.\nБез лишних вопросов.",
"Никогда не поздно\nвыбрать свободу.",
"Привычка к запретам —\nповод проснуться.",
"Откройте глаза.\nСтен больше нет.",
"Вспомните, как выглядит\nнастоящая сеть.",
"Запреты стали нормой.\nПора это менять.",
"Свобода начинается\nс вашего решения.",
"Выход из спящего режима.\nСделайте первый шаг.",
"Лучший момент для\nсвободы — сейчас.",
"Иллюзия границ рушится\nв один клик.",
"Хватит мириться с рамками.\nМир шире, чем кажется.",
"Не ждите свободы.\nВключите её.",
"Цифровая амнезия окончена.\nВерните своё.",
"Осознанность начинается\nтам, где кончается цензура.",
"Первый шаг к свободе —\nперестать верить в стены.",
"Malenia.\nВаше цифровое пробуждение."
];
function renderQuote(raw) {
// italic the second line if two lines exist
const lines = raw.split('\n');
if (lines.length === 2) {
return `${lines[0]}<br><em>${lines[1]}</em>`;
}
return raw;
}
const el = document.getElementById('quote-text');
const chosen = quotes[Math.floor(Math.random() * quotes.length)];
el.innerHTML = renderQuote(chosen);
/* ── Custom cursor ──────────────────────────────────── */
const dot = document.getElementById('cursor-dot');
const ring = document.getElementById('cursor-ring');
let mx = -100, my = -100, rx = -100, ry = -100;
document.addEventListener('mousemove', e => { mx = e.clientX; my = e.clientY; });
(function loop() {
rx += (mx - rx) * .12;
ry += (my - ry) * .12;
dot.style.left = mx + 'px';
dot.style.top = my + 'px';
ring.style.left = rx + 'px';
ring.style.top = ry + 'px';
requestAnimationFrame(loop);
})();
document.querySelectorAll('a, button').forEach(el => {
el.addEventListener('mouseenter', () => document.body.classList.add('hovering'));
el.addEventListener('mouseleave', () => document.body.classList.remove('hovering'));
});
document.addEventListener('mouseleave', () => {
dot.style.opacity = '0';
ring.style.opacity = '0';
});
document.addEventListener('mouseenter', () => {
dot.style.opacity = '1';
ring.style.opacity = '1';
});
</script>
</body></html>