package main

// translations — таблица переводов "ключ -> {ru, en}". Заполняется
// по мере перевода каждого файла интерфейса; см. i18n.go для
// функций T/Tf, которые ей пользуются.
var translations = map[string]translationEntry{
	// --- Экран выбора языка ---
	"lang.title": {"=== ВЫБОР ЯЗЫКА ===", "=== CHOOSE LANGUAGE ==="},
	"lang.ru":    {"Русский", "Русский (Russian)"},
	"lang.en":    {"English", "English"},
	"lang.hint":  {"[↑↓/kj] выбор   [enter] подтвердить", "[↑↓/kj] select   [enter] confirm"},

	// --- Общее меню ---
	"app.subtitle":       {"Коллекция консольных игр на Go", "A console collection of card and board games in Go"},
	"menu.hint":          {"[↑↓/kj] выбор   [enter] подтвердить   [q] выход", "[↑↓/kj] select   [enter] confirm   [q] quit"},
	"menu.rules":         {"Правила", "Rules"},
	"menu.rules_desc":    {"Прочитать правила выбранной игры", "Read the rules of a chosen game"},
	"menu.language":      {"Язык / Language", "Язык / Language"},
	"menu.language_desc": {"Сменить язык интерфейса", "Change interface language"},
	"menu.quit":          {"Выход", "Quit"},
	"menu.quit_desc":     {"Закрыть коллекцию игр", "Close the game collection"},

	// --- Реестр игр: названия и описания ---
	"game.tonk.name":     {"Тонк (Tonk)", "Tonk"},
	"game.tonk.desc":     {"Карточная игра на 1 человека + 3 бота разного уровня сложности", "Card game for 1 human + 3 bots of varying skill"},
	"game.durak.name":    {"Дурак (Durak)", "Durak (Russian Fool)"},
	"game.durak.desc":    {"Классическая карточная игра на 2-6 игроков (подкидной вариант)", "Classic card game for 2-6 players (full throw-in variant)"},
	"game.bj.name":       {"Блэкджек (Blackjack)", "Blackjack"},
	"game.bj.desc":       {"Каждый играет против дилера, 1-6 игроков включая человека", "Everyone plays the dealer separately, 1-6 players including you"},
	"game.101.name":      {"101", "101"},
	"game.101.desc":      {"Избавьтесь от карт первым; штрафные очки за оставшиеся на руках, до 101 — выбывание", "Empty your hand first; penalty points for cards left in hand, reaching 101 eliminates you"},
	"game.1000.name":     {"1000 (Тысяча)", "1000 (Thousand)"},
	"game.1000.desc":     {"Взяточная игра с торгами и марьяжами, строго на троих (вы + 2 бота)", "Trick-taking game with bidding and marriages, strictly 3 players (you + 2 bots)"},
	"game.klondike.name": {"Косынка (Klondike)", "Klondike Solitaire"},
	"game.klondike.desc": {"Классический пасьянс на одного игрока, без ботов", "Classic single-player solitaire, no bots"},
	"game.checkers.name": {"Шашки (Checkers)", "Checkers"},
	"game.checkers.desc": {"Русские шашки против бота (минимакс), обязательное взятие", "Russian draughts against a minimax bot, mandatory captures"},

	// --- Подменю "Правила" и сам экран правил ---
	"rulesmenu.title":   {"=== ПРАВИЛА: ВЫБЕРИТЕ ИГРУ ===", "=== RULES: CHOOSE A GAME ==="},
	"rulesmenu.hint":    {"[↑↓/kj] выбор   [enter] показать правила   [esc/q] назад в меню", "[↑↓/kj] select   [enter] show rules   [esc/q] back to menu"},
	"rules.title":       {"=== ПРАВИЛА ===", "=== RULES ==="},
	"rules.hint":        {"[↑↓/kj] строка   [pgup/pgdown] страница   [g/G] начало/конец   [esc/q] назад", "[↑↓/kj] line   [pgup/pgdown] page   [g/G] start/end   [esc/q] back"},
	"rules.scroll_info": {"(строки %d-%d из %d)", "(lines %d-%d of %d)"},

	// --- Настройка ставки (Тонк) ---
	"stake.title":     {"НАСТРОЙКА СТАВКИ", "STAKE SETUP"},
	"stake.capital":   {"Стартовый капитал", "Starting capital"},
	"stake.ante":      {"Ставка (анте) за раунд", "Ante per round"},
	"stake.tonk_mult": {"Множитель банка при Тонке", "Tonk pot multiplier"},
	"stake.pot_info":  {"Банк на 4 игроков", "Pot for 4 players"},
	"stake.tonk_win":  {"Победа Тонком", "Tonk win"},
	"stake.hint":      {"[↑↓/kj] поле   [←→/hl] изменить значение   [enter] начать игру   [esc/q] назад", "[↑↓/kj] field   [←→/hl] change value   [enter] start game   [esc/q] back"},

	// --- Выбор числа игроков (Дурак, 101) ---
	"playercount.title": {"ЧИСЛО ИГРОКОВ", "NUMBER OF PLAYERS"},
	"playercount.line":  {"игроков (включая вас)", "players (including you)"},
	"playercount.bots":  {"Вы + %d бот(ов) со случайными именами.", "You + %d bot(s) with random names."},
	"playercount.hint":  {"[←→/hl] изменить число игроков (2-6)   [enter] начать игру   [esc/q] назад", "[←→/hl] change player count (2-6)   [enter] start game   [esc/q] back"},

	// --- Настройка Блэкджека ---
	"bjsettings.title":   {"НАСТРОЙКА", "SETUP"},
	"bjsettings.players": {"Число игроков (включая вас)", "Number of players (including you)"},
	"bjsettings.capital": {"Стартовый капитал", "Starting capital"},
	"bjsettings.bet":     {"Ставка за раунд", "Bet per round"},
	"bjsettings.multi":   {"Вы + %d бот(ов) со случайными именами, каждый играет против дилера отдельно.", "You + %d bot(s) with random names, each playing the dealer separately."},
	"bjsettings.solo":    {"Вы играете в одиночку против дилера.", "You play solo against the dealer."},
	"bjsettings.hint":    {"[↑↓/kj] поле   [←→/hl] изменить значение   [enter] начать игру   [esc/q] назад", "[↑↓/kj] field   [←→/hl] change value   [enter] start game   [esc/q] back"},

	// --- Уровень сложности (Шашки) ---
	"checkerslvl.title":       {"УРОВЕНЬ СЛОЖНОСТИ", "DIFFICULTY LEVEL"},
	"checkerslvl.field_label": {"Сложность бота", "Bot difficulty"},
	"checkerslvl.hint":        {"[↑↓/←→] выбор уровня   [enter] начать игру   [esc/q] назад", "[↑↓/←→] choose level   [enter] start game   [esc/q] back"},
	"color.white":             {"Белые", "White"},
	"color.black":             {"Чёрные", "Black"},
	"color.random":            {"Случайно", "Random"},
	"color.field_label":       {"Ваш цвет", "Your color"},
	"checkerslvl.easy":        {"Простой", "Easy"},
	"checkerslvl.easy_desc":   {"быстрый, ощутимо слабее", "fast, noticeably weaker"},
	"checkerslvl.hard":        {"Сильный", "Strong"},
	"checkerslvl.hard_desc":   {"заметно сильнее, чуть медленнее думает", "noticeably stronger, thinks a bit slower"},

	"tictactoelvl.title":       {"УРОВЕНЬ СЛОЖНОСТИ", "DIFFICULTY LEVEL"},
	"tictactoelvl.easy":        {"Лёгкий", "Easy"},
	"tictactoelvl.easy_desc":   {"ходит совершенно случайно", "moves completely at random"},
	"tictactoelvl.medium":      {"Средний", "Medium"},
	"tictactoelvl.medium_desc": {"не упустит свою победу и заблокирует вашу", "won't miss its own win or let you win either"},
	"tictactoelvl.hard":        {"Непобедимый", "Unbeatable"},
	"tictactoelvl.hard_desc":   {"полный перебор — выиграть у него нельзя, можно только сыграть вничью", "full search — you can't beat it, only draw at best"},

	"nardysettings.title":         {"НАСТРОЙКИ ПАРТИИ", "GAME SETTINGS"},
	"nardysettings.variant":       {"Вариант правил", "Rule variant"},
	"nardysettings.difficulty":    {"Сложность бота", "Bot difficulty"},
	"nardysettings.variant.short": {"Короткие", "Short"},
	"nardysettings.variant.long":  {"Длинные", "Long"},
	"nardylvl.easy":               {"Лёгкий", "Easy"},
	"nardylvl.easy_desc":          {"случайные ходы среди легальных", "random legal moves"},
	"nardylvl.medium":             {"Средний", "Medium"},
	"nardylvl.medium_desc":        {"жадная оценка каждого отдельного хода", "greedily evaluates each single move"},
	"nardylvl.hard":               {"Сильный", "Strong"},
	"nardylvl.hard_desc":          {"перебирает весь ход целиком, оценивая итоговую позицию", "searches the whole turn, evaluating the resulting position"},

	"urlvl.easy":        {"Лёгкий", "Easy"},
	"urlvl.easy_desc":   {"случайные ходы среди легальных", "random legal moves"},
	"urlvl.medium":      {"Средний", "Medium"},
	"urlvl.medium_desc": {"жадная оценка результата каждого хода", "greedily evaluates the outcome of each move"},
	"urlvl.hard":        {"Сильный", "Strong"},
	"urlvl.hard_desc":   {"вдобавок учитывает риск немедленного взятия соперником", "also accounts for the risk of an immediate capture by the opponent"},

	"senetlvl.easy":        {"Лёгкий", "Easy"},
	"senetlvl.easy_desc":   {"случайные ходы среди легальных", "random legal moves"},
	"senetlvl.medium":      {"Средний", "Medium"},
	"senetlvl.medium_desc": {"жадная оценка результата каждого хода", "greedily evaluates the outcome of each move"},
	"senetlvl.hard":        {"Сильный", "Strong"},
	"senetlvl.hard_desc":   {"вдобавок учитывает риск немедленного взятия соперником", "also accounts for the risk of an immediate capture by the opponent"},

	// --- Сообщения об ошибках движков (ключ — сам русский текст,
	// возвращаемый err.Error(); переводится в момент отображения в
	// TUI через T(err.Error()), сами errors.New(...) не трогаем,
	// чтобы не сломать сравнения ошибок по идентичности в тестах) ---
	"в исходной стопке нет карт":                                            {"в исходной стопке нет карт", "no cards in the source pile"},
	"вес руки превышает порог объявления Тонка":                             {"вес руки превышает порог объявления Тонка", "hand value exceeds the Tonk declaration threshold"},
	"доступно взятие — простой ход запрещён":                                {"доступно взятие — простой ход запрещён", "a capture is available — a simple move is not allowed"},
	"карту нельзя подложить к этой комбинации":                              {"карту нельзя подложить к этой комбинации", "this card can't be added to that combination"},
	"карты не образуют валидную комбинацию":                                 {"карты не образуют валидную комбинацию", "these cards don't form a valid combination"},
	"карты нет на руке игрока":                                              {"карты нет на руке игрока", "that card isn't in the player's hand"},
	"колода и сброс исчерпаны — раунд закончен вничью":                      {"колода и сброс исчерпаны — раунд закончен вничью", "stock and discard pile are exhausted — the round ends in a draw"},
	"комбинация на столе не найдена":                                        {"комбинация на столе не найдена", "combination not found on the table"},
	"на столе нет карт":                                                     {"на столе нет карт", "there are no cards on the table"},
	"на столе нет карты, которую нужно отбивать":                            {"на столе нет карты, которую нужно отбивать", "there's no card on the table to beat"},
	"на фундамент можно положить только одну карту":                         {"на фундамент можно положить только одну карту", "only one card can be moved to a foundation"},
	"на этой клетке нет вашей шашки":                                        {"на этой клетке нет вашей шашки", "you don't have a piece on that square"},
	"недопустимое действие для текущей фазы":                                {"недопустимое действие для текущей фазы", "this action isn't allowed in the current phase"},
	"недопустимое действие для текущей фазы хода":                           {"недопустимое действие для текущей фазы хода", "this action isn't allowed in the current turn phase"},
	"недостаточно средств для этого действия":                               {"недостаточно средств для этого действия", "not enough funds for this action"},
	"такой ход сейчас недопустим":                                           {"такой ход сейчас недопустим", "that move isn't legal right now"},
	"сначала нужно бросить кости":                                           {"сначала нужно бросить кости", "you need to roll the dice first"},
	"кости в этом ходу уже брошены":                                         {"кости в этом ходу уже брошены", "the dice have already been rolled this turn"},
	"нечего отменять":                                                       {"нечего отменять", "nothing to undo"},
	"нужно продолжать бить той же шашкой":                                   {"нужно продолжать бить той же шашкой", "you must continue capturing with the same piece"},
	"нужно сыграть карту, которая подходит — брать из колоды нельзя":        {"нужно сыграть карту, которая подходит — брать из колоды нельзя", "you must play a matching card — drawing from the stock isn't allowed"},
	"нужно ходить в масть или козырем, если они есть на руке":               {"нужно ходить в масть или козырем, если они есть на руке", "you must follow suit or play trump if you have one"},
	"клетка уже занята":                                                     {"клетка уже занята", "that cell is already taken"},
	"недопустимый номер клетки":                                             {"недопустимый номер клетки", "invalid cell number"},
	"партия уже завершена":                                                  {"партия уже завершена", "the match is already over"},
	"первый ходящий обязан назвать ставку не менее 100 и не может пасовать": {"первый ходящий обязан назвать ставку не менее 100 и не может пасовать", "the first bidder must bid at least 100 and cannot pass"},
	"сейчас не ваш ход":                                                     {"сейчас не ваш ход", "it isn't your turn right now"},
	"нельзя пасовать (чек) — на столе уже есть ставка, которую нужно уравнять или сбросить": {"нельзя пасовать (чек) — на столе уже есть ставка, которую нужно уравнять или сбросить", "you can't check — there's already a bet on the table that must be called or folded"},
	"ставка меньше минимально допустимой":                                                   {"ставка меньше минимально допустимой", "the bet is below the minimum allowed"},
	"недостаточно фишек для такой ставки":                                                   {"недостаточно фишек для такой ставки", "not enough chips for that bet"},
	"ставка должна быть выше текущей минимум на 5":                                          {"ставка должна быть выше текущей минимум на 5", "the bid must be at least 5 higher than the current one"},
	"играть втёмную можно только на самом первом ходе торгов":                               {"играть втёмную можно только на самом первом ходе торгов", "playing blind is only possible on the very first bidding turn"},
	"ставка превышает разрешённый максимум (120 плюс марьяж на руке)":                       {"ставка превышает разрешённый максимум (120 плюс марьяж на руке)", "the bid exceeds the allowed maximum (120 plus any marriage in hand)"},
	"стопка сброса пуста":                                                                   {"стопка сброса пуста", "the discard pile is empty"},
	"такой ход недопустим":                                                                  {"такой ход недопустим", "that move isn't allowed"},
	"удвоить ставку можно только на первых двух картах":                                     {"удвоить ставку можно только на первых двух картах", "you can only double down on your first two cards"},
	"уже отдано нужное количество карт":                                                     {"уже отдано нужное количество карт", "the required number of cards has already been passed"},
	"эта карта (или последовательность под ней) не может быть перемещена":                   {"эта карта (или последовательность под ней) не может быть перемещена", "this card (or the sequence under it) can't be moved"},
	"эта карта не бьёт атакующую карту":                                                     {"эта карта не бьёт атакующую карту", "this card doesn't beat the attacking card"},
	"эта карта не подходит по масти или рангу":                                              {"эта карта не подходит по масти или рангу", "this card doesn't match by suit or rank"},
	"эту карту нельзя подкинуть: не тот ранг или лимит атаки исчерпан":                      {"эту карту нельзя подкинуть: не тот ранг или лимит атаки исчерпан", "this card can't be thrown in: wrong rank or the attack limit is reached"},
	"эту карту нельзя положить в эту колонну":                                               {"эту карту нельзя положить в эту колонну", "this card can't be placed in that column"},
	"эту карту нельзя положить на фундамент":                                                {"эту карту нельзя положить на фундамент", "this card can't be placed on the foundation"},

	// --- Общие ключи, используемые в нескольких играх ---
	"common.you":              {"Вы", "You"},
	"common.you_suffix":       {" (вы)", " (you)"},
	"common.goodbye":          {"До встречи!\n", "See you!\n"},
	"common.your_hand":        {"Ваша рука:", "Your hand:"},
	"common.thinking":         {"%s думает...\n", "%s is thinking...\n"},
	"common.thinking_generic": {"Бот думает...", "The bot is thinking..."},

	"nardy.title.short":        {"=== КОРОТКИЕ НАРДЫ ===", "=== SHORT NARDY (BACKGAMMON) ==="},
	"nardy.title.long":         {"=== ДЛИННЫЕ НАРДЫ ===", "=== LONG NARDY ==="},
	"nardy.bar_off_line":       {"Бар — %s:%d  %s:%d     Снято — %s:%d  %s:%d", "Bar — %s:%d  %s:%d     Borne off — %s:%d  %s:%d"},
	"nardy.you_are":            {"Вы играете за: %s", "You are playing as: %s"},
	"nardy.hint.roll":          {"[r/enter] бросить кости", "[r/enter] roll the dice"},
	"nardy.hint.pick_source":   {"Выберите, с какой точки ходить:", "Choose which point to move from:"},
	"nardy.hint.pick_die":      {"Выберите кость для этого хода:", "Choose which die to use:"},
	"nardy.hint.cancel_source": {"[esc] назад к выбору точки", "[esc] back to point selection"},
	"nardy.source_bar":         {"с бара", "from the bar"},
	"nardy.hint.quit":          {"[q] в меню", "[q] to menu"},
	"nardy.dice_line":          {"Кости: %d, %d   (осталось: %s)", "Dice: %d, %d   (remaining: %s)"},
	"nardy.move_label":         {"%s → %s (кость %d)", "%s → %s (die %d)"},
	"nardy.outcome.win":        {"Вы выиграли!", "You won!"},
	"nardy.outcome.lose":       {"Бот выиграл.", "The bot won."},
	"nardy.msg.bot_moved":      {"Бот сходил.", "The bot made a move."},
	"nardy.msg.no_legal_moves": {"У вас не нашлось ни одного хода — очки сгорели.", "You had no legal moves — the roll is forfeited."},
	"nardy.msg.game_over":      {"Партия завершена.", "The game is over."},

	"ur.title":              {"=== ИГРА УР (ROYAL GAME OF UR) ===", "=== THE ROYAL GAME OF UR ==="},
	"ur.you_are":            {"Вы играете за: %s", "You are playing as: %s"},
	"ur.hand":               {"рука", "hand"},
	"ur.off":                {"снятие", "off"},
	"ur.hand_off_line":      {"В руке — %s:%d  %s:%d     Снято — %s:%d  %s:%d", "In hand — %s:%d  %s:%d     Borne off — %s:%d  %s:%d"},
	"ur.hint.roll":          {"[r/enter] бросить кости", "[r/enter] roll the dice"},
	"ur.hint.pick_move":     {"Выберите ход:", "Choose a move:"},
	"ur.hint.no_moves":      {"Нет легальных ходов — ход переходит сопернику.", "No legal moves — turn passes to the opponent."},
	"ur.hint.quit":          {"[q] в меню", "[q] to menu"},
	"ur.dice_line":          {"Кости: %d", "Dice: %d"},
	"ur.move_label":         {"%s → %s", "%s → %s"},
	"ur.outcome.win":        {"Вы выиграли!", "You won!"},
	"ur.outcome.lose":       {"Бот выиграл.", "The bot won."},
	"ur.msg.bot_moved":      {"Бот сходил.", "The bot made a move."},
	"ur.msg.no_legal_moves": {"У вас не нашлось ни одного хода.", "You had no legal moves."},
	"ur.msg.game_over":      {"Партия завершена.", "The game is over."},

	"senet.title":              {"=== СЕНЕТ (SENET) ===", "=== SENET ==="},
	"senet.you_are":            {"Вы играете за: %s", "You are playing as: %s"},
	"senet.off":                {"снятие", "off"},
	"senet.backward":           {"(назад)", "(backward)"},
	"senet.off_line":           {"Снято — %s:%d  %s:%d", "Borne off — %s:%d  %s:%d"},
	"senet.hint.roll":          {"[r/enter] бросить палочки", "[r/enter] throw the sticks"},
	"senet.hint.pick_move":     {"Выберите ход:", "Choose a move:"},
	"senet.hint.no_moves":      {"Нет легальных ходов — ход переходит сопернику.", "No legal moves — turn passes to the opponent."},
	"senet.hint.quit":          {"[q] в меню", "[q] to menu"},
	"senet.dice_line":          {"Бросок: %d", "Throw: %d"},
	"senet.move_label":         {"%d → %s%s", "%d → %s%s"},
	"senet.outcome.win":        {"Вы выиграли!", "You won!"},
	"senet.outcome.lose":       {"Бот выиграл.", "The bot won."},
	"senet.msg.bot_moved":      {"Бот сходил.", "The bot made a move."},
	"senet.msg.no_legal_moves": {"У вас не нашлось ни одного хода.", "You had no legal moves."},
	"senet.msg.game_over":      {"Партия завершена.", "The game is over."},

	"poker.title":                    {"=== ТЕХАССКИЙ ХОЛДЕМ ===", "=== TEXAS HOLD'EM ==="},
	"poker.board_label":              {"Стол:", "Board:"},
	"poker.pot_line":                 {"Банк: %d", "Pot: %d"},
	"poker.your_hand_label":          {"Ваши карты:", "Your hand:"},
	"poker.seat_label":               {"Игрок %d", "Player %d"},
	"poker.you_label":                {"Вы", "You"},
	"poker.player_line":              {"%-12s фишки: %-6d ставка: %-6d %s", "%-12s chips: %-6d bet: %-6d %s"},
	"poker.status.folded":            {"[сбросил]", "[folded]"},
	"poker.status.allin":             {"[олл-ин]", "[all-in]"},
	"poker.status.eliminated":        {"[выбыл]", "[eliminated]"},
	"poker.hint.your_turn":           {"Ваш ход:", "Your turn:"},
	"poker.hint.next_hand":           {"[n/enter] следующая раздача", "[n/enter] next hand"},
	"poker.hint.bet_amount":          {"[←→/hl] крупный шаг   [↑↓/kj] мелкий шаг   [enter] подтвердить   [esc] отмена", "[←→/hl] big step   [↑↓/kj] small step   [enter] confirm   [esc] cancel"},
	"poker.hint.quit":                {"[q] в меню", "[q] to menu"},
	"poker.bet_amount_line":          {"Ставка/рейз: %d", "Bet/raise: %d"},
	"poker.action.fold":              {"Сбросить карты", "Fold"},
	"poker.action.check":             {"Чек", "Check"},
	"poker.action.call":              {"Уравнять", "Call"},
	"poker.action.bet":               {"Поставить/рейз", "Bet/raise"},
	"poker.action.allin":             {"Ва-банк (олл-ин)", "All-in"},
	"poker.showdown.title":           {"Вскрытие карт:", "Showdown:"},
	"poker.showdown.fold_title":      {"Все соперники сбросили карты.", "All opponents folded."},
	"poker.showdown.winner_line":     {"  %s забирает: %d", "  %s wins: %d"},
	"poker.showdown.winner_line_you": {"  Вы забираете: %d", "  You win: %d"},
	"poker.outcome.win":              {"Вы выиграли турнир!", "You won the tournament!"},
	"poker.outcome.lose":             {"Турнир выиграл: %s", "The tournament was won by: %s"},
	"poker.hand.highcard":            {"старшая карта", "high card"},
	"poker.hand.pair":                {"пара", "pair"},
	"poker.hand.twopair":             {"две пары", "two pair"},
	"poker.hand.trips":               {"тройка", "three of a kind"},
	"poker.hand.straight":            {"стрит", "straight"},
	"poker.hand.flush":               {"флеш", "flush"},
	"poker.hand.fullhouse":           {"фулл-хаус", "full house"},
	"poker.hand.quads":               {"каре", "four of a kind"},
	"poker.hand.straightflush":       {"стрит-флеш", "straight flush"},

	"tictactoe.title":         {"=== КРЕСТИКИ-НОЛИКИ ===", "=== TIC-TAC-TOE ==="},
	"tictactoe.your_mark":     {"Вы играете за: %s", "You are playing as: %s"},
	"tictactoe.hint.turn":     {"Ваш ход.", "Your turn."},
	"tictactoe.hint.play":     {"[1-9] или ←↑↓→ + enter — поставить знак   [q] в меню", "[1-9] or ←↑↓→ + enter — place your mark   [q] to menu"},
	"tictactoe.hint.over":     {"[n] новая партия   [q] в меню", "[n] new game   [q] to menu"},
	"tictactoe.outcome.win":   {"Вы выиграли!", "You won!"},
	"tictactoe.outcome.lose":  {"Бот выиграл.", "The bot won."},
	"tictactoe.outcome.draw":  {"Ничья.", "It's a draw."},
	"tictactoe.msg.bot_moved": {"Бот сходил.", "The bot made a move."},
	"common.no_cards":         {"(нет карт)", "(no cards)"},

	// --- Тонк ---
	"tonk.title":               {"=== ТОНК ===", "=== TONK ==="},
	"tonk.status_line":         {"Колода: %d карт    Сброс сверху: %s    Банк раунда: %d (ставка: %d, Тонк ×%d)\n\n", "Deck: %d cards    Top discard: %s    Round pot: %d (ante: %d, Tonk ×%d)\n\n"},
	"tonk.melds_label":         {"Комбинации на столе:", "Combinations on the table:"},
	"tonk.table_empty":         {"(стол пуст)", "(table is empty)"},
	"tonk.set":                 {"Сет", "Set"},
	"tonk.sequence":            {"Сиквенс", "Sequence"},
	"tonk.meld_line":           {"  [%d] %s (%s): %s\n", "  [%d] %s (%s): %s\n"},
	"tonk.player_line":         {"%s%-24s карт: %-2d капитал: %d", "%s%-24s cards: %-2d balance: %d"},
	"tonk.hand_weight":         {"Вес руки: %d\n\n", "Hand weight: %d\n\n"},
	"tonk.hint.draw":           {"Ваш ход. [d] взять из колоды   [p] взять из сброса (%s)   [k] рискнуть дропом   [q] в меню", "Your turn. [d] draw from stock   [p] draw discard (%s)   [k] risk a drop   [q] menu"},
	"tonk.hint.tonk_available": {"  [t] Тонк доступен!", "  [t] Tonk available!"},
	"tonk.hint.action1":        {"[←→/hl] выбор карты   [space] отметить для комбинации   [m] выложить комбинацию", "[←→/hl] choose card   [space] mark for combination   [m] lay combination"},
	"tonk.hint.action2":        {"[1-9] подложить текущую карту к комбинации №N   [enter] сбросить текущую карту", "[1-9] add current card to combination #N   [enter] discard current card"},
	"tonk.hint.gameover":       {"[n] новый раунд   [q] в меню", "[n] new round   [q] menu"},
	"tonk.msg.bot_moved":       {"%s сходил(а).", "%s made a move."},
	"tonk.msg.drew_deck":       {"Вы взяли карту из колоды.", "You drew a card from the stock."},
	"tonk.msg.drew_discard":    {"Вы взяли из сброса: %s", "You took from the discard pile: %s"},
	"tonk.msg.drop_caught":     {"Дроп не удался — вас поймали! Банк и штраф достались %s.", "The drop failed — you got caught! The pot and penalty went to %s."},
	"tonk.msg.drop_success":    {"Дроп удался! Вы забрали банк.", "The drop succeeded! You took the pot."},
	"tonk.msg.tonk_declared":   {"Вы объявили Тонк!", "You declared Tonk!"},
	"tonk.msg.discarded":       {"Вы сбросили %s.", "You discarded %s."},
	"tonk.msg.meld_laid":       {"Комбинация выложена на стол.", "Combination laid on the table."},
	"tonk.msg.card_added":      {"Карта %s подложена к комбинации №%d.", "Card %s added to combination #%d."},
	"выберите (пробел) минимум 3 карты для комбинации": {"выберите (пробел) минимум 3 карты для комбинации", "select (space) at least 3 cards for a combination"},
	"на столе нет комбинации №%d":                      {"на столе нет комбинации №%d", "there's no combination #%d on the table"},
	"бот %s: %w": {"бот %s: %w", "bot %s: %w"},
	"tonk.bankrupt.human": {"Вы обанкротились и выбыли! Ваше место занял новый игрок: %s. Дальше играют боты — можно наблюдать или [q] выйти в меню.",
		"You went bankrupt and are out! Your seat was taken by a new player: %s. The bots will keep playing — you can watch or press [q] to go to the menu."},
	"tonk.bankrupt.bot": {"%s обанкротился(лась) и выбыл(а). За стол сел новый игрок: %s (капитал %d).",
		"%s went bankrupt and is out. A new player sat down: %s (balance %d)."},
	"tonk.result.dead":         {"Раунд закончился вничью: колода и сброс исчерпаны. Банк (%d) возвращён игрокам.", "The round ended in a draw: stock and discard pile are exhausted. The pot (%d) was returned to the players."},
	"tonk.result.tonk":         {"%s объявил(а) Тонк и забрал(а) банк ×%d (%d)!", "%s declared Tonk and took the pot ×%d (%d)!"},
	"tonk.result.drop_caught":  {"Дроп не удался! %s оказался(лась) реально ниже всех и забрал(а) банк с штрафом!", "The drop failed! %s really had the lowest hand and took the pot plus the penalty!"},
	"tonk.result.drop_success": {"%s рискнул(а) дропом и выиграл(а) — забрал(а) банк (%d)!", "%s risked a drop and won — took the pot (%d)!"},
	"tonk.result.win":          {"%s избавился(лась) от всех карт и забрал(а) банк (%d)!", "%s emptied their hand and took the pot (%d)!"},
	"tonk.result.delta_line":   {"  %-24s изменение капитала: %+d (итого: %d)\n", "  %-24s balance change: %+d (total: %d)\n"},

	// --- Дурак ---
	"durak.title":            {"=== ДУРАК ===", "=== DURAK ==="},
	"durak.legend":           {"(A — атакующий, D — защищающийся, T — сейчас подкидывает)", "(A — attacker, D — defender, T — currently throwing in)"},
	"durak.status_line":      {"Козырь: %s    В колоде: %d карт\n\n", "Trump: %s    Cards left: %d\n\n"},
	"durak.table_label":      {"Стол (атака/защита):", "Table (attack/defense):"},
	"durak.hint.gameover":    {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
	"durak.hint.attack":      {"[←→/hl] выбор карты   [enter] подкинуть карту (обязательный первый ход)   [q] в меню", "[←→/hl] choose card   [enter] play card (mandatory first move)   [q] menu"},
	"durak.hint.defend":      {"[←→/hl] выбор карты   [enter] отбить карту   [t] забрать стол   [q] в меню", "[←→/hl] choose card   [enter] beat the card   [t] take the table   [q] menu"},
	"durak.hint.throwin":     {"[←→/hl] выбор карты   [enter] подкинуть ещё карту   [p] пасовать   [q] в меню", "[←→/hl] choose card   [enter] throw in another card   [p] pass   [q] menu"},
	"durak.msg.threw_in":     {"Вы подкинули %s.", "You threw in %s."},
	"durak.msg.passed":       {"Вы пасовали.", "You passed."},
	"durak.msg.defended":     {"Вы отбились картой %s.", "You beat it with %s."},
	"durak.msg.took":         {"Вы забрали стол себе в руку.", "You took the table into your hand."},
	"durak.status_out":       {" [отбился]", " [safe]"},
	"durak.player_line":      {"%s%-20s карт: %-2d%s", "%s%-20s cards: %-2d%s"},
	"durak.result.stalemate": {"Партия зашла в тупик (карты слишком долго не выходили из игры) и объявлена ничьей.", "The game reached a stalemate (cards weren't leaving play for too long) and was declared a draw."},
	"durak.result.noloser":   {"Ничья! Все избавились от карт одновременно — дурака нет.", "A draw! Everyone emptied their hands at the same time — no fool this time."},
	"durak.result.loser":     {"%s остался(лась) с картами на руках — дурак!", "%s was left holding cards — the fool!"},
}

// blackjackTranslations добавляется отдельным init(), чтобы не
// раздувать один литерал карты translations — Go не позволяет
// повторно объявить один и тот же map-литерал в двух местах, а
// добавлять записи в уже созданную карту через init можно.
func init() {
	for k, v := range map[string]translationEntry{
		"blackjack.title":             {"=== БЛЭКДЖЕК ===", "=== BLACKJACK ==="},
		"blackjack.dealer_line":       {"Дилер:\n%s\n\n", "Dealer:\n%s\n\n"},
		"blackjack.hint.gameover":     {"[n] новый раунд   [q] в меню", "[n] new round   [q] menu"},
		"blackjack.bankrupt":          {"Вы банкрот — фишек не осталось.", "You're bankrupt — you have no chips left."},
		"blackjack.hint.bankrupt":     {"[q] в меню", "[q] menu"},
		"blackjack.hint.turn":         {"[h] взять карту   [s] остановиться   [d] удвоить ставку   [q] в меню", "[h] hit   [s] stand   [d] double down   [q] menu"},
		"blackjack.msg.hit":           {"Вы взяли карту.", "You took a card."},
		"blackjack.msg.stand":         {"Вы остановились.", "You stood."},
		"blackjack.msg.double":        {"Вы удвоили ставку.", "You doubled down."},
		"blackjack.status.stood":      {"стоп", "stood"},
		"blackjack.status.busted":     {"перебор", "bust"},
		"blackjack.status.blackjack":  {"блэкджек!", "blackjack!"},
		"blackjack.status.playing":    {"ходит", "playing"},
		"blackjack.player_header":     {"%s%-20s ставка: %-4d   итог: %d   [%s]", "%s%-20s bet: %-4d   total: %d   [%s]"},
		"blackjack.msg.bet_reduced":   {"Не хватает на полную ставку — играете на всё, что осталось: %d", "Not enough for the full bet — playing with everything you have left: %d"},
		"blackjack.msg.no_funds":      {"Денег не осталось — этот раунд играется без ставки.", "You're out of chips — this round is played with no stake."},
		"blackjack.hand_with_total":   {"%s (всего: %d)", "%s (total: %d)"},
		"blackjack.busted_suffix":     {" — перебор!", " — bust!"},
		"blackjack.outcome.blackjack": {"блэкджек! выигрыш 3:2", "blackjack! 3:2 win"},
		"blackjack.outcome.win":       {"выигрыш", "win"},
		"blackjack.outcome.push":      {"ничья, ставка возвращена", "push, bet returned"},
		"blackjack.outcome.lose":      {"проигрыш", "loss"},
		"blackjack.outcome.bust":      {"перебор, проигрыш", "bust, loss"},
		"blackjack.result_line":       {"  %-20s %-24s изменение капитала: %+d (итого: %d)", "  %-20s %-24s balance change: %+d (total: %d)"},

		"oneohone.title":               {"=== 101 ===", "=== 101 ==="},
		"oneohone.status_line":         {"Сброс сверху: %s    В колоде: %d карт\n\n", "Top discard: %s    Cards left: %d\n\n"},
		"oneohone.pending_eight_line":  {"Нужно покрыть восьмёрку: масть %s или другая восьмёрка", "You must cover the eight: suit %s or another eight"},
		"oneohone.declared_suit_line":  {"Дама назвала масть: %s (действует один ход)", "Queen declared suit: %s (lasts one move)"},
		"oneohone.hint.gameover_match": {"[q] в меню", "[q] menu"},
		"oneohone.hint.gameover":       {"[n] новый раунд   [q] в меню", "[n] new round   [q] menu"},
		"oneohone.hint.turn":           {"[←→/hl] выбор карты   [enter] сыграть карту   [d] взять из колоды (если нечем ходить)   [q] в меню", "[←→/hl] choose card   [enter] play card   [d] draw from stock (if you can't play)   [q] menu"},
		"oneohone.msg.played":          {"Вы сыграли %s.", "You played %s."},
		"oneohone.msg.suit_chosen":     {"Вы назвали масть: %s.", "You called the suit: %s."},
		"oneohone.choose_suit_prompt":  {"Вы положили даму! Назовите масть для следующего хода:\n[1] трефы   [2] бубны   [3] червы   [4] пики", "You played a Queen! Call a suit for the next move:\n[1] clubs   [2] diamonds   [3] hearts   [4] spades"},
		"oneohone.msg.drew":            {"Вы взяли карту.", "You drew a card."},
		"oneohone.status.out":          {" [выбыл]", " [out]"},
		"oneohone.player_line":         {"%s%-16s карт: %-2d счёт: %-4d%s", "%s%-16s cards: %-2d score: %-4d%s"},
		"oneohone.result.stalemate":    {"Раунд зашёл в тупик и принудительно завершён без изменения счёта.", "The round hit a stalemate and was forced to end with no score change."},
		"oneohone.result.win":          {"%s избавился(лась) от всех карт и выиграл(а) раунд!", "%s emptied their hand and won the round!"},
		"oneohone.result.queen_bonus":  {" (бонус за даму!)", " (queen bonus!)"},
		"oneohone.result.delta_line":   {"  %-16s %+d очков за раунд (итого: %d)%s", "  %-16s %+d points this round (total: %d)%s"},
		"oneohone.result.eliminated":   {" — выбыл(а) из партии!", " — eliminated from the match!"},
		"oneohone.result.reset":        {" — ровно 101, счёт обнулён!", " — exactly 101, score reset!"},
		"oneohone.result.no_winner":    {"Партия завершилась без победителя (все выбыли одновременно).", "The match ended with no winner (everyone was eliminated at the same time)."},
		"oneohone.result.match_over":   {"Партия окончена! Победитель: %s", "Match over! Winner: %s"},

		"thousand.title":               {"=== 1000 ===", "=== 1000 ==="},
		"thousand.hint.gameover_match": {"[q] в меню", "[q] menu"},
		"thousand.hint.gameover":       {"[n] новая раздача   [q] в меню", "[n] new hand   [q] menu"},
		"thousand.bidding_status":      {"Текущая максимальная ставка: %d (у %s)\n\n", "Current high bid: %d (by %s)\n\n"},
		"thousand.trump_unset":         {"ещё не назначен", "not set yet"},
		"thousand.play_status":         {"Ставка: %d (у %s)    Козырь: %s\n", "Bid: %d (by %s)    Trump: %s\n"},
		"thousand.trick_label":         {"Взятка:", "Trick:"},
		"thousand.your_hand":           {"Ваша рука:", "Your hand:"},
		"thousand.hint.bid":            {"[↑→/kl] +5   [↓←/hj] -5   [enter] поставить %d   [p] пас   [v] играть втёмную\n", "[↑→/kl] +5   [↓←/hj] -5   [enter] bid %d   [p] pass   [v] play blind\n"},
		"thousand.hint.discard":        {"[←→/hl] выбор карты   [enter] отдать карту следующему сопернику", "[←→/hl] choose card   [enter] give the card to the next opponent"},
		"thousand.hint.trick":          {"[←→/hl] выбор карты   [enter] сыграть карту (король/дама масти = объявить марьяж)", "[←→/hl] choose card   [enter] play card (King/Queen of a suit = declare a marriage)"},
		"thousand.hint.menu":           {"[q] в меню", "[q] menu"},
		"thousand.msg.bid":             {"Вы поставили %d.", "You bid %d."},
		"thousand.msg.passed":          {"Вы пасовали.", "You passed."},
		"thousand.msg.blind_declared":  {"Вы объявили игру втёмную! Заявка 120, награда и штраф удвоены.", "You declared a blind game! Bid 120, reward and penalty doubled."},
		"thousand.msg.gave_card":       {"Вы отдали %s.", "You gave away %s."},
		"thousand.msg.played":          {"Вы сыграли %s.", "You played %s."},
		"thousand.no_bidder":           {"никого — торги ещё не начались", "no one — bidding hasn't started yet"},
		"thousand.suit.clubs":          {"трефы", "clubs"},
		"thousand.suit.diamonds":       {"бубны", "diamonds"},
		"thousand.suit.hearts":         {"червы", "hearts"},
		"thousand.suit.spades":         {"пики", "spades"},
		"thousand.player_line":         {"%s%-14s карт: %-2d очки за раздачу: %-4d счёт: %-5d%s", "%s%-14s cards: %-2d hand points: %-4d score: %-5d%s"},
		"thousand.declarer_tag":        {" [торг]", " [bid]"},
		"thousand.barrel_tag":          {"[бочка %d/%d]", "[barrel %d/%d]"},
		"thousand.golden_round_tag":    {"=== ЗОЛОТОЙ КОН (очки соперников удваиваются) ===", "=== GOLDEN ROUND (opponents' points are doubled) ==="},
		"thousand.blind_round_tag":     {"=== ИГРА ВТЁМНУЮ (заявка 120, всё удвоено) ===", "=== BLIND GAME (bid 120, everything doubled) ==="},
		"thousand.trick_not_started":   {"(взятка ещё не начата)", "(trick not started yet)"},
		"thousand.result.made":         {"%s выполнил(а) ставку %d!", "%s made the bid of %d!"},
		"thousand.result.failed":       {"%s не выполнил(а) ставку %d.", "%s failed to make the bid of %d."},
		"thousand.result.delta_line":   {"  %-14s %+d очков за раздачу (итого: %d)", "  %-14s %+d points this hand (total: %d)"},
		"thousand.result.match_over":   {"Партия окончена! Победитель: %s", "Match over! Winner: %s"},

		"klondike.title":             {"=== КОСЫНКА ===", "=== KLONDIKE ==="},
		"klondike.msg.undone":        {"Ход отменён.", "Move undone."},
		"klondike.msg.drew":          {"Взяли карту из колоды.", "Drew a card from the stock."},
		"klondike.msg.moved":         {"Ход выполнен.", "Move made."},
		"klondike.msg.to_foundation": {"Карта отправлена на фундамент.", "Card sent to the foundation."},
		"klondike.empty":             {"(пусто)", "(empty)"},
		"klondike.stock_line":        {"Колода: (%d)", "Stock: (%d)"},
		"klondike.waste_label":       {"Отбой:", "Waste:"},
		"klondike.foundations_line":  {"Фундаменты:\n%s\n", "Foundations:\n%s\n"},
		"klondike.moves_line":        {"Ходов: %d\n\n", "Moves: %d\n\n"},
		"klondike.won":               {"Пасьянс сошёлся за %d ходов! Поздравляем!", "Solved in %d moves! Congratulations!"},
		"klondike.hint.gameover":     {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
		"klondike.hint.noselect":     {"[1-7] выбрать колонну   [0] выбрать отбой   [d] взять из колоды", "[1-7] select column   [0] select waste   [d] draw from stock"},
		"klondike.hint.selected":     {"[1-7] переложить в колонну   [f] на фундамент   [esc] отменить выбор   [d] взять из колоды", "[1-7] move to column   [f] to foundation   [esc] cancel selection   [d] draw from stock"},
		"klondike.hint.runlen":       {"[↑↓] сколько карт переносить: %d из %d", "[↑↓] how many cards to move: %d of %d"},
		"klondike.hint.footer":       {"[u] отменить ход   [n] новая партия   [q] в меню", "[u] undo move   [n] new game   [q] menu"},

		"checkers.title":         {"=== ШАШКИ ===", "=== CHECKERS ==="},
		"checkers.legend":        {"(o — простая шашка, O — дамка; светлые буквы — ваши белые, тёмные — чёрные бота)", "(o — man, O — king; light letters are your white pieces, dark are the bot's black pieces)"},
		"chess.legend":           {"(K/Q/R/B/N/P — король/ферзь/ладья/слон/конь/пешка; заглавные — ваши белые, строчные — чёрные бота)", "(K/Q/R/B/N/P — king/queen/rook/bishop/knight/pawn; uppercase are your white pieces, lowercase are the bot's black pieces)"},
		"checkers.msg.bot_moved": {"Бот сходил.", "The bot made a move."},
		"checkers.msg.moved":     {"Ход выполнен.", "Move made."},
		"checkers.result.draw":   {"Ничья (слишком долго не было взятий).", "Draw (no captures for too long)."},
		"checkers.result.win":    {"Вы выиграли!", "You won!"},
		"checkers.result.lose":   {"Победил бот.", "The bot won."},
		"checkers.hint.gameover": {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
		"checkers.turn.you":      {"Ваш ход (белые)", "Your turn (white)"},
		"checkers.turn.bot":      {"Бот думает (чёрные)...", "The bot is thinking (black)..."},
		"checkers.hint.noselect": {"[↑↓←→/hjkl] курсор   [enter] выбрать шашку   [q] в меню", "[↑↓←→/hjkl] cursor   [enter] select a piece   [q] menu"},
		"checkers.hint.selected": {"[↑↓←→/hjkl] курсор   [enter] переместить (или отменить выбор)   [esc] отменить выбор", "[↑↓←→/hjkl] cursor   [enter] move (or cancel selection)   [esc] cancel selection"},

		"на этой клетке нет вашей фигуры": {"на этой клетке нет вашей фигуры", "you don't have a piece on that square"},

		"chess.title":                            {"=== ШАХМАТЫ ===", "=== CHESS ==="},
		"chess.msg.bot_moved":                    {"Бот сходил.", "The bot made a move."},
		"chess.msg.moved":                        {"Ход выполнен.", "Move made."},
		"chess.check":                            {"Шах!", "Check!"},
		"chess.result.win_checkmate":             {"Мат! Вы выиграли!", "Checkmate! You won!"},
		"chess.result.lose_checkmate":            {"Мат! Победил бот.", "Checkmate! The bot won."},
		"chess.result.draw":                      {"Ничья (%s).", "Draw (%s)."},
		"chess.drawreason.stalemate":             {"пат", "stalemate"},
		"chess.drawreason.insufficient_material": {"недостаточно материала для мата", "insufficient material"},
		"chess.drawreason.no_progress":           {"слишком долго без взятий и ходов пешками", "too long without captures or pawn moves"},
		"chess.hint.gameover":                    {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
		"chess.turn.you":                         {"Ваш ход (белые)", "Your turn (white)"},
		"chess.turn.bot":                         {"Бот думает (чёрные)...", "The bot is thinking (black)..."},
		"chess.hint.noselect":                    {"[↑↓←→/hjkl] курсор   [enter] выбрать фигуру   [q] в меню", "[↑↓←→/hjkl] cursor   [enter] select a piece   [q] menu"},
		"chess.hint.selected":                    {"[↑↓←→/hjkl] курсор   [enter] переместить (или отменить выбор)   [esc] отменить выбор", "[↑↓←→/hjkl] cursor   [enter] move (or cancel selection)   [esc] cancel selection"},

		"game.chess.name": {"Шахматы (Chess)", "Chess"},
		"game.chess.desc": {"Классические шахматы против бота (минимакс), с рокировкой и взятием на проходе", "Classic chess against a minimax bot, with castling and en passant"},

		"game.corpsestarch.name": {"Трупные батончики (Corpse-Starch Box)", "Corpse-Starch Box"},
		"game.corpsestarch.desc": {"Инкрементальная игра: копите трупный крахмал, открывайте новые механики по ходу партии", "An incremental game: gather corpse starch, unlock new mechanics as you go"},
		"game.tictactoe.name":    {"Крестики-нолики", "Tic-Tac-Toe"},
		"game.tictactoe.desc":    {"Классика на доске 3×3 против бота — три уровня сложности, включая непобедимый", "The 3×3 classic against a bot — three difficulty levels, including an unbeatable one"},
		"game.nardy.name":        {"Нарды", "Nardy (Backgammon)"},
		"game.nardy.desc":        {"Короткие или длинные нарды против бота — три уровня сложности", "Short or long nardy against a bot — three difficulty levels"},
		"game.ur.name":           {"Игра Ур (Royal Game of Ur)", "The Royal Game of Ur"},
		"game.ur.desc":           {"Одна из древнейших настольных игр (Месопотамия, ~2600 до н.э.) — реконструкция правил Ирвинга Финкеля, три уровня сложности бота", "One of the oldest known board games (Mesopotamia, ~2600 BCE) — Irving Finkel's rule reconstruction, three bot difficulty levels"},
		"game.senet.name":        {"Сенет (Senet)", "Senet"},
		"game.senet.desc":        {"Древнеегипетская игра (известна с ~3500 до н.э.) — консолидированная реконструкция правил, три уровня сложности бота", "An ancient Egyptian game (attested since ~3500 BCE) — a consolidated rule reconstruction, three bot difficulty levels"},
		"game.poker.name":        {"Техасский Холдем", "Texas Hold'em"},
		"game.poker.desc":        {"Полноценный турнир No-Limit с выбыванием, от 2 до 6 игроков; уровень каждого бота (лёгкий/средний/сильный) назначается случайно", "A full No-Limit elimination tournament, 2 to 6 players; each bot's difficulty (easy/medium/strong) is assigned randomly"},

		"corpsestarch.title":                 {"=== ТРУПНЫЕ БАТОНЧИКИ ===", "=== CORPSE-STARCH BOX ==="},
		"corpsestarch.header.starch":         {"Трупный крахмал: %s   (всего добыто: %s)", "Corpse starch: %s   (total gathered: %s)"},
		"corpsestarch.header.corruption":     {"Скверна: %d", "Corruption: %d"},
		"corpsestarch.header.starch.demonic": {"Души: %s   (всего собрано: %s)", "Souls: %s   (total gathered: %s)"},
		"corpsestarch.header.astronomican":   {"Отблеск астрономикона: %d", "Astronomican's glimmer: %d"},
		"corpsestarch.hint":                  {"[1-9] выбрать действие   [N] начать заново   [q] в меню (партия автосохраняется)", "[1-9] choose an action   [N] start over   [q] menu (game is autosaved)"},
		"corpsestarch.confirm_reset":         {"Вы уверены? Весь прогресс будет безвозвратно потерян.", "Are you sure? All progress will be permanently lost."},
		"corpsestarch.confirm_reset.hint":    {"[y] да, начать заново   [n/esc] отмена", "[y] yes, start over   [n/esc] cancel"},
		"corpsestarch.msg.reset_done":        {"Начата новая партия.", "A new game has started."},

		"corpsestarch.action.requisition":     {"Реквизировать трупный крахмал (+%s)", "Requisition corpse starch (+%s)"},
		"corpsestarch.action.buy_servitor":    {"Приобрести: %s (сейчас: %d, цена: %s)", "Acquire: %s (owned: %d, cost: %s)"},
		"corpsestarch.action.upgrade_click":   {"Заточить цепной меч (цена: %s)", "Sharpen chainsword (cost: %s)"},
		"corpsestarch.action.dip":             {"Окунуть цепной меч в отстойник", "Dip your chainsword in the sump"},
		"corpsestarch.action.start_mission":   {"Начать зачистку: %s (%s)", "Start purge: %s (%s)"},
		"corpsestarch.action.collect_mission": {"Забрать награду за зачистку", "Collect purge reward"},
		"corpsestarch.action.defend":          {"Отбиваться от культистов Хаоса (заявлено атак: %d)", "Fight off Chaos cultists (attacks logged: %d)"},
		"corpsestarch.action.defend.demonic":  {"Отбиваться от карателей Империума (заявлено атак: %d)", "Fight off the Imperial punisher fleet (attacks logged: %d)"},

		"corpsestarch.msg.requisitioned":   {"Реквизиция одобрена Муниторумом.", "Requisition approved by the Munitorum."},
		"corpsestarch.msg.servitor_bought": {"Новая единица введена в строй.", "A new unit has been brought online."},
		"corpsestarch.msg.upgrade_bought":  {"Цепной меч заточен острее.", "The chainsword is sharper now."},
		"corpsestarch.msg.cannot_afford":   {"Недостаточно трупного крахмала.", "Not enough corpse starch."},
		"corpsestarch.msg.mission_started": {"Отряд отправлен на зачистку.", "A squad has been dispatched on the purge."},
		"corpsestarch.msg.defended":        {"Вы отбили атаку культистов.", "You fought off a cultist attack."},

		"corpsestarch.mission.inprogress": {"Зачистка идёт: %s (осталось %s)", "Purge underway: %s (%s remaining)"},
		"corpsestarch.mission.ready":      {"Зачистка завершена: %s — заберите награду!", "Purge complete: %s — collect your reward!"},

		"corpsestarch.log.title":                    {"Журнал Муниторума:", "Munitorum log:"},
		"corpsestarch.log.dip_bonus":                {"Отстойник выплюнул горсть трупного крахмала.", "The sump spat out a handful of corpse starch."},
		"corpsestarch.log.dip_blessing":             {"Дух машины благословил ваш клинок — временный прирост дохода.", "The machine spirit blessed your blade — temporary income boost."},
		"corpsestarch.log.dip_nothing":              {"Отстойник ответил тишиной.", "The sump answers only with silence."},
		"corpsestarch.log.dip_corruption":           {"Скверна коснулась вашего снаряжения.", "Taint has touched your wargear."},
		"corpsestarch.incursion.active":             {"ВТОРЖЕНИЕ ХАОСА! Культисты атакуют станцию — осталось: %s", "CHAOS INCURSION! Cultists are attacking the station — time left: %s"},
		"corpsestarch.incursion.active.demonic":     {"КАРАТЕЛЬНЫЙ ФЛОТ! Силы Империума атакуют вашу цитадель — осталось: %s", "PUNISHER FLEET! Imperial forces are attacking your citadel — time left: %s"},
		"corpsestarch.log.warp_breach":              {"Скверна прорвалась варп-выбросом! Половина запасов и оборудования потеряна — из пробоя хлынули культисты Хаоса.", "The taint erupts in a warp breach! Half your stockpile and equipment are lost — Chaos cultists pour through the rupture."},
		"corpsestarch.log.incursion_repelled":       {"Вторжение культистов отражено. Обошлось малой кровью.", "The cultist incursion has been repelled. It could have been worse."},
		"corpsestarch.log.incursion_repelled_bonus": {"Вторжение отражено! За стойкость станция получила дополнительный груз трупного крахмала.", "The incursion has been repelled! For your resolve, the station received a bonus shipment of corpse starch."},

		"corpsestarch.chaos.offer.title": {"=== ПРЕДЛОЖЕНИЕ ХАОСА ===", "=== THE OFFER OF CHAOS ==="},
		"corpsestarch.chaos.offer.text": {
			"Пятый варп-выброс прогремел, и в наступившей тишине что-то заговорило — терпеливо, ласково, из самой Скверны. Оно предлагает не сдерживать её больше, а принять целиком: стать чем-то новым, чему больше не грозит распад плоти.",
			"The fifth warp breach has thundered through, and in the silence after it, something speaks — patient, coaxing, from within the taint itself. It offers you an end to restraint: to embrace it fully and become something new, something no longer threatened by the failure of flesh.",
		},
		"corpsestarch.chaos.offer.accept":  {"[y] Принять Дар — начать перерождение", "[y] Accept the Gift — begin the rebirth"},
		"corpsestarch.chaos.offer.decline": {"[n] Отвергнуть зов", "[n] Reject the call"},
		"corpsestarch.log.chaos_declined": {
			"Вы отвергли зов Хаоса. Метки развеялись без следа, а кто-то щедро вознаградил вашу стойкость.",
			"You have rejected the call of Chaos. The marks dissipate without a trace, and someone rewards your resolve generously.",
		},
		"corpsestarch.log.rebirth_begins": {
			"Вы приняли Дар. Плоть тает, а душа перекраивается заново — процесс не остановить и не ускорить.",
			"You have accepted the Gift. Flesh dissolves as the soul is remade from scratch — the process cannot be stopped or hurried.",
		},
		"corpsestarch.log.rebirth_complete": {
			"Перерождение завершено. Вы больше не тот, кем были — но голод остался прежним.",
			"The rebirth is complete. You are no longer who you were — but the hunger remains just the same.",
		},
		"corpsestarch.rebirth.active":   {"ПЕРЕРОЖДЕНИЕ... осталось: %s\n\nПлоть перекраивается — сейчас ничего нельзя сделать.", "REBIRTH IN PROGRESS... time left: %s\n\nYour flesh is being remade — nothing can be done right now."},
		"corpsestarch.rebirth.hint":     {"[q] сохранить и выйти в меню   [N] начать заново", "[q] save and quit to menu   [N] start over"},
		"corpsestarch.log.mission_done": {"Отряд вернулся с зачистки с трофеями.", "The squad returned from the purge with spoils."},

		"corpsestarch.servitor.skull":        {"Сервочерп", "Servo-Skull"},
		"corpsestarch.servitor.menial":       {"Сервитор-подёнщик", "Menial Servitor"},
		"corpsestarch.servitor.cogitator":    {"Когитаторный комплекс", "Cogitator Array"},
		"corpsestarch.servitor.pinkhorror":   {"Розовый ужас", "Pink Horror"},
		"corpsestarch.servitor.screamer":     {"Визгун", "Screamer"},
		"corpsestarch.servitor.lordofchange": {"Владыка Перемен", "Lord of Change"},

		"corpsestarch.mission.vermin":      {"Зачистить улей от паразитов", "Purge the Hive Vermin"},
		"corpsestarch.mission.chapel":      {"Очистить часовню от еретиков", "Cleanse the Chapel of Heretics"},
		"corpsestarch.mission.waaagh":      {"Заглушить барабаны Вааагх!", "Silence the Ork Waaagh Drums"},
		"corpsestarch.mission.borderworld": {"Разграбить приграничный мир", "Raid a Border World"},
		"corpsestarch.mission.shrineworld": {"Обрушить кару на планету-святилище", "Bring Ruin to a Shrine World"},
		"corpsestarch.mission.sector":      {"Испепелить целый сектор пламенем Перемен", "Sear a Whole Sector with the Flames of Change"},

		"corpsestarch.msg.welcome_back": {"С возвращением! Пока вас не было, сервиторы намолотили +%s трупного крахмала.", "Welcome back! While you were away, your servitors gathered +%s corpse starch."},

		"game.go.name": {"Го (Go)", "Go"},
		"game.go.desc": {"Классическая настольная игра на доске 9x9/13x13/19x19, три уровня сложности бота", "Classic board game on a 9x9/13x13/19x19 board, three bot difficulty levels"},

		"gosettings.title":        {"НАСТРОЙКА ПАРТИИ", "GAME SETUP"},
		"gosettings.boardsize":    {"Размер доски", "Board size"},
		"gosettings.difficulty":   {"Сложность бота", "Bot difficulty"},
		"gosettings.hint":         {"[↑↓/kj] поле   [←→/hl] изменить значение   [enter] начать игру   [esc/q] назад", "[↑↓/kj] field   [←→/hl] change value   [enter] start game   [esc/q] back"},
		"gosettings.level.easy":   {"Простой", "Easy"},
		"gosettings.level.medium": {"Средний", "Medium"},
		"gosettings.level.hard":   {"Сильный", "Strong"},

		"go.title":           {"=== ГО ===", "=== GO ==="},
		"go.header.captures": {"Взято чёрными: %d    Взято белыми: %d", "Captured by black: %d    Captured by white: %d"},
		"go.color.black":     {"Чёрные", "Black"},
		"go.color.white":     {"Белые", "White"},
		"go.turn.you":        {"Ваш ход (чёрные)", "Your turn (black)"},
		"go.turn.bot":        {"Бот думает (белые)...", "The bot is thinking (white)..."},
		"go.hint.play":       {"[↑↓←→/hjkl] курсор   [enter] поставить камень   [p] пасовать   [q] в меню", "[↑↓←→/hjkl] cursor   [enter] place a stone   [p] pass   [q] menu"},
		"go.hint.gameover":   {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
		"go.msg.bot_moved":   {"Бот сходил.", "The bot made a move."},
		"go.msg.bot_passed":  {"Бот пасовал.", "The bot passed."},
		"go.msg.played":      {"Камень поставлен.", "Stone placed."},
		"go.msg.passed":      {"Вы пасовали.", "You passed."},
		"go.result.line":     {"Партия окончена! Победили %s (счёт: %.1f — %.1f)", "Game over! %s win (score: %.1f — %.1f)"},

		"точка вне пределов доски":                      {"точка вне пределов доски", "that point is off the board"},
		"точка уже занята":                              {"точка уже занята", "that point is already occupied"},
		"этот ход самоубийственный — так ходить нельзя": {"этот ход самоубийственный — так ходить нельзя", "that move is suicidal — it isn't allowed"},
		"этот ход запрещён правилом ко":                 {"этот ход запрещён правилом ко", "that move is forbidden by the ko rule"},

		"game.minesweeper.name": {"Сапёр (Minesweeper)", "Minesweeper"},
		"game.minesweeper.desc": {"Классический Сапёр, три пресета размера поля на выбор", "Classic Minesweeper, three field size presets to choose from"},

		"mssettings.title":        {"НАСТРОЙКА ПОЛЯ", "FIELD SETUP"},
		"mssettings.hint":         {"[↑↓/kj] выбор пресета   [enter] начать игру   [esc/q] назад", "[↑↓/kj] choose preset   [enter] start game   [esc/q] back"},
		"mssettings.beginner":     {"Новичок", "Beginner"},
		"mssettings.intermediate": {"Любитель", "Intermediate"},
		"mssettings.expert":       {"Эксперт", "Expert"},

		"minesweeper.title":         {"=== САПЁР ===", "=== MINESWEEPER ==="},
		"minesweeper.header.mines":  {"Осталось мин: %d", "Mines remaining: %d"},
		"minesweeper.hint.play":     {"[↑↓←→/hjkl] курсор   [enter] открыть/хорда   [f] флаг   [q] в меню", "[↑↓←→/hjkl] cursor   [enter] reveal/chord   [f] flag   [q] menu"},
		"minesweeper.hint.gameover": {"[n] новая партия   [q] в меню", "[n] new game   [q] menu"},
		"minesweeper.msg.revealed":  {"Клетка открыта.", "Cell revealed."},
		"minesweeper.msg.boom":      {"Бах! Это была мина.", "Boom! That was a mine."},
		"minesweeper.msg.flagged":   {"Флаг установлен.", "Flag placed."},
		"minesweeper.msg.unflagged": {"Флаг снят.", "Flag removed."},
		"minesweeper.msg.chorded":   {"Соседние клетки открыты.", "Neighboring cells revealed."},

		"эта клетка ещё не открыта": {"эта клетка ещё не открыта", "that cell isn't revealed yet"},
		"minesweeper.result.win":    {"Поздравляем! Все безопасные клетки открыты.", "Congratulations! All safe cells revealed."},
		"minesweeper.result.lose":   {"Вы подорвались на мине. Партия окончена.", "You hit a mine. Game over."},

		"клетка вне пределов поля":           {"клетка вне пределов поля", "that cell is off the field"},
		"клетка уже открыта":                 {"клетка уже открыта", "that cell is already revealed"},
		"сначала снимите флаг с этой клетки": {"сначала снимите флаг с этой клетки", "remove the flag from that cell first"},
	} {
		translations[k] = v
	}
}
