Files
2026-10-14 23:39:17 +07:00

27 KiB
Raw Permalink Blame History

Дизайн-система сайта и игры «Вечерний детектив»

Два направления с общим логотипом: сайт помогает выбрать дело и управлять участием, игра погружает в расследование. Визуальные правила описаны здесь; единственный источник правил реализации — FRONTEND_CODE_STANDARD.md. Рабочие страницы мигрируют постепенно; образцы не меняют их оформление.

Области применения

Направление Где применяется Характер
Сайт «Золотой вечер» Главная, каталог, кабинет, страницы организатора, редакторы и обычные формы Тёмные ровные панели, машинописный шрифт, ярко-жёлтые действия, лёгкие фактуры
Игра «Материалы дела» Расследование команды, улики, сюжетные документы, игровое управление и печатные материалы Существующие бумага, кожа, металл, машинописный текст, бронзовые надписи и фактурные кнопки

Превью сюжетного документа внутри каталога или редактора использует игровой стиль; окружающие управление и формы — стиль сайта. Игровые изображения и фоны сценариев сохраняют собственное оформление.

Живые образцы

Запустить npm run dev и открыть /design-system на адресе Vite. Вкладка «Сайт» открывается первой, «Игра» показывает отдельные материалы и управление, «Компоненты» — последовательный каталог: заголовок компонента, живой пример, описание контракта и код подключения; затем следующий компонент. Страница доступна только в разработке, без входа и пункта основного меню; маршрут и компоненты образцов исключены из production-сборки.

Все данные вымышлены. Форма, модальное окно и ход игры работают локально; игровой ход не вызывает API и не меняет данные игры. Сайт использует SiteThemeProvider, игровые образцы — собственный NConfigProvider: тема сайта не попадает в игровые компоненты.

Общий бренд и логотип

Использовать существующий знак: детектив в шляпе, чёрный круг, золотая окантовка. Не растягивать, не обрезать окантовку, не перерисовывать. Свободное поле — не меньше четверти диаметра; промежуток до названия — от 12 px. Размеры образцов — 48 и 144 px.

Изображение рядом с названием имеет пустой alt, самостоятельный знак — описательный. JPEG сохраняет белый фон внутри круга, круглое размещение допускает border-radius: 50%. Прозрачного и векторного исходника нет; качество крупной печати и узнаваемость favicon проверяются отдельно.

Основной цвет текста обоих стилей на тёмных поверхностях — светлый #EEE, второстепенный — #BDB8AE. Игровой бежевый #BFA07D используется точечно: в бренде, декоративных надписях и текстовыделителе. Цвета статусов сохраняют значение; текст на бумаге и жёлтых кнопках остаётся тёмным. Общий блок бренда DesignBrand содержит логотип 48 px, промежуток 12 px и название «Вечерний детектив» через HeaderText. На узком экране название может переноситься; название направления «Материалы дела» располагается отдельно.

Общие правила: mobile-first, desktop от 1024 px, текущие контейнеры 700/1200 px, явные состояния ошибки и загрузки, доступность с клавиатуры. Шкала отступов: 4, 8, 12, 16, 24, 32, 48, 64 px. Цвета задавать семантическими CSS-переменными.

Сайт «Золотой вечер»

Палитра

Токены находятся в src/assets/base.css. --brand-bronze и бумага связывают оформление с игрой; жёлтый primary относится к сайту, а не к игровым действиям.

CSS-переменная Цвет Назначение
--brand-background #111111 Фон сайта; текст на золотой кнопке и бумаге
--brand-surface #222222 Карточки, панели, окна
--brand-surface-hover #2E2E39 Подсветка поверхности при наведении
--brand-text #EEEEEE Основной текст
--brand-text-muted #BDB8AE Пояснения, подписи, второстепенные данные
--brand-accent #FFD43B Основное действие, ссылки, активный элемент, focus
--brand-accent-hover #FFE066 Наведение на основное действие
--brand-accent-pressed #F5C518 Нажатие на основное действие
--brand-border #77737F Границы полей и панелей
--brand-success #87C99D Успех
--brand-info #94BFEE Информация
--brand-error #F29A9A Ошибка и опасное действие
--brand-bronze #BFA07D Бренд, текстовыделитель и декоративные надписи
--brand-paper #F4EDE0 Бумажные материалы

