FiveRP: the server from the hosting account, not the earlier one
Wrong server was published before. This is the one that runs on the hosting account the video was made on: FiveRP - two-step registration (account, then an identity printed onto a passport), login that returns you to your resident, and a loading screen driven by the game's own streaming events. resources/[local]/fiverp-auth NUI + scrypt hashes + oxmysql resources/[local]/fiverp-characters identity, character load, spawn resources/[local]/fiverp-loadscreen loading screen sql/schema.sql accounts, characters docs/DESIGN.md the design system every screen follows docs/screens/ shot from the live server Only our own code is in here. cfx-server-data and oxmysql are fetched by install.sh instead of being vendored, which keeps the repo at 3.7 MB. install.sh does the whole box in one command: recommended FXServer build, cfx-server-data, oxmysql, MariaDB with the schema, resources, server.cfg (mode 600 - it carries the key and the database password), boot entry, then it waits for the Cfx registration. Tested end to end on a spare install root: 29 resources scanned, database and schema created, and it stopped exactly where a wrong licence key should stop it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
71856b15e9
commit
c857979a55
+303
@@ -0,0 +1,303 @@
|
||||
# FiveRP — Server Design System
|
||||
|
||||
Единый стиль для **всего** сервера: loading screen, авторизация, будущие меню
|
||||
(инвентарь, телефон, банк, HUD). Основан на белой «стеклянной» теме Filmorum
|
||||
(`fiveM_design.md`), адаптирован под CEF/NUI FiveM.
|
||||
|
||||
> Правило номер один: **ни один компонент не хардкодит цвет, радиус или шрифт.**
|
||||
> Только `var(--…)` из блока токенов ниже. Смена темы = одна строка.
|
||||
|
||||
---
|
||||
|
||||
## 0. Шрифт — Unbounded
|
||||
|
||||
**Unbounded — основной шрифт всего сервера.** Геометрический дисплейный гротеск,
|
||||
переменная ось веса 300–800. Никаких других сансов в интерфейсе.
|
||||
|
||||
Файлы лежат в каждом ресурсе локально (`html/fonts/`), а НЕ грузятся с
|
||||
`fonts.googleapis.com`: у части игроков CEF стартует раньше сети, и веб-шрифт
|
||||
успевает не приехать — интерфейс мигает системным шрифтом. Локальный woff2
|
||||
рисуется с первого кадра.
|
||||
|
||||
```css
|
||||
@font-face {
|
||||
font-family: 'Unbounded';
|
||||
font-style: normal;
|
||||
font-weight: 300 800; /* вариативный: один файл на все веса */
|
||||
font-display: block; /* block, не swap — подмены шрифта быть не должно */
|
||||
src: url('fonts/unbounded-latin.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
|
||||
U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* + unbounded-latin-ext.woff2 и unbounded-cyrillic.woff2 теми же блоками */
|
||||
```
|
||||
|
||||
```css
|
||||
--sans: 'Unbounded', -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
||||
Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
--mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas,
|
||||
'Liberation Mono', 'DejaVu Sans Mono', monospace;
|
||||
```
|
||||
|
||||
**Как набирать Unbounded.** Шрифт широкий и характерный — он требует другой
|
||||
типографики, чем SF Pro:
|
||||
|
||||
| Роль | Размер | Вес | Трекинг |
|
||||
|---|---|---|---|
|
||||
| Display (лого, экран загрузки) | 44–72px | 800 | `-0.04em` |
|
||||
| H1 (заголовок панели) | 26–30px | 700 | `-0.035em` |
|
||||
| H2 (секция) | 18–20px | 600 | `-0.03em` |
|
||||
| Кнопка / линк | 14px | 600 | `-0.01em` |
|
||||
| Body / инпут | 14–15px | 400 | `-0.005em` |
|
||||
| Лейбл поля | 11px | 600 | `+0.09em`, `uppercase` |
|
||||
| Eyebrow / надзаголовок | 10px | 600 | `+0.20em`, `uppercase` |
|
||||
| Метаданные | 11–12px | 400 | `0` |
|
||||
|
||||
Правила:
|
||||
- **Крупный кегль = минусовой трекинг.** У Unbounded широкие апроши; без
|
||||
`letter-spacing: -0.03em` заголовок расползается.
|
||||
- **Мелкий кегль = плюсовой трекинг + uppercase.** Ниже 12px строчные буквы
|
||||
Unbounded слипаются — все подписи только капслоком с разрядкой.
|
||||
- **Веса 300 и 800 — крайности**, в интерфейсе живут 400/500/600/700.
|
||||
- **Не набирать Unbounded длинный текст.** Абзац больше двух строк — читать
|
||||
тяжело. Для многострочных описаний кегль 13px/1.65 и вес 400, не больше.
|
||||
- **Цифры документов, ID, MRZ — только `--mono`.** Unbounded для них слишком
|
||||
«дизайнерский», а нужен вид машинного считывания.
|
||||
|
||||
---
|
||||
|
||||
## 1. Философия
|
||||
|
||||
- **Air, light, frosted** — полупрозрачные стеклянные панели поверх живой игры.
|
||||
- **Кислород** — между карточками 12px, между секциями 40–48px.
|
||||
- **Один акцент** — синий `#0071e3`, дозированно: кнопка, ссылка, фокус.
|
||||
- **Сдержанное движение** — fade и подъём на 4px. Анимации ради анимации нет.
|
||||
- **Один герой на экран** — крупный объект (паспорт, лого), остальное тихое.
|
||||
|
||||
---
|
||||
|
||||
## 2. Токены
|
||||
|
||||
```css
|
||||
:root {
|
||||
--bg: #f5f5f7;
|
||||
--bg-deep: #e8e8ed;
|
||||
--surface: rgba(255, 255, 255, 0.72);
|
||||
--surface-solid:#ffffff;
|
||||
--panel: rgba(255, 255, 255, 0.80);
|
||||
--header-bg: rgba(255, 255, 255, 0.70);
|
||||
--field-bg: rgba(0, 0, 0, 0.04);
|
||||
--field-bg-focus:#ffffff;
|
||||
|
||||
--fg: #1d1d1f;
|
||||
--fg-secondary: #6e6e73;
|
||||
--fg-tertiary: #a1a1a6;
|
||||
|
||||
--accent: #0071e3;
|
||||
--accent-strong:#0077ed;
|
||||
--accent-soft: rgba(0, 113, 227, 0.08);
|
||||
--ring: rgba(0, 113, 227, 0.18);
|
||||
|
||||
--line: rgba(0, 0, 0, 0.06);
|
||||
--line-strong: rgba(0, 0, 0, 0.10);
|
||||
--hover: rgba(0, 0, 0, 0.04);
|
||||
|
||||
--success: #34c759;
|
||||
--danger: #ff3b30;
|
||||
|
||||
--radius-lg: 1.5rem; /* 24px — крупные панели */
|
||||
--radius-md: 1rem; /* 16px — карточки, инпуты */
|
||||
--radius-sm: 0.7rem; /* 11px — мелочь */
|
||||
|
||||
--ease: cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
color-scheme: light;
|
||||
}
|
||||
```
|
||||
|
||||
Тёмная и бежевая темы — через `data-theme` на `html`, переопределением тех же
|
||||
токенов (`--bg`, `--surface`, `--fg`, `--accent`, `--success`, `--danger`).
|
||||
|
||||
---
|
||||
|
||||
## 3. КРИТИЧНО: особенности CEF во FiveM
|
||||
|
||||
Это не «хорошо бы», а условия, при нарушении которых интерфейс ломается
|
||||
в игре, оставаясь идеальным в браузере.
|
||||
|
||||
1. **`backdrop-filter` и `box-shadow` не живут на одном элементе.**
|
||||
Композитор CEF рисует тень такого элемента непрозрачным прямоугольником —
|
||||
в игре под панелью появляется чёрный квадрат. Если нужны и блюр, и тень —
|
||||
тень вешать на элемент-обёртку, а блюр на внутренний. По умолчанию
|
||||
**у стеклянных панелей тени нет вообще**: их отделяет от игры блюр и
|
||||
светлая граница, этого достаточно.
|
||||
|
||||
2. **`html, body { background: transparent }`** — иначе NUI закрашивает игру.
|
||||
|
||||
3. **Никаких затемняющих подложек.** Экран за панелью — это игра, её видно
|
||||
и она красивая. Контраст добирается блюром и белой заливкой стекла, а не
|
||||
`rgba(0,0,0,…)` поверх кадра. Допустим только **осветляющий** вуаль:
|
||||
`radial-gradient(…, rgba(255,255,255,0.28), transparent)`.
|
||||
|
||||
4. **Шрифты — локальные woff2.** См. раздел 0.
|
||||
|
||||
5. **`prefers-reduced-motion`** — обязательный блок с самого начала.
|
||||
|
||||
6. **Курсор и фокус** — `SetNuiFocus(true, true)` только когда панель открыта,
|
||||
и обязательно `SetNuiFocus(false, false)` при закрытии, иначе игрок
|
||||
остаётся без управления.
|
||||
|
||||
---
|
||||
|
||||
## 4. Стеклянная панель
|
||||
|
||||
```css
|
||||
.glass {
|
||||
background: var(--surface);
|
||||
backdrop-filter: saturate(180%) blur(24px);
|
||||
-webkit-backdrop-filter: saturate(180%) blur(24px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.55);
|
||||
border-radius: var(--radius-lg);
|
||||
/* без box-shadow — см. раздел 3.1 */
|
||||
}
|
||||
```
|
||||
|
||||
Тень разрешена только элементам **без** `backdrop-filter` (карточки на
|
||||
непрозрачном фоне, экран загрузки):
|
||||
|
||||
```css
|
||||
.shadow-soft { box-shadow: 0 1px 2px rgba(0,0,0,.03), 0 12px 40px -12px rgba(0,0,0,.12); }
|
||||
.shadow-lift { box-shadow: 0 2px 4px rgba(0,0,0,.04), 0 24px 50px -16px rgba(0,0,0,.20); }
|
||||
```
|
||||
|
||||
Ховер кликабельной карточки: `transform: translateY(-4px)`, 0.4s `--ease`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Кнопки
|
||||
|
||||
```css
|
||||
.btn-primary {
|
||||
border-radius: 999px;
|
||||
padding: 12px 24px;
|
||||
font: 600 14px var(--sans);
|
||||
letter-spacing: -0.01em;
|
||||
color: #fff;
|
||||
background-image: linear-gradient(180deg, var(--accent-strong), var(--accent));
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.20);
|
||||
}
|
||||
.btn-primary:hover { filter: brightness(1.08); }
|
||||
.btn-primary:active { transform: scale(0.97); }
|
||||
.btn-primary:disabled { opacity: .5; pointer-events: none; }
|
||||
|
||||
.btn-ghost {
|
||||
border-radius: 999px;
|
||||
padding: 10px 20px;
|
||||
font: 600 14px var(--sans);
|
||||
color: var(--accent);
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
.btn-ghost:hover { background: rgba(0,113,227,.14); }
|
||||
```
|
||||
|
||||
Ровно два стиля кнопок на весь сервер. Третий не заводить.
|
||||
|
||||
---
|
||||
|
||||
## 6. Поля ввода
|
||||
|
||||
```css
|
||||
.field {
|
||||
width: 100%;
|
||||
border-radius: var(--radius-md);
|
||||
padding: 13px 14px;
|
||||
font: 400 15px var(--sans);
|
||||
letter-spacing: -0.005em;
|
||||
color: var(--fg);
|
||||
background: var(--field-bg);
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
transition: background-color .2s, border-color .2s, box-shadow .2s;
|
||||
}
|
||||
.field::placeholder { color: var(--fg-tertiary); }
|
||||
.field:focus {
|
||||
background: var(--field-bg-focus);
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 4px var(--ring); /* можно: у инпута нет backdrop-filter */
|
||||
}
|
||||
.field.is-bad { border-color: var(--danger); box-shadow: 0 0 0 4px rgba(255,59,48,.14); }
|
||||
```
|
||||
|
||||
Лейбл над полем — 11px/600/`+0.09em`/uppercase/`--fg-secondary`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Компоновка
|
||||
|
||||
- Панель по центру экрана, ширина `min(940px, 92vw)`, радиус `--radius-lg`.
|
||||
- Внутренние отступы панели 32–40px.
|
||||
- Между полями формы 16px, между группами 24px.
|
||||
- Двухколоночная схема «форма + герой»: `grid-template-columns: minmax(0,1fr) 420px`.
|
||||
- Сворачивание в одну колонку — анимацией `grid-template-columns` и `width`,
|
||||
620ms `--ease`.
|
||||
|
||||
---
|
||||
|
||||
## 8. Motion
|
||||
|
||||
```css
|
||||
.fade-up { animation: fadeUp .6s cubic-bezier(.22,1,.36,1) both; }
|
||||
.delay-1 { animation-delay: .06s } .delay-2 { animation-delay: .12s }
|
||||
.delay-3 { animation-delay: .18s } .delay-4 { animation-delay: .24s }
|
||||
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(18px) scale(.995); filter: blur(6px); }
|
||||
to { opacity: 1; transform: none; filter: blur(0); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: .001ms !important;
|
||||
transition-duration: .001ms !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Фокус и доступность
|
||||
|
||||
```css
|
||||
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
|
||||
::selection { background: var(--accent-soft); color: var(--accent-strong); }
|
||||
```
|
||||
|
||||
Контраст текста к стеклу — не ниже 4.5:1. `--fg-tertiary` только для
|
||||
плейсхолдеров и декоративных подписей, никогда для смысловых.
|
||||
|
||||
---
|
||||
|
||||
## 10. Существующие интерфейсы
|
||||
|
||||
| Ресурс | Что это | Файлы |
|
||||
|---|---|---|
|
||||
| `fiverp-loadscreen` | экран загрузки сервера | `html/index.html`, `style.css`, `app.js` |
|
||||
| `fiverp-auth` | регистрация и вход, паспорт США | `html/index.html`, `style.css`, `app.js` |
|
||||
|
||||
`fiverp-auth` использует один «герой» — разворот паспорта США (страница с
|
||||
данными: фото, поля, MRZ). Паспорт — единственный насыщенный цветом объект
|
||||
на экране; форма рядом с ним остаётся полностью нейтральной.
|
||||
|
||||
---
|
||||
|
||||
## 11. Чек-лист нового интерфейса
|
||||
|
||||
1. Скопировать `html/fonts/` и блок `:root` из `fiverp-auth`.
|
||||
2. `html, body { background: transparent }`.
|
||||
3. Панель — `.glass`, **без** `box-shadow`.
|
||||
4. Ни одного затемняющего слоя поверх игры.
|
||||
5. Шрифт Unbounded, трекинг по таблице из раздела 0.
|
||||
6. Акцент только `--accent`; кнопки только `.btn-primary` / `.btn-ghost`.
|
||||
7. Подключить `prefers-reduced-motion`.
|
||||
8. `SetNuiFocus(false, false)` на закрытии — проверить руками.
|
||||
9. Отрендерить в headless Chrome и **посмотреть глазами** до выката.
|
||||
Reference in New Issue
Block a user