feat: Forge design system app-wide + Stacks i18n
Build / build (push) Successful in 10m47s

Promotes the Forge visual language from the Stacks feature into a
global design system used across the app:

- app.css: Forge utilities (dot-grid backdrop, eyebrow, ember,
  display/lede, status pills, stat grid, panels, registration
  marks, alert, terminal, buttons). CSS variables alias the forge
  display font to the app's standard sans stack (Inter, now
  properly self-hosted via @fontsource/inter).
- +layout.svelte: reskinned sidebar brand, active nav rail,
  mobile top bar, global h1/h2 typography overrides, main dot-grid
  backdrop.
- Shared components reskinned: EmptyState (breathing-ember empty
  mark), StatusBadge (mono pills with pulse), ConfirmDialog
  (registration marks + forge buttons).
- Dashboard (+page.svelte): ForgeHero header, forge-stat-grid,
  Instrument-style section titles with accent.
- New ForgeHero component for reusable hero headers.

Stacks feature fully localized (EN + RU):
- 80+ keys under stacks.* covering list, new, detail, revisions,
  logs, errors, status labels, delete/rollback dialogs.
- Russian uses forge vocabulary (куются/наковальня/куём/etc).
- $t() wired through all three Stacks pages.
This commit is contained in:
2026-04-16 04:17:42 +03:00
parent 75424a5f25
commit 0fd92fdfa3
14 changed files with 1251 additions and 343 deletions
+122
View File
@@ -890,5 +890,127 @@
"language": {
"en": "Английский",
"ru": "Русский"
},
"stacks": {
"eyebrow": "КУЗНИЦА",
"title": "Стеки",
"lede": "Compose-чертежи, выкованные как <em>атомарные единицы</em>. Запускайте сервисы, меняйте ревизии и откатывайтесь без нервов.",
"newStack": "Новый стек",
"refresh": "Обновить",
"total": "Всего",
"running": "Работают",
"deploying": "Куются",
"failed": "Сбой",
"stopped": "Холодные",
"empty": {
"title": "Наковальня остыла.",
"desc": "Загрузите docker-compose.yml, чтобы выковать первый стек."
},
"card": {
"noDescription": "Без описания",
"updated": "Обновлён",
"start": "Запустить",
"stop": "Остановить",
"delete": "Удалить",
"open": "Открыть"
},
"new": {
"eyebrow": "НОВЫЙ ЧЕРТЁЖ",
"title": "Выковать новый стек.",
"lede": "Загрузите или вставьте <code>docker-compose.yml</code>. Все сервисы чертежа разворачиваются как одна атомарная единица.",
"back": "Стеки",
"name": "Имя",
"namePlaceholder": "мой-стек",
"nameHint": "Строчные буквы, через дефис. Используется как имя compose-проекта.",
"description": "Описание",
"descriptionPlaceholder": "Что делает этот стек?",
"composeYaml": "Compose YAML",
"required": "обязательно",
"optional": "необязательно",
"loadSample": "Загрузить пример",
"uploadFile": "Загрузить файл",
"dropHere": "Перетащите сюда docker-compose.yml",
"dropSub": "или нажмите для выбора · или используйте <strong>Загрузить пример</strong> выше",
"lines": "{n} строк",
"bytes": "{n} байт",
"clear": "Очистить",
"deployImmediate": "Развернуть сразу",
"deployHint": "Куй железо, пока горячо. Без галочки стек сохраняется холодным.",
"cancel": "Отмена",
"forging": "Куём…",
"forgeAndDeploy": "Выковать и развернуть",
"saveBlueprint": "Сохранить чертёж",
"errorRequired": "Имя и compose YAML обязательны.",
"errorCreate": "Не удалось создать стек"
},
"detail": {
"manifest": "МАНИФЕСТ",
"loading": "Загрузка чертежа…",
"composeProject": "COMPOSE-ПРОЕКТ",
"noDescription": "Без описания",
"refresh": "Обновить",
"start": "Запустить",
"stop": "Остановить",
"delete": "Удалить",
"fault": "СБОЙ",
"err": "ОШБ",
"stats": {
"services": "Сервисы",
"servicesSub": "в чертеже",
"running": "Работают",
"runningSub": "активных контейнеров",
"revisions": "Ревизии",
"revisionsSub": "в истории",
"current": "Текущая",
"currentSub": "развёрнута"
},
"services": {
"title": "Сервисы",
"count": "{n} в работе",
"empty": "— нет запущенных контейнеров —"
},
"tabs": {
"blueprint": "Чертёж",
"revisions": "Ревизии",
"logs": "Логи"
},
"yaml": {
"currentRevision": "Текущая ревизия",
"edit": "Править и развернуть",
"cancel": "Отмена",
"forging": "Куём…",
"deployNew": "Развернуть новую ревизию"
},
"revisions": {
"current": "ТЕКУЩАЯ",
"by": "автор",
"rollback": "← Откатиться к этой ревизии",
"rollbackTitle": "Откатить ревизию?",
"rollbackMessage": "Создать новую ревизию из rev {n} и развернуть стек заново.",
"rollbackConfirm": "Откатить"
},
"logs": {
"service": "Сервис:",
"allServices": "Все сервисы",
"fetching": "Загрузка…",
"fetch": "Получить логи",
"empty": "— логи не загружены. нажмите получить. —"
},
"delete": {
"title": "Удалить стек?",
"messageBase": "Будет выполнен 'docker compose down' и удалён \"{name}\".",
"messageVolumes": " Именованные тома также будут удалены.",
"confirm": "Удалить"
},
"errors": {
"load": "Не удалось загрузить стек",
"stop": "Остановка не удалась",
"start": "Запуск не удался",
"update": "Обновление не удалось",
"rollback": "Откат не удался",
"delete": "Удаление не удалось",
"fetchLogs": "Не удалось загрузить логи"
}
}
}
}