Skip to content
200

https://www.t30p.ru/

28.0 KB· 842 ms· text/html· Google Fonts, Cloudflare
Saved copy from just now.
More ▾

Screenshot

https://www.t30p.ru/ · desktop 1280 × 800Download
Screenshot of https://www.t30p.ru/

Esc or a click outside closes this. The picture is taken by our server, so the site never sees your visit.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="T30P — экосистема сервисов для аналитики социальных сетей, мониторинга чатов и автоматизации. YouTube рейтинги, статистика соцсетей, Chatometr(ЧАТОМЕТР), НаРаботу, фотобудка с ИИ-шаржами." />
    <link rel="shortcut icon" type="image/gif" href="/favicon.gif" />
    <link rel="canonical" href="https://www.t30p.ru/" />
    <title>T30P — Наши проекты</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=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
    <style>
        *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

        :root {
            --bg: #f5f7fa;
            --surface: #ffffff;
            --surface-hover: #f0f2f5;
            --border: rgba(0,0,0,0.07);
            --text: #1a202c;
            --text-muted: #64748b;
            --accent-1: #7c3aed;
            --accent-2: #0284c7;
            --accent-3: #059669;
            --accent-4: #ea580c;
            --grad-1: linear-gradient(135deg, #7c3aed, #a78bfa);
            --grad-2: linear-gradient(135deg, #0284c7, #38bdf8);
            --grad-3: linear-gradient(135deg, #059669, #34d399);
            --grad-4: linear-gradient(135deg, #ea580c, #fb923c);
        }

        body {
            font-family: 'Inter', -apple-system, sans-serif;
            background: var(--bg);
            color: var(--text);
            min-height: 100vh;
            overflow-x: hidden;
        }

        /* Animated background */
        .bg-glow {
            position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            pointer-events: none; z-index: 0;
            background:
                radial-gradient(ellipse 600px 400px at 20% 10%, rgba(124,58,237,0.06), transparent),
                radial-gradient(ellipse 500px 500px at 80% 50%, rgba(2,132,199,0.05), transparent),
                radial-gradient(ellipse 400px 300px at 50% 90%, rgba(5,150,105,0.04), transparent);
        }

        .wrapper { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; padding: 0 24px; }

        /* Header */
        header {
            text-align: center;
            padding: 80px 0 20px;
        }
        .logo {
            font-size: 3rem; font-weight: 800;
            background: linear-gradient(135deg, #7c3aed, #0284c7, #059669);
            -webkit-background-clip: text; -webkit-text-fill-color: transparent;
            background-clip: text;
            letter-spacing: -1px;
            animation: fadeInDown .8s ease;
        }
        .subtitle {
            color: var(--text-muted); font-size: 1.15rem; margin-top: 12px;
            animation: fadeInDown .8s ease .15s both;
        }

        /* Section title */
        .section-title {
            text-align: center; margin: 40px 0 48px;
            animation: fadeInDown .8s ease .3s both;
        }
        .section-title h2 {
            font-size: 2rem; font-weight: 700;
            color: var(--text);
        }
        .section-title p { color: var(--text-muted); margin-top: 8px; font-size: .95rem; }

        /* Cards grid */
        .projects {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 28px;
            padding-bottom: 80px;
        }

        .card {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 20px;
            padding: 36px 32px 32px;
            transition: transform .35s ease, box-shadow .35s ease, border-color .35s ease;
            position: relative;
            overflow: hidden;
            animation: fadeInUp .7s ease both;
            text-decoration: none;
            color: inherit;
            display: flex;
            flex-direction: column;
        }
        .card:nth-child(1) { animation-delay: .2s; }
        .card:nth-child(2) { animation-delay: .35s; }
        .card:nth-child(3) { animation-delay: .5s; }
        .card:nth-child(4) { animation-delay: .65s; }
        .card:nth-child(5) { animation-delay: .8s; }
        .card:nth-child(6) { animation-delay: .95s; }

        .card::before {
            content: ''; position: absolute; top: 0; left: 0; right: 0;
            height: 3px; border-radius: 20px 20px 0 0;
            opacity: 0; transition: opacity .35s ease;
        }
        .card:nth-child(1)::before { background: var(--grad-1); }
        .card:nth-child(2)::before { background: var(--grad-2); }
        .card:nth-child(3)::before { background: var(--grad-3); }
        .card:nth-child(4)::before { background: var(--grad-4); }
        .card:nth-child(5)::before { background: linear-gradient(135deg, #1d4ed8, #60a5fa); }
        .card:nth-child(6)::before { background: linear-gradient(135deg, #db2777, #f472b6); }

        .card:hover {
            transform: translateY(-6px);
            box-shadow: 0 20px 50px rgba(0,0,0,0.08);
            border-color: rgba(0,0,0,0.1);
        }
        .card:hover::before { opacity: 1; }

        .card-icon {
            width: 64px; height: 64px; border-radius: 16px;
            display: flex; align-items: center; justify-content: center;
            margin-bottom: 20px; transition: transform .35s ease;
        }
        .card:hover .card-icon { transform: scale(1.08); }
        .card:nth-child(1) .card-icon { background: rgba(124,58,237,0.08); }
        .card:nth-child(2) .card-icon { background: rgba(2,132,199,0.08); }
        .card:nth-child(3) .card-icon { background: rgba(5,150,105,0.08); }
        .card:nth-child(4) .card-icon { background: rgba(234,88,12,0.08); }
        .card:nth-child(5) .card-icon { background: rgba(29,78,216,0.08); }
        .card:nth-child(6) .card-icon { background: rgba(219,39,119,0.08); }

        .card-icon svg { width: 32px; height: 32px; }

        .card h3 { font-size: 1.35rem; font-weight: 700; margin-bottom: 8px; }
        .card .badge {
            display: inline-block; font-size: .7rem; font-weight: 600;
            padding: 3px 10px; border-radius: 20px; margin-left: 8px;
            vertical-align: middle; text-transform: uppercase; letter-spacing: .5px;
        }
        .badge-beta { background: rgba(234,88,12,0.1); color: var(--accent-4); }

        .card p {
            color: var(--text-muted); line-height: 1.65; font-size: .93rem;
            flex-grow: 1;
        }
        .card-features {
            display: flex; flex-wrap: wrap; gap: 8px;
            margin-top: 20px; padding-top: 20px;
            border-top: 1px solid var(--border);
        }
        .feature-tag {
            font-size: .78rem; padding: 5px 12px;
            border-radius: 8px; font-weight: 500;
        }
        .card:nth-child(1) .feature-tag { background: rgba(124,58,237,0.07); color: var(--accent-1); }
        .card:nth-child(2) .feature-tag { background: rgba(2,132,199,0.07); color: var(--accent-2); }
        .card:nth-child(3) .feature-tag { background: rgba(5,150,105,0.07); color: var(--accent-3); }
        .card:nth-child(4) .feature-tag { background: rgba(234,88,12,0.07); color: var(--accent-4); }
        .card:nth-child(5) .feature-tag { background: rgba(29,78,216,0.07); color: #1d4ed8; }
        .card:nth-child(6) .feature-tag { background: rgba(219,39,119,0.07); color: #db2777; }

        .card-link {
            display: inline-flex; align-items: center; gap: 6px;
            margin-top: 20px; font-weight: 600; font-size: .9rem;
            transition: gap .3s ease;
        }
        .card:nth-child(1) .card-link { color: var(--accent-1); }
        .card:nth-child(2) .card-link { color: var(--accent-2); }
        .card:nth-child(3) .card-link { color: var(--accent-3); }
        .card:nth-child(4) .card-link { color: var(--accent-4); }
        .card:nth-child(5) .card-link { color: #1d4ed8; }
        .card:nth-child(6) .card-link { color: #db2777; }
        .card:hover .card-link { gap: 10px; }

        /* Footer */
        footer {
            border-top: 1px solid var(--border);
            padding: 40px 0;
            text-align: center;
            color: var(--text-muted);
            font-size: .85rem;
            line-height: 1.8;
        }
        footer a { color: var(--text-muted); text-decoration: none; transition: color .2s; }
        footer a:hover { color: var(--text); }
        .footer-links { margin-top: 12px; display: flex; justify-content: center; gap: 24px; flex-wrap: wrap; }

        /* Ratings section */
        .ratings {
            padding: 48px 0 0;
        }
        .ratings h3 {
            text-align: center; font-size: 1.15rem; font-weight: 600;
            color: var(--text-muted); margin-bottom: 20px;
        }
        .ratings-grid {
            display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
        }
        .ratings-grid a {
            display: inline-block; padding: 8px 18px;
            background: var(--surface); border: 1px solid var(--border);
            border-radius: 10px; font-size: .85rem; font-weight: 500;
            color: var(--text-muted); text-decoration: none;
            transition: all .25s ease;
        }
        .ratings-grid a:hover {
            color: var(--accent-2); border-color: var(--accent-2);
            box-shadow: 0 4px 16px rgba(2,132,199,0.1);
            transform: translateY(-2px);
        }

        /* Responsive */
        @media (max-width: 768px) {
            .projects { grid-template-columns: 1fr; }
            .logo { font-size: 2.2rem; }
            header { padding: 48px 0 12px; }
            .section-title { margin: 28px 0 32px; }
            .section-title h2 { font-size: 1.5rem; }
        }

        /* Animations */
        @keyframes fadeInDown {
            from { opacity: 0; transform: translateY(-20px); }
            to { opacity: 1; transform: translateY(0); }
        }
        @keyframes fadeInUp {
            from { opacity: 0; transform: translateY(30px); }
            to { opacity: 1; transform: translateY(0); }
        }

        /* Legal Modal */
        .modal-backdrop {
            display: none;
            position: fixed; inset: 0; z-index: 1000;
            background: rgba(0,0,0,0.45);
            backdrop-filter: blur(4px);
            -webkit-backdrop-filter: blur(4px);
            align-items: center; justify-content: center;
            animation: backdropIn .25s ease;
        }
        .modal-backdrop.open { display: flex; }
        @keyframes backdropIn {
            from { opacity: 0; } to { opacity: 1; }
        }
        .modal {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 20px;
            box-shadow: 0 32px 80px rgba(0,0,0,0.18);
            width: 90%; max-width: 760px;
            max-height: 82vh;
            display: flex; flex-direction: column;
            animation: modalIn .3s cubic-bezier(.34,1.56,.64,1);
        }
        @keyframes modalIn {
            from { opacity: 0; transform: translateY(24px) scale(.97); }
            to   { opacity: 1; transform: translateY(0) scale(1); }
        }
        .modal-header {
            display: flex; align-items: center; justify-content: space-between;
            padding: 22px 28px 18px;
            border-bottom: 1px solid var(--border);
            flex-shrink: 0;
        }
        .modal-header h2 {
            font-size: 1.15rem; font-weight: 700; color: var(--text);
        }
        .modal-close {
            width: 34px; height: 34px; border-radius: 50%;
            border: 1px solid var(--border);
            background: var(--bg); cursor: pointer;
            display: flex; align-items: center; justify-content: center;
            transition: background .2s, border-color .2s;
            flex-shrink: 0;
        }
        .modal-close:hover { background: #fee2e2; border-color: #fca5a5; }
        .modal-close svg { pointer-events: none; }
        .modal-body {
            overflow-y: auto; padding: 24px 28px 28px;
            color: var(--text); font-size: .9rem; line-height: 1.75;
        }
        .modal-body h1, .modal-body h2, .modal-body h3 {
            margin: 1.2em 0 .5em; font-weight: 700;
            color: var(--text);
        }
        .modal-body h1 { font-size: 1.25rem; }
        .modal-body h2 { font-size: 1.05rem; }
        .modal-body p { margin: .55em 0; color: var(--text-muted); }
        .modal-body a { color: var(--accent-2); text-decoration: none; }
        .modal-body a:hover { text-decoration: underline; }
        .modal-loading {
            text-align: center; padding: 48px 0;
            color: var(--text-muted); font-size: .95rem;
        }
        .modal-loading::after {
            content: ''; display: block; margin: 16px auto 0;
            width: 28px; height: 28px; border-radius: 50%;
            border: 3px solid var(--border);
            border-top-color: var(--accent-2);
            animation: spin .7s linear infinite;
        }
        @keyframes spin { to { transform: rotate(360deg); } }
    </style>
</head>
<body>
    <div class="bg-glow"></div>
    <div class="wrapper">
        <header>
            <div class="logo">T30P</div>
            <p class="subtitle">Аналитика и автоматизация для социальных сетей</p>
        </header>

        <div class="section-title">
            <h2>Наши проекты</h2>
            <p>Инструменты для работы с данными, мониторинга и продвижения</p>
        </div>

        <div class="projects">
            <!-- 1. Light T30P -->
            <a href="https://light.t30p.ru/" class="card" id="project-youtube">
                <div class="card-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <polygon points="5 3 19 12 5 21 5 3"/>
                    </svg>
                </div>
                <h3>Топ YouTube за день</h3>
                <p>Ежедневный рейтинг самых популярных русскоязычных видео на YouTube. Автоматический сбор и ранжирование трендовых видео с использованием YouTube API. Отслеживайте, что смотрит Рунет прямо сейчас.</p>
                <div class="card-features">
                    <span class="feature-tag">YouTube API</span>
                    <span class="feature-tag">Ежедневные рейтинги</span>
                    <span class="feature-tag">Тренды</span>
                </div>
                <span class="card-link">Перейти к рейтингу <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
            </a>

            <!-- 2. Social T30P -->
            <a href="https://social.t30p.ru/" class="card" id="project-social">
                <div class="card-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#0284c7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
                        <circle cx="9" cy="7" r="4"/>
                        <path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
                        <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
                    </svg>
                </div>
                <h3>Статистика соцсетей</h3>
                <p>Рейтинг и аналитика социальных аккаунтов. Отслеживайте динамику подписчиков, вовлечённость аудитории и активность в ВКонтакте, Telegram, YouTube и других платформах в одном месте.</p>
                <div class="card-features">
                    <span class="feature-tag">Мульти-платформа</span>
                    <span class="feature-tag">Аналитика</span>
                    <span class="feature-tag">Рейтинги</span>
                </div>
                <span class="card-link">Открыть статистику <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
            </a>

            <!-- 3. Chatometr -->
            <a href="https://chatometr.ru/#!/about" class="card" id="project-chatometr">
                <div class="card-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#059669" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
                    </svg>
                </div>
                <h3>Chatometr (ЧАТОМЕТР)</h3>
                <p>Сбор, мониторинг и аналитика сообщений из Telegram, ВКонтакте, WhatsApp и MAX. Анализ настроений в чатах, отслеживание проблемных тем и обращений. Расширенная аналитика и выгрузки данных.</p>
                <div class="card-features">
                    <span class="feature-tag">Telegram</span>
                    <span class="feature-tag">ВКонтакте</span>
                    <span class="feature-tag">WhatsApp</span>
                    <span class="feature-tag">MAX</span>
                </div>
                <span class="card-link">Узнать больше <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
            </a>

            <!-- 5. MAX Ad Blocker -->
            <a href="/MaxAdBlocker.aspx" class="card" id="project-maxadblocker">
                <div class="card-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#1d4ed8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M12 2L3 7v5c0 5.25 3.75 10.15 9 11.35C17.25 22.15 21 17.25 21 12V7L12 2z"/>
                        <line x1="9" y1="9" x2="15" y2="15" stroke="#ef4444" stroke-width="2.2"/>
                        <line x1="15" y1="9" x2="9" y2="15" stroke="#ef4444" stroke-width="2.2"/>
                    </svg>
                </div>
                <h3>MAX Ad Blocker</h3>
                <p>Расширение для браузера, которое автоматически скрывает рекламные посты (<strong>#реклама</strong>) на web.max.ru. Чистая лента без рекламы — счётчик скрытых постов в реальном времени.</p>
                <div class="card-features">
                    <span class="feature-tag">Chrome Extension</span>
                    <span class="feature-tag">web.max.ru</span>
                    <span class="feature-tag">Manifest V3</span>
                </div>
                <span class="card-link">Установить расширение <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
            </a>

            <!-- 6. Фотобудка -->
            <a href="https://t.me/photo2ai_bot" class="card" id="project-photo">
                <div class="card-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="#db2777" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
                        <circle cx="12" cy="13" r="4"/>
                    </svg>
                </div>
                <h3>Фотобудка с ИИ-шаржами <span class="badge badge-beta">бета</span></h3>
                <p>Сделайте селфи — и через минуту получите четыре весёлых ИИ-шаржа на выбор. Понравившийся вариант можно скачать, отправить себе по QR-коду или распечатать. Работает прямо в браузере, а также в Telegram-боте <strong>@photo2ai_bot</strong> и в MAX-боте — оплата картой или Telegram Stars.</p>
                <div class="card-features">
                    <span class="feature-tag">Селфи → шарж за минуту</span>
                    <span class="feature-tag">4 варианта на выбор</span>
                    <span class="feature-tag">Telegram и MAX</span>
                    <span class="feature-tag">QR и печать</span>
                </div>
                <span class="card-link">Попробовать в Telegram <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
            </a>
        </div>

        <div class="ratings">
            <h3>Рейтинги</h3>
            <div class="ratings-grid">
                <a href="/y">YouTube</a>
                <a href="/Twitch.aspx">Twitch TV</a>
                <a href="/Telegram.aspx">Телеграм</a>
                <a href="/TikTok.aspx">ТикТок</a>
                <a href="/Smi.aspx">СМИ</a>
                <a href="/Zen.aspx">Яндекс.Дзен</a>
                <a href="/Tenchat.aspx">Тенчат</a>
                <a href="https://vk.com/drninfo">Дайджест Недвижимости</a>
                <a href="https://vk.com/topmosreg">Подмосковные новости</a>
                <a href="/MaxAdBlocker.aspx">MAX Ad Blocker</a>
                <a href="https://t.me/photo2ai_bot">Фотобудка в Telegram</a>
                <a href="https://max.ru/se13742258_1_bot">Фотобудка в MAX</a>
            </div>
        </div>

        <footer>
            <div>&copy; 2006–2026 [766год] T30P — Рейтинг постов русскоязычной блогосферы</div>
            <div style="margin-top:6px; font-size:.82rem;">Посты собираются и рейтингуются автоматически. Не является СМИ.</div>
            <div class="footer-links">
                <a href="mailto:topbot@yandex.ru">topbot@yandex.ru</a>
                <a href="/#legal" id="legalLink">Политика конфиденциальности</a>
                <a href="https://www.t30p.ru/faq.aspx">Помощь</a>
                <a href="/MaxAdBlocker.aspx">MAX Ad Blocker</a>
                <a href="https://t.me/t30pru">Telegram</a>
                <a href="https://vk.com/t30pru">ВКонтакте</a>
            </div>
        </footer>
    </div>

    <!-- Legal Modal -->
    <div class="modal-backdrop" id="legalModal" role="dialog" aria-modal="true" aria-labelledby="legalModalTitle">
        <div class="modal" id="legalModalBox">
            <div class="modal-header">
                <h2 id="legalModalTitle">Политика конфиденциальности</h2>
                <button class="modal-close" id="legalModalClose" title="Закрыть" aria-label="Закрыть">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#64748b" stroke-width="2.5" stroke-linecap="round">
                        <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
                    </svg>
                </button>
            </div>
            <div class="modal-body" id="legalModalBody">
                <div class="modal-loading">Загрузка...</div>
            </div>
        </div>
    </div>

    <!-- Legal modal script -->
    <script>
    (function () {
        var backdrop = document.getElementById('legalModal');
        var body     = document.getElementById('legalModalBody');
        var closeBtn = document.getElementById('legalModalClose');
        var loaded   = false;

        function openModal() {
            backdrop.classList.add('open');
            document.body.style.overflow = 'hidden';
            if (!loaded) loadContent();
        }

        function closeModal() {
            backdrop.classList.remove('open');
            document.body.style.overflow = '';
            // clear hash without page jump
            history.replaceState(null, '', location.pathname + location.search);
        }

        function loadContent() {
            loaded = true;
            body.innerHTML = '<div class="modal-loading">Загрузка...</div>';
            fetch('/PrivacyPolicy.aspx')
                .then(function(r) { return r.text(); })
                .then(function(html) {
                    var doc = new DOMParser().parseFromString(html, 'text/html');
                    // InnerContent is rendered as a plain div by ASP.NET master page
                    // It sits inside: form#form1 > div#index > div#top > div#InnerContent
                    var content =
                        doc.getElementById('InnerContent') ||
                        doc.getElementById('top') ||
                        doc.querySelector('main') ||
                        doc.body;
                    // Strip only chrome elements — NOT 'form' (ASP.NET wraps everything in form)
                    var removeSelectors = [
                        'script', 'style', 'link', 'noscript',
                        'header', 'footer', 'nav',
                        '#header', '#footer', '#nav', '#popup',
                        '#r-content',
                        '.foot', '.foot2', '.foot3', '.footinf', '.footinf2',
                        '.sk2', '.skf', '.socialico', '.errorpage',
                        '.menu', '#menu'
                    ];
                    content.querySelectorAll(removeSelectors.join(',')).forEach(function(el){ el.remove(); });
                    body.innerHTML = content.innerHTML || '<p style="color:#64748b">Текст не найден.</p>';
                })
                .catch(function() {
                    body.innerHTML = '<p style="color:#64748b">Не удалось загрузить текст. ' +
                        '<a href="/PrivacyPolicy.aspx" target="_blank">Открыть на отдельной странице &rarr;</a></p>';
                });
        }

        // Open on #legal hash
        function checkHash() {
            if (location.hash === '#legal') openModal();
        }

        // Close handlers
        closeBtn.addEventListener('click', closeModal);
        backdrop.addEventListener('click', function(e) {
            if (e.target === backdrop) closeModal();
        });
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && backdrop.classList.contains('open')) closeModal();
        });

        // Footer link — prevent navigation, open modal instead
        var legalLink = document.getElementById('legalLink');
        if (legalLink) {
            legalLink.addEventListener('click', function(e) {
                e.preventDefault();
                history.replaceState(null, '', '/#legal');
                openModal();
            });
        }

        // On load
        checkHash();
        window.addEventListener('hashchange', checkHash);
    })();
    </script>

    <!-- Yandex.Metrika counter -->
    <script type="text/javascript">
       (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
       m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
       (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
       ym(41655969, "init", {
            clickmap:true,
            trackLinks:true,
            accurateTrackBounce:true,
            webvisor:true
       });
    </script>
    <noscript><img src="https://mc.yandex.ru/watch/41655969" style="position:absolute; left:-9999px;" alt="" /></noscript>
    <!-- /Yandex.Metrika counter -->
</body>
</html>

Shown as plain text. Nothing from www.t30p.ru runs in your browser. Underlined links open their own code view, and line numbers give you a link to share.