Предупреждение использует золото и явную подпись. Статусы не передавать только цветом: добавлять текст и штатную иконку. Жёлтый акцент не использовать как цвет обычного текста на бумаге или белом фоне.

Типографика и компоновка

Весь стиль сайта использует существующий font_old_typer: заголовки, основной текст, подписи, меню, кнопки, формы, таблицы и модальные окна. Новые шрифты не загружаются. Шрифт задаётся на контейнере и в локальной теме Naive UI, чтобы сохраняться в телепортируемых окнах. Игровая типографика остаётся прежней.

Элемент Размер Вес Межстрочный интервал
Главный заголовок clamp(32px, 4vw, 48px) 600 1.15
Заголовок раздела 28 px 600 1.3
Заголовок блока 22 px 600 1.4
Вступление 18 px 400 1.5
Основной текст 18 px 400 1.5
Подпись 14 px 400 1.5
Короткая надпись над разделом 14 px 400 1.5
Бумажный текст 18 px существующий вес MessagePaper 1.5

Шкала отступов: 4, 8, 12, 16, 24, 32, 48, 64 px. На мобильном экране внешние поля 16 px, на desktop — 24 px; между разделами 32 px на мобильном и 48 px на desktop, без сложения верхних и нижних отступов соседних секций. Базовое скругление 8 px. Панели имеют тонкую границу; выраженную тень оставить бумажному слою и существующим фактурным компонентам.

Использовать текущие контейнеры .width700 для дел и .width1200 для списков, прокрутку .center-block-custom и шапку высотой 70 px. Mobile-first; desktop-порог — @media (width >= 1024px). До него колонки складываются вертикально, кнопки переносятся; широкая таблица прокручивается внутри себя.

Главный блок выравнивается по верхнему краю, между колонками 32 px. Внутри карточек поля 16 px на мобильном и 24 px на desktop, между элементами 16 px, перед главным действием 24 px. Отступы абзацев по умолчанию нулевые; интервалы задаются контейнерами. Не сжимать машинописный заголовок отрицательным межбуквенным интервалом. Небольшие папки каталога сохраняют подписи не меньше 14 px.

Компоненты и материалы

Использовать Naive UI. NConfigProvider берёт тему из CSS-токенов. Primary имеет сплошную заливку #FFD43B, hover #FFE066, pressed #F5C518, текст #111; сохранять машинописный шрифт и видимый focus. Опасное действие использует красный акцент. Disabled и loading — штатные состояния Naive UI.

Главный блок, карточки, формы, таблицы и окна имеют ровные поверхности. Кожа допускается как небольшая полоса в шапке (BeltBlock), бумага — в документальных фрагментах превью дела (paper.jpg); не оформлять весь сайт стопками листов. Название с логотипом в обоих стилях использует общий DesignBrand и существующий HeaderText: бежевый #BFA07D, машинописный шрифт 22 px, вес 600 и разрядка 2 px. Меню и основной текст сайта используют font_old_typer.

Ссылки жёлтые на тёмном фоне; на светлом ярлыке текст тёмный. Формы имеют подписи и ошибки у полей, таблицы — локальную прокрутку при необходимости. Модальные окна — n-modal + n-card, заголовок, role dialog и aria-modal.

Доска расследования

Без градиентов и свечения. Главный блок использует композицию из текстовых улик: записка, билет, время отправления, номера и соединительные линии приглушённого бронзового цвета. Логотип остаётся в шапке, не заменяет обложку каждого дела. Под композицией — название, параметры и жёлтое действие.

На desktop фрагменты расположены асимметрично с небольшими поворотами; на мобильном — вертикально, без наложения текста. Бумага использует существующую фактуру. Машинописный шрифт допустим внутри документальных фрагментов; описания, навигация, формы и кнопки тоже используют font_old_typer.

