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:
Claude Opus 5
2026-08-12 23:42:20 +00:00
co-authored by Claude Opus 5
parent 71856b15e9
commit c857979a55
88 changed files with 3904 additions and 7463 deletions
+303
View File
@@ -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 (секция) | 1820px | 600 | `-0.03em` |
| Кнопка / линк | 14px | 600 | `-0.01em` |
| Body / инпут | 1415px | 400 | `-0.005em` |
| Лейбл поля | 11px | 600 | `+0.09em`, `uppercase` |
| Eyebrow / надзаголовок | 10px | 600 | `+0.20em`, `uppercase` |
| Метаданные | 1112px | 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 и **посмотреть глазами** до выката.