Системные правила интерфейсов

Дизайн-гайдлайн и эталонный код

Официальное руководство по визуальной стилистике и чистый эталонный HTML/CSS код страниц «Игровой стол» для разработчиков и ИИ-агентов.

1. Палитра дизайн-токенов

Background #FFFFFF Основной фон всех страниц
--ink #121317 Текст, заголовки, Primary-кнопки
--ink-muted #5F6368 Пояснения, субтитры, вторичный текст
--card-bg #F8F9FB Фон карточек, полей ввода кода
--border rgba(18, 19, 23, 0.08) Тонкие разделители и рамки
--accent-green #137333 Успех, подтверждение статуса

2. Строгие правила для ИИ при создании страниц

1
Всегда чистый белый фон: Тело страницы (`body`) обязано иметь цвет `#ffffff`. Никаких темных «геймерских» фонов, черных градиентов или неоновых рамок.
2
Фирменная типографика: Основной шрифт — строго 'Google Sans', sans-serif. Для кодов авторизации, цифр и ID использовать моноширинный 'JetBrains Mono', monospace.
3
Стандартная шапка и логотип: В шапке использовать строго SVG assets/image/logo.svg с CSS-свойством filter: invert(1) для чистого черного цвета логотипа на белом фоне. Ссылка всегда ведёт на корень /.
4
Pill-кнопки (скругление 999px): Все интерактивные кнопки имеют полное скругление border-radius: 999px, высоту 48–52px и плавную микро-анимацию при наведении.
5
Обязательный деплой: При любых изменениях файлов в папке public/ необходимо запускать деплой Firebase: npx firebase-tools deploy --only hosting:main-site.

3. Эталонный код главной страницы (index.html)

Минималистичный лейаут с центрированным заголовком, субтитром и кнопками перехода:

index.html (Core Layout)
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <title>Игровой стол</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="/fav.ico?v=4">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap">
    <style>
        :root {
            --ink: #121317;
            --ink-muted: #5f6368;
            --border: rgba(18, 19, 23, 0.08);
            --card-bg: #f8f9fb;
        }
        body {
            margin: 0; min-height: 100svh; display: flex; flex-direction: column;
            background: #ffffff; color: var(--ink); font-family: 'Google Sans', sans-serif;
        }
        .site-header { width: 100%; padding: 24px 48px; display: flex; align-items: center; }
        .brand-logo { height: 26px; filter: invert(1); display: block; }
        .hero { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; text-align: center; }
        .hero-title { font-size: clamp(2.5rem, 6vw, 5rem); font-weight: 500; letter-spacing: -0.025em; line-height: 1.08; margin-bottom: 24px; }
        .hero-subtitle { font-size: 18px; color: var(--ink-muted); max-width: 560px; margin-bottom: 40px; line-height: 1.6; }
        .btn {
            display: inline-flex; align-items: center; justify-content: center; gap: 10px;
            height: 52px; padding: 0 30px; border-radius: 999px; font-size: 16px; font-weight: 500;
            text-decoration: none; border: 1px solid transparent; cursor: pointer; transition: all 0.2s ease;
        }
        .btn-primary { background: var(--ink); color: #fff; box-shadow: 0 8px 24px rgba(18, 19, 23, 0.12); }
        .btn-primary:hover { background: #2b2d33; transform: translateY(-2px); }
        .btn-secondary { background: var(--card-bg); color: var(--ink); border-color: rgba(18, 19, 23, 0.1); }
        .btn-secondary:hover { background: #f0f2f6; transform: translateY(-2px); }
        .site-footer { width: 100%; padding: 32px 24px; border-top: 1px solid var(--border); }
        .footer-inner { max-width: 1120px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; }
    </style>
</head>
<body>
    <header class="site-header">
        <a href="/"><img src="assets/image/logo.svg" class="brand-logo" alt="Игровой стол"></a>
    </header>
    <main class="hero">
        <h1 class="hero-title">Один сервер. Единая экосистема.</h1>
        <p class="hero-subtitle">Цифровая инфраструктура сообщества «Игровой стол» и система Karczerbot.</p>
        <div style="display:flex; gap:14px; flex-wrap:wrap; justify-content:center;">
            <a href="https://discord.gg/xY9Gtp6GVR" class="btn btn-primary">Discord сервер</a>
            <a href="/kbadmin" class="btn btn-secondary">Karczerbot</a>
        </div>
    </main>
    <footer class="site-footer">
        <div class="footer-inner">
            <span style="color:var(--ink-muted); font-size:14px;">© 2026 Игровой стол</span>
            <div style="display:flex; gap:20px;">
                <a href="/design.html" style="color:var(--ink-muted); text-decoration:none;">Брендбук</a>
                <a href="/guideline.html" style="color:var(--ink); text-decoration:none; font-weight:500;">Гайдлайн</a>
            </div>
        </div>
    </footer>
</body>
</html>

4. Эталонный код карточки авторизации (callback.html)

Шаблон карточки с одноразовым кодом, кнопкой копирования в буфер и кнопками Discord:

callback.html (Card & Code Box)
<!-- Карточка центрального экрана callback.html -->
<main class="hero">
    <div class="card">
        <div class="status-badge" id="statusBadge">
            <svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.4" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
            <span>Авторизация подтверждена</span>
        </div>

        <h1 class="hero-title">Одноразовый код</h1>
        <p class="hero-subtitle">
            Скопируйте код и отправьте его боту на сервере с помощью команды <code class="code-pill">/code</code>
        </p>

        <div class="code-box">
            <span class="code-text" id="codeDisplay">Загрузка...</span>
            <button type="button" class="btn-copy" id="copyBtn" onclick="copyCode()">
                <span id="copyText">Копировать</span>
            </button>
        </div>

        <div class="actions">
            <a href="https://discord.com/channels/1301478636880400405" target="_blank" class="btn btn-primary">
                Перейти в Discord
            </a>
            <a href="/" class="btn btn-secondary">
                На главную страницу
            </a>
        </div>
    </div>
</main>

<script>
    const urlParams = new URLSearchParams(window.location.search);
    const code = urlParams.get('code');
    const codeDisplay = document.getElementById('codeDisplay');
    const copyBtn = document.getElementById('copyBtn');
    const copyText = document.getElementById('copyText');

    if (code && code.trim() !== '') {
        codeDisplay.textContent = code;
    } else {
        codeDisplay.textContent = 'Код не найден';
        codeDisplay.classList.add('error');
        copyBtn.style.display = 'none';
    }

    function copyCode() {
        if (!code) return;
        navigator.clipboard.writeText(code).then(() => {
            copyBtn.classList.add('copied');
            copyText.textContent = 'Скопировано!';
            setTimeout(() => {
                copyBtn.classList.remove('copied');
                copyText.textContent = 'Копировать';
            }, 2000);
        });
    }
</script>