Документальные фрагменты декоративные, не имеют самостоятельных hover или действий. Линии не перехватывают клики. Формы и служебные панели сохраняют ровные поверхности. Большая доска использует CaseBoard; каталог — повторяемые папки CaseFolder с предметными обложками.

Детали досье

Приём Где и как применять
Папка с ярлыком Карточка каталога, номер на выступающем ярлыке; оставлять 32 px между карточками
Бежевый маркер Одно важное выражение в заголовке, тёмный текст на бежевой неровной полосе
Улика на обороте Явная кнопка раскрывает цитату, aria-expanded и aria-controls; без 3D-переворота
Архивные разделители Пунктир между разделами, номера и уголки на обложках; не дополнительные рамки вокруг каждого текста
Предметная обложка Билет, ключ или письмо из существующих иконок и бумажных фактур; тот же символ рядом с названием
Заметка на полях Короткая сюжетная подпись рядом с большой доской; на мобильном — ниже композиции
Штамп статуса «Новое дело», «Скоро», «Пройдено»; только при наличии соответствующего реального состояния
Подсветка связи Одна бронзовая линия становится жёлтой при hover или фокусе действия в карточке
Конец досье Номер листа, название проекта, тонкая линия и «Продолжение — в следующем деле»

Карточки поднимаются на 3 px при наведении мыши и фокусе внутри. Переходы занимают 160 ms; при prefers-reduced-motion подъём и переходы отключаются, раскрытие цитат продолжает работать. Touch не зависит от hover: цитата открывается кнопкой. Декоративные слои и линии не перехватывают клики.

Три папки в образцах вымышлены, их штампы не обозначают реальные публикации или историю пользователя. В образце дело «Скоро» имеет отключённое основное действие через отдельный disabled; сам статус не управляет доступностью. На рабочем сайте привязать состояния к данным; не вычислять «новое» или «пройдено» по предположениям. Формы и таблицы сохраняют спокойный вид.

Игра «Материалы дела»

Эталон и палитра

Эталон — текущее оформление расследования команды, а не тема сайта. Сохранить MessagePaper, IntroBlock, GameInputForm, BeltBlock, MetalPlate и их фактуры. Окружение тёмное #111, панели #222, основной текст #EEE, бумажный текст чёрный, декоративные надписи бронзовые #BFA07D. Существующие мятные состояния и фактурные игровые кнопки сохраняются; жёлтую тему сайта не передавать игровому provider.

Материалы и управление

Материал Источник Применение
Бумага MessagePaper, paper.jpg, paper_white.jpg Вступление, точки, улики и фотографии; сохранять слои и тени
Кожа BeltBlock, belt.png Полосы управления и фактурные действия
Металл MetalPlate, metal.png, pin.png Детали панелей, без заливки всей страницы
Игровое управление GameInputForm, input_center.png, button.png Место назначения, счётчики и фактурная кнопка

Машинописный шрифт сохраняется в документах и существующих игровых компонентах; сайт использует тот же шрифт по собственным правилам компоновки. HeaderText — для бронзовых игровых надписей. В образцах подписи на коже и металле используют чёрную подложку 80% для читаемости. Это локальное оформление образцов, не массовая переделка рабочих игровых компонентов.

Вступление и улика используют настоящие компоненты с демонстрационными данными. Панель хода повторяет поведение игры: успешный локальный ход очищает поле и показывает результат. В образцах панель размещена в потоке страницы; в рабочей игре остаётся её существующее фиксированное положение.

Печатные материалы

Светлые внутренние страницы, тёмный текст, небольшие золотые метки. Тёмное оформление допустимо для обложек. Не печатать свечение интерфейса. Номера, подписи и статусы должны читаться в чёрно-белом виде; сюжетные изображения сохраняют собственную стилистику.

Проверка изменённого экрана

  • На ширинах 375, 768 и 1280 px нет горизонтальной прокрутки всей страницы; таблица может прокручиваться локально.

  • Текст имеет контраст от 4.5:1; крупный текст и значимые границы управления — от 3:1. Проверять реальные пары цветов, в том числе hover и pressed.

  • Все действия доступны с клавиатуры; focus виден, окно закрывается и возвращает фокус на открывший его элемент.

  • Ошибка, успех, загрузка и пустое состояние различимы без цвета.

  • Логотип не деформирован; весь UI сайта использует font_old_typer, включая окна.

  • Компонентные стили локальны, глобальная тема изменяется только при осознанной миграции. Типы, ESLint и Stylelint проходят; изменения маршрутов проверены сборкой.

  • Переключение вкладок доступно с клавиатуры; сайт открывается первым.

  • Жёлтая тема сайта не меняет игровые кнопки и документы.

  • Игровой ход в образцах работает без сетевых запросов.

Подключение библиотеки

Компоненты находятся в src/components, импортируются напрямую и не зависят от dev-маршрута. Отдельного пакета и глобальной регистрации нет. Демонстрационные данные остаются в SiteDesignPreview, GameDesignPreview и ComponentDesignCatalog. Рабочие экраны пока не мигрируют.

<script setup lang="ts">
import { NButton, NCard } from 'naive-ui'
import SiteThemeProvider from '@/components/SiteThemeProvider.vue'
import CaseFolder from '@/components/CaseFolder.vue'

function openCase(title: string) {
  // Здесь родитель выполняет нужную навигацию или загрузку.
  console.log(title)
}
</script>

<template>
  <SiteThemeProvider>
    <NCard title="Материалы"><NButton type="primary">Открыть</NButton></NCard>
    <CaseFolder
      number="014"
      title="Последний поезд"
      description="Письмо и билет"
      quote="Не доверяй времени"
      object="ticket"
      cover-label="Материал 014 / Билет"
      cover-caption="23:40 · Вагон 03"
      @open="openCase"
    />
  </SiteThemeProvider>
</template>

Provider читает существующие CSS-токены при монтировании, задаёт darkTheme, цвета, машинописный шрифт и размеры Naive UI; кнопки, поля, таблицы и окна используются непосредственно из naive-ui. Телепортируемые окна сохраняют тему; для текста внутри NCard используйте машинописный шрифт на классе окна, как в каталоге. --site-card-padding позволяет контейнеру задавать поля карточек. Игровые компоненты размещайте вне provider сайта, под своим NConfigProvider :theme="darkTheme" :theme-overrides="{}".

Компонент Props Slots / события
SiteThemeProvider Нет default / нет
DesignBrand Нет Нет
CaseFolder number, title, description, quote, object: ticket/key/letter, coverLabel, coverCaption; status?, disabled=false, actionLabel='Открыть дело' Нет / open(title: string)
CaseBoard label, fragments: readonly массив { number, title, text, caption?, detail?, kind?: note/ticket/timetable }, footer? footer / нет
ObjectCover object: ticket/key/letter, label, caption, status? Нет
StatusStamp text? default заменяет text / нет
TextHighlight Нет default / нет
SectionHeading title, id?, eyebrow? default заменяет title / нет
DossierFooter label default / нет
MessagePaper Нет default / нет
HeaderText Нет default / нет
BeltBlock Нет default / нет
MetalPlate Нет default / нет
IntroBlock introduction: EditableIntroduction, mode: show/show-editor/edit default в режиме edit / update:mode
GameInputForm addAction: (code: string) => Promise, allPlacesCount, newPlacesCount, gameStatus Нет; true от addAction очищает поле

Статус папки необязателен и только показывает текст. Доступность задаёт родитель через disabled, подпись действия — через actionLabel. Событие open передаёт название; маршрутизация и API остаются у родителя. Каждая цитата получает уникальный Vue useId(), даже для повторных карточек одного дела.

Вкладки переключаются стрелками по кругу, Home открывает «Сайт», End — «Компоненты». Каталог показывает disabled, loading, ошибку и успешную форму, обрабатывает open локально и не отправляет запросы к серверу.