// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3

#include "i18n.h"
#include "platform.h"
#include "../config/version.h"  // DRAGONX_DEFAULT_RPC_PORT

#include <fstream>
#include <cstdio>
#include <cstring>
#include <nlohmann/json.hpp>

// Embedded language files
#include "embedded/lang_es.h"
#include "embedded/lang_zh.h"
#include "embedded/lang_ru.h"
#include "embedded/lang_de.h"
#include "embedded/lang_fr.h"
#include "embedded/lang_pt.h"
#include "embedded/lang_ja.h"
#include "embedded/lang_ko.h"
#include "../util/logger.h"

namespace dragonx {
namespace util {

using json = nlohmann::json;

namespace {

// Map a printf conversion char to its varargs argument class: 'i' (int-promoted), 'f'
// (double), 'p' (pointer/string). This is what matters for safety — reading a double slot
// as an int (or vice-versa) is undefined behavior; interchanging d/x is merely cosmetic.
char conversionClass(char c)
{
    switch (c) {
        case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c': return 'i';
        case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': case 'a': case 'A': return 'f';
        case 's': case 'p': return 'p';
        default: return '?';
    }
}

// Ordered argument signature of a printf-style format string (e.g. "%d / %.0f%%" -> "if").
// "%%" is a literal and contributes nothing.
std::string formatSignature(const std::string& s)
{
    std::string sig;
    for (size_t i = 0; i < s.size(); ++i) {
        if (s[i] != '%') continue;
        if (++i >= s.size()) break;
        if (s[i] == '%') continue;  // literal "%%"
        while (i < s.size() && std::strchr("-+ #0123456789.*lhLzjtq", s[i])) ++i;
        if (i < s.size()) sig.push_back(conversionClass(s[i]));
    }
    return sig;
}

}  // namespace

I18n::I18n()
{
    // Register built-in languages
    // CJK glyphs are provided by the merged NotoSansCJK-Subset fallback font.
    // Cyrillic glyphs are included in the Ubuntu font glyph ranges.
    registerLanguage("en", "English");
    registerLanguage("es", "Español");
    registerLanguage("zh", "中文");
    registerLanguage("ru", "Русский");
    registerLanguage("de", "Deutsch");
    registerLanguage("fr", "Français");
    registerLanguage("pt", "Português");
    registerLanguage("ja", "日本語");
    registerLanguage("ko", "한국어");
    
    // Load default English strings (built-in fallback)
    loadLanguage("en");
}

I18n& I18n::instance()
{
    static I18n instance;
    return instance;
}

void I18n::overlayTranslations(const nlohmann::json& translations)
{
    for (auto& [key, value] : translations.items()) {
        if (!value.is_string()) continue;
        const std::string translated = value.get<std::string>();
        // If the English base for this key carries printf specifiers, the translation must
        // keep the same argument signature — otherwise it would be passed to printf/ImGui
        // with mismatched varargs (UB). On mismatch, keep the safe English string.
        const auto base = strings_.find(key);
        if (base != strings_.end()) {
            const std::string baseSig = formatSignature(base->second);
            if (!baseSig.empty() && baseSig != formatSignature(translated)) {
                DEBUG_LOGF("i18n: dropping '%s' — format mismatch (\"%s\" vs English)\n",
                           key.c_str(), translated.c_str());
                continue;
            }
        }
        strings_[key] = translated;
    }
}

bool I18n::loadLanguage(const std::string& locale)
{
    // Try to load from file: CWD-relative first, then exe-relative
    std::string rel_path = "res/lang/" + locale + ".json";
    std::string exe_path = Platform::getExecutableDirectory() + "/" + rel_path;

    // Try both paths; prefer whichever opens successfully
    for (const auto& lang_file : { rel_path, exe_path }) {
        std::ifstream file(lang_file);
        if (!file.is_open()) continue;

        try {
            json j;
            file >> j;

            // Load English built-in as fallback base for non-English
            if (locale != "en") {
                loadBuiltinEnglish();
            } else {
                strings_.clear();
            }
            overlayTranslations(j);

            current_locale_ = locale;
            DEBUG_LOGF("Loaded language file: %s (%zu strings)\n", lang_file.c_str(), strings_.size());
            return true;

        } catch (const std::exception& e) {
            DEBUG_LOGF("Error parsing language file %s: %s\n", lang_file.c_str(), e.what());
        }
    }
    
    // Try embedded language data
    const unsigned char* embedded_data = nullptr;
    unsigned int embedded_size = 0;
    
    if (locale == "es") {
        embedded_data = res_lang_es_json;
        embedded_size = res_lang_es_json_len;
    } else if (locale == "zh") {
        embedded_data = res_lang_zh_json;
        embedded_size = res_lang_zh_json_len;
    } else if (locale == "ru") {
        embedded_data = res_lang_ru_json;
        embedded_size = res_lang_ru_json_len;
    } else if (locale == "de") {
        embedded_data = res_lang_de_json;
        embedded_size = res_lang_de_json_len;
    } else if (locale == "fr") {
        embedded_data = res_lang_fr_json;
        embedded_size = res_lang_fr_json_len;
    } else if (locale == "pt") {
        embedded_data = res_lang_pt_json;
        embedded_size = res_lang_pt_json_len;
    } else if (locale == "ja") {
        embedded_data = res_lang_ja_json;
        embedded_size = res_lang_ja_json_len;
    } else if (locale == "ko") {
        embedded_data = res_lang_ko_json;
        embedded_size = res_lang_ko_json_len;
    }
    
    if (embedded_data != nullptr && embedded_size > 0) {
        try {
            std::string json_str(reinterpret_cast<const char*>(embedded_data), embedded_size);
            json j = json::parse(json_str);
            
            // Load English built-in as fallback base for non-English
            if (locale != "en") {
                loadBuiltinEnglish();
            } else {
                strings_.clear();
            }
            overlayTranslations(j);

            current_locale_ = locale;
            DEBUG_LOGF("Loaded embedded language: %s (%zu strings)\n", locale.c_str(), strings_.size());
            return true;
            
        } catch (const std::exception& e) {
            DEBUG_LOGF("Error parsing embedded language %s: %s\n", locale.c_str(), e.what());
        }
    }
    
    // If English, use built-in strings
    if (locale == "en") {
        loadBuiltinEnglish();
        current_locale_ = "en";
        return true;
    }
    
    return false;
}

void I18n::loadBuiltinEnglish()
{
        strings_.clear();
        
        // Navigation & Tabs
        strings_["overview"] = "Overview";
        strings_["balance"] = "Balance";
        strings_["send"] = "Send";
        strings_["receive"] = "Receive";
        strings_["transactions"] = "Transactions";
        strings_["history"] = "History";
        strings_["contacts"] = "Contacts";
        strings_["chat"] = "Chat";
        strings_["chat_locked_hint"] = "Unlock your wallet to load your chats.";
        strings_["chat_empty_hint"] = "No conversations yet. Messages you receive will appear here.";
        strings_["chat_you"] = "You";
        strings_["chat_contact_request"] = "contact request";
        strings_["chat_send_failed"] = "not sent";
        strings_["chat_new_button"] = "New chat";
        strings_["chat_select_hint"] = "Select a conversation to view it.";
        strings_["chat_waiting_reply"] = "Waiting for this contact to reply — you can message them once they do.";
        strings_["chat_send"] = "Send";
        strings_["chat_new_title"] = "New chat";
        strings_["chat_new_zaddr"] = "Recipient z-address";
        strings_["chat_new_needs_zaddr"] = "Chat needs a shielded (z) address — transparent (t) addresses can't receive encrypted messages.";
        strings_["chat_new_message"] = "Message";
        strings_["chat_new_send"] = "Send request";
        strings_["chat_cancel"] = "Cancel";
        strings_["chat_add_contact"] = "Add contact";
        strings_["chat_contact_added"] = "Contact added — rename it in Contacts";
        strings_["chat_new_message_toast"] = "New encrypted chat message";
        strings_["chat_toast_not_connected"] = "Not connected — chat message not sent.";
        strings_["chat_toast_no_zaddr"] = "No z-address available to send chat from.";
        strings_["chat_toast_lite_busy"] = "A send is already in progress, or no wallet is open.";
        strings_["chat_toast_waiting_reply"] = "Waiting for the contact to reply before you can message them.";
        strings_["chat_toast_compose_failed"] = "Could not compose the message (too long?).";
        strings_["chat_toast_request_compose_failed"] = "Could not compose the contact request (invalid address / text?).";
        strings_["chat_toast_request_queued"] = "Contact request queued.";
        strings_["chat_toast_need_funds"] = "Need a small shielded balance to send chat (to cover the fee).";
        strings_["chat_sending"] = "sending\xE2\x80\xA6";
        strings_["chat_time_now"] = "now";
        strings_["chat_retry"] = "Retry";
        strings_["chat_jump_latest"] = "Latest";
        strings_["chat_empty_title"] = "No conversations yet";
        strings_["chat_empty_start"] = "Start one with \"New conversation\".";
        strings_["chat_search"] = "Search conversations";
        strings_["chat_no_matches"] = "No conversations match your search.";
        strings_["chat_export"] = "Export chat\xE2\x80\xA6";
        strings_["chat_export_warn"] = "Saves the decrypted messages as plain text. Store the file securely.";
        strings_["chat_export_done"] = "Conversation exported";
        strings_["chat_export_failed"] = "Could not write the export file.";
        strings_["chat_len_over"] = "Message too long";
        strings_["chat_mute"] = "Mute";
        strings_["chat_unmute"] = "Unmute";
        strings_["chat_hide"] = "Hide";
        strings_["chat_unhide"] = "Unhide";
        strings_["chat_show_hidden"] = "Show hidden";
        strings_["chat_emoji_search"] = "Search emoji";
        strings_["chat_hide_hidden"] = "Hide hidden";
        strings_["chat_hidden_toast"] = "Conversation hidden — a new message brings it back";
        // Delete conversation (local cache) — revive-on-new-message vs delete & block
        strings_["chat_delete"] = "Delete conversation";
        strings_["chat_delete_title"] = "Delete conversation?";
        strings_["chat_delete_body_prefix"] = "Delete your local copy of the conversation with ";
        strings_["chat_delete_body_suffix"] = "?";
        strings_["chat_delete_revive_note"] = "\"Delete\" clears the history on this device. If they message you again, the conversation comes back.";
        strings_["chat_delete_local_note"] = "This only affects this device — the messages stay on the blockchain and the other person keeps their copy.";
        strings_["chat_delete_confirm"] = "Delete";
        strings_["chat_delete_block"] = "Delete & block";
        strings_["chat_deleted_toast"] = "Conversation deleted";
        strings_["chat_delete_failed"] = "Couldn't delete the conversation — nothing was changed.";
        strings_["chat_blocked_toast"] = "Conversation deleted & blocked";
        strings_["chat_blocked_manage"] = "Blocked";
        strings_["chat_blocked_title"] = "Blocked conversations";
        strings_["chat_blocked_desc"] = "Blocked conversations are removed and their messages are dropped — old and new — until you unblock. Unblocking re-imports the conversation from the chain.";
        strings_["chat_unblock"] = "Unblock";
        strings_["chat_unblocked_toast"] = "Conversation unblocked";
        strings_["chat_pick_contact"] = "Choose from contacts\xE2\x80\xA6";
        strings_["chat_no_z_contacts"] = "No shielded-address contacts yet";
        strings_["chat_copy_address_tip"] = "Click to copy address";
        strings_["chat_verify_key"] = "Identity key \xE2\x80\x94 compare to verify";
        strings_["chat_awaiting_key"] = "Waiting for reply";
        strings_["chat_rename"] = "Rename contact";
        strings_["chat_rename_hint"] = "Contact name";
        strings_["chat_renamed"] = "Contact renamed";
        // Chat note-buffer status (status bar, while the Chat tab is active). %d are counts;
        // keep the format specifiers intact in translations.
        strings_["chat_buffer_sending_one"] = "Chat: sending %d message\xE2\x80\xA6";
        strings_["chat_buffer_sending"] = "Chat: sending %d messages\xE2\x80\xA6";
        strings_["chat_buffer_preparing"] = "Chat buffer: preparing %d/%d\xE2\x80\xA6";
        strings_["chat_buffer_loading"] = "Chat buffer: \xE2\x80\xA6";
        strings_["chat_buffer_ready"] = "Chat buffer: %d/%d ready";
        // Chat customization (gear modal + Settings → Chat & Contacts)
        strings_["chat_settings_title"] = "Chat settings";
        strings_["chat_settings_tip"] = "Chat customization";
        strings_["chat_settings_section"] = "CHAT & CONTACTS";
        strings_["chat_opt_emoji"] = "Emoji style";
        strings_["chat_emoji_mono"] = "Monochrome";
        strings_["chat_emoji_color"] = "Color";
        strings_["chat_opt_poll"] = "Message poll rate";
        strings_["chat_opt_bubble_style"] = "Bubble style";
        strings_["chat_bubble_rounded"] = "Rounded";
        strings_["chat_bubble_square"] = "Square";
        strings_["chat_bubble_minimal"] = "Minimal";
        strings_["chat_opt_bubble_accent"] = "Bubble color";
        strings_["chat_accent_theme"] = "Theme";
        strings_["chat_accent_blue"] = "Blue";
        strings_["chat_accent_green"] = "Green";
        strings_["chat_accent_purple"] = "Purple";
        strings_["chat_accent_amber"] = "Amber";
        strings_["chat_accent_pink"] = "Pink";
        strings_["chat_opt_density"] = "Message density";
        strings_["chat_density_comfortable"] = "Comfortable";
        strings_["chat_density_compact"] = "Compact";
        strings_["chat_opt_font_size"] = "Text size";
        strings_["chat_opt_timestamp"] = "Timestamps";
        strings_["chat_ts_global"] = "Follow global";
        strings_["chat_ts_24h"] = "24-hour";
        strings_["chat_ts_12h"] = "12-hour";
        strings_["chat_opt_enter_sends"] = "Enter sends message";
        strings_["chat_opt_global_clock"] = "Global clock format";
        strings_["chat_settings_done"] = "Done";
        strings_["chat_ts_global_short"] = "Global";
        strings_["chat_sec_appearance"] = "APPEARANCE";
        strings_["chat_sec_messaging"] = "MESSAGING";
        strings_["chat_today"] = "Today";
        strings_["chat_yesterday"] = "Yesterday";
        // Seed-phrase backup (full-node)
        strings_["seed_backup_button"] = "Seed phrase";
        strings_["tt_seed_backup"] = "Show and back up your wallet's 24-word recovery seed phrase";
        strings_["seed_backup_title"] = "Back up seed phrase";
        strings_["seed_backup_intro"] = "These words are the master backup of your wallet. Anyone who has them controls your funds.";
        strings_["seed_backup_warning"] = "Write them down in order, store them offline, and never share or photograph them. If you lose them, your funds cannot be recovered.";
        strings_["seed_backup_loading"] = "Loading your seed phrase…";
        strings_["seed_backup_locked"] = "Unlock your wallet to reveal its seed phrase.";
        strings_["seed_backup_none"] = "This wallet predates seed phrases, so it has no 24-word phrase. Back it up with \"Backup wallet\" or by exporting your private keys instead.";
        strings_["seed_backup_load_failed"] = "Could not load the seed phrase.";
        strings_["seed_backup_copy"] = "Copy";
        strings_["seed_backup_save"] = "Save to file…";
        strings_["seed_backup_saved"] = "Saved an UNENCRYPTED seed file — move it to secure offline storage and delete this copy: ";
        strings_["seed_backup_save_failed"] = "Could not write ";
        strings_["seed_backup_close"] = "Close";
        strings_["seed_backup_reminder"] = "Your wallet has a 24-word recovery seed phrase. Back it up now in Settings → Node & Security.";
        strings_["seed_migrate_button"] = "Migrate to seed…";
        // Multi-wallet: wallet-files list + switcher
        strings_["wallets_button"] = "Wallets…";
        strings_["tt_wallets_button"] = "List your wallet files and switch between them";
        strings_["wallets_title"] = "Wallets";
        strings_["wallets_intro"] = "Wallet files in your data directory (and any folders you add). Open one to switch — the node restarts to load it, and each wallet keeps its own data.";
        strings_["wallets_col_name"] = "Wallet";
        strings_["wallets_col_size"] = "Size";
        strings_["wallets_col_addresses"] = "Addresses";
        strings_["wallets_col_txs"] = "txs";
        strings_["wallets_col_keys"] = "keys";
        strings_["wallets_created"] = "created";
        strings_["wallets_sort_by"] = "Sort:";
        strings_["wallets_sort_created"] = "Created";
        strings_["wallets_sort_addresses"] = "Addresses";
        strings_["wallets_sort_txs"] = "Txs";
        strings_["wallets_sort_size"] = "Size";
        strings_["wallets_sort_asc"] = "Ascending (oldest / fewest / smallest first)";
        strings_["wallets_sort_desc"] = "Descending (newest / most / largest first)";
        strings_["wallets_col_balance"] = "Balance";
        strings_["wallets_col_opened"] = "Last opened";
        strings_["wallets_current"] = "current";
        strings_["wallets_active"] = "Active";
        strings_["wallets_badge_encrypted"] = "Encrypted (passphrase-protected)";
        strings_["wallets_badge_seed"] = "Seed phrase wallet (HD)";
        strings_["wallets_badge_legacy"] = "Legacy wallet (no seed phrase)";
        strings_["wallets_badge_unknown"] = "Wallet type not fully determined (large file — open to confirm)";
        strings_["wallets_badge_hd"] = "HD wallet — can't confirm a seed phrase without opening it";
        strings_["wallets_badge_seed_short"] = "Seed phrase";
        strings_["wallets_badge_encrypted_short"] = "Encrypted";
        strings_["wallets_badge_legacy_short"] = "Legacy";
        strings_["wallets_badge_hd_short"] = "HD wallet";
        strings_["wallets_badge_unknown_short"] = "Unknown";
        strings_["wallets_open"] = "Open";
        strings_["wallets_open_folder"] = "Open folder location";
        strings_["wallets_open_inplace_tt"] = "Open this wallet where it is — linked into the data directory (no copy)";
        strings_["wallets_open_failed"] = "Couldn't open this wallet in place. It's likely on a different drive than your data directory — move it onto the same drive (on Windows, enabling Developer Mode also lets it link across drives).";
        strings_["wallets_never"] = "Never opened";
        strings_["wallets_external_tt"] = "Outside your data directory \xE2\x80\x94 Open links it in place (no copy).";
        strings_["wallets_scan_folder"] = "Scan another folder for wallets\xE2\x80\xA6";
        strings_["wallets_scanned_folders"] = "Scanned folders:";
        strings_["wallets_remove_folder"] = "Stop scanning this folder";
        strings_["wallets_empty_hint"] = "Scan a folder to find more wallets";
        strings_["wallets_folder_invalid"] = "That folder doesn't exist.";
        strings_["wallets_new_label"] = "Create a new wallet:";
        strings_["wallets_new_hint"] = "Name (e.g. savings)";
        strings_["wallets_create"] = "Create wallet";
        strings_["wallets_name_invalid"] = "Please enter a valid wallet name.";
        strings_["wallets_exists"] = "A wallet with that name already exists.";
        strings_["wallets_creating"] = "Creating wallet — the node will restart…";
        strings_["wallets_reveal"] = "Reveal folder";
        // In-app folder picker (Scan another folder)
        strings_["picker_title"] = "Select a folder to scan";
        strings_["picker_up"] = "Up one level";
        strings_["picker_home"] = "Home folder";
        strings_["picker_empty"] = "This folder has no sub-folders or wallet files.";
        strings_["picker_dat_count"] = "%d wallet file(s) in this folder";
        strings_["picker_dat_none"] = "No wallet files directly in this folder";
        strings_["picker_select"] = "Scan this folder";
        // In-app image picker (contact avatars)
        strings_["img_picker_title"] = "Choose an image";
        strings_["img_picker_pictures"] = "Pictures folder";
        strings_["img_picker_empty"] = "This folder has no sub-folders or images.";
        strings_["img_picker_none"] = "No images in this folder";
        strings_["img_picker_count"] = "%d image(s) in this folder";
        strings_["img_picker_use"] = "Use image";
        strings_["tt_seed_migrate"] = "Create a new seed-phrase wallet and move your funds into it";
        // Migrate-to-seed modal
        strings_["mig_title"] = "Migrate to a seed wallet";
        strings_["mig_intro"] = "This creates a brand-new wallet backed by a 24-word seed phrase, in an isolated node, so you can move your funds into it. Your current wallet is NOT touched and NO funds move in this step — you'll back up the new seed first, then sweep your funds into it as a separate, confirmed step.";
        strings_["mig_create"] = "Create seed wallet";
        // Intro pre-flight (checking the current wallet before offering to migrate)
        strings_["mig_precheck_checking"] = "Checking your wallet";
        strings_["mig_already_mnemonic"] = "Your wallet already has a 24-word seed phrase — there's nothing to migrate. Just back it up and keep the words somewhere safe.";
        strings_["mig_backup_instead"] = "Back up seed phrase";
        strings_["mig_daemon_too_old"] = "Your DragonX node is too old to create a seed wallet — it lacks the mnemonic support this needs. Update the node (Settings → NODE & SECURITY → Install bundled, or Check for updates), then try again.";
        strings_["mig_not_connected"] = "Connect to your node first, then reopen this to migrate.";
        strings_["mig_unlock_to_migrate"] = "Unlock your wallet first, then reopen this to migrate.";
        strings_["mig_check_failed"] = "Couldn't check your wallet. Make sure it's unlocked and connected, then re-check.";
        strings_["mig_recheck"] = "Re-check";
        // Sweep step: balance still loading / no funds to move
        strings_["mig_checking_balance"] = "Checking your balance";
        strings_["mig_no_funds"] = "Your wallet has no funds to migrate. You can adopt the new seed wallet directly — it replaces your current (empty) wallet with the seed-backed one. Your old wallet is still moved aside to a timestamped backup, just in case.";
        strings_["mig_sweep_inflight"] = "A sweep was already started and hasn't confirmed yet. Your balance reads zero because the funds are in the pending sweep transaction — they are not lost. Wait for it to confirm before finishing; the wallet will not be swapped until the sweep is mined.";
        strings_["mig_checking_sweep"] = "Looking for the sweep transaction";
        strings_["mig_check_sweep"] = "Check the sweep";
        strings_["mig_adopt_now"] = "Adopt seed wallet";
        strings_["mig_nofunds_confirm"] = "I understand this replaces my current wallet with the new seed wallet";
        // Adopting step note (shown under the spinner while the node restarts + rescans)
        strings_["mig_adopting_note"] = "The node is restarting on your new wallet and will rescan the chain — this can take several minutes. Leave the wallet running; it reconnects automatically.";
        strings_["mig_working"] = "Creating your new seed wallet in an isolated node — this can take a minute. Your main wallet keeps running.";
        strings_["mig_seed_warning"] = "Write these 24 words down in order and store them offline. They are the only backup of your new wallet — if you lose them, the funds you migrate are gone forever.";
        strings_["mig_receive_addr"] = "New wallet receive address:";
        strings_["mig_copy_seed"] = "Copy seed";
        strings_["mig_backed_up"] = "I've written down my seed phrase";
        strings_["mig_step1_done"] = "Step 1 of 2 complete — your funds have NOT moved yet. Sweeping them into this new wallet is the next step.";
        strings_["mig_continue_sweep"] = "Continue to sweep";
        strings_["mig_discard"] = "Discard migration";
        strings_["mig_sweep_intro"] = "Now sweep all funds from your current wallet into the new seed wallet. This sends a single transaction to the new wallet's address; your seed phrase (already backed up) controls the funds from here on.";
        strings_["mig_balance"] = "Current wallet balance: %.8f DRGX (minus a small fee)";
        strings_["mig_to"] = "To: ";
        strings_["mig_unlock_first"] = "Unlock your wallet first to spend from it.";
        strings_["mig_sweep_all"] = "Sweep all funds";
        strings_["mig_later"] = "Later";
        strings_["mig_sweeping"] = "Sweeping your funds into the new wallet…";
        strings_["mig_confirming"] = "Waiting for the sweep to confirm on-chain before switching wallets — this guarantees your funds have actually moved.";
        strings_["mig_confs"] = "Sweep confirmations: %d";
        strings_["mig_txid"] = "txid: ";
        strings_["mig_remaining"] = "Remaining in old wallet: %.8f DRGX";
        strings_["mig_adopt"] = "Make this my wallet";
        strings_["mig_remainder"] = "Some funds are still in your old wallet (too many inputs for one transaction) — sweep the remainder before switching.";
        strings_["mig_sweep_remaining"] = "Sweep remaining";
        strings_["mig_waiting_mine"] = "Waiting for the sweep transaction to be mined…";
        strings_["mig_adopting"] = "Installing your new wallet and rescanning…";
        strings_["mig_done"] = "Migration complete. Your wallet is now backed by your seed phrase.";
        strings_["mig_done_detail"] = "The daemon is rescanning to show your funds — this can take a few minutes. Your previous wallet was saved as a .bak in the data folder.";
        strings_["mig_done_btn"] = "Done";
        strings_["contacts_search_placeholder"] = "Search contacts...";
        strings_["contacts_settings_title"] = "Contacts settings";
        strings_["contacts_settings_tip"] = "Contacts customization";
        strings_["contacts_avatar_shape"] = "Avatar shape";
        strings_["contacts_shape_circle"] = "Circle";
        strings_["contacts_shape_square"] = "Square";
        strings_["contacts_shape_tab"] = "Left tab";
        strings_["contacts_list_scale"] = "List scale";
        strings_["contacts_search_no_match"] = "No matching contacts";
        strings_["address_book_confirm_delete"] = "Confirm delete?";
        strings_["mining"] = "Mining";
        strings_["peers"] = "Peers";
        strings_["market"] = "Market";
        strings_["settings"] = "Settings";
        strings_["console"] = "Console";
        strings_["tools"] = "TOOLS";
        strings_["advanced"] = "ADVANCED";
        
        // Settings sections
        strings_["appearance"] = "APPEARANCE";
        strings_["theme_language"] = "THEME & LANGUAGE";
        strings_["scale_effects"] = "SCALE & EFFECTS";
        strings_["advanced_effects"] = "Advanced Effects...";
        strings_["tools_actions"] = "Tools & Actions...";
        strings_["tools_actions_hdr"] = "TOOLS & ACTIONS";
        strings_["wallet_options_hdr"] = "OPTIONS";
        strings_["wallet_diagnostics_hdr"] = "DIAGNOSTICS";
        strings_["wallet"] = "WALLET";
        strings_["node_security"] = "NODE & SECURITY";
        strings_["node"] = "NODE";
        strings_["security"] = "SECURITY";
        strings_["explorer_section"] = "EXPLORER";
        strings_["explorer_urls_hdr"] = "URLS";
        strings_["about"] = "About";
        strings_["backup_data"] = "BACKUP & DATA";
        strings_["backup_col_import"] = "IMPORT & RESTORE";
        strings_["backup_col_backup"] = "BACKUP";
        strings_["backup_col_export"] = "EXPORT";
        strings_["balance_layout"] = "Balance Layout";
        strings_["low_spec_mode"] = "Low-spec mode";
        strings_["simple_background"] = "Simple background";
        strings_["console_scanline"] = "Console scanline";
        strings_["theme_effects"] = "Theme effects";
        strings_["animate_avatars"] = "Animate avatars";
        strings_["acrylic"] = "Acrylic";
        strings_["noise"] = "Noise";
        strings_["ui_opacity"] = "UI Opacity";
        strings_["window_opacity"] = "Window Opacity";
        strings_["font_scale"] = "Font Scale";
        strings_["refresh"] = "Refresh";
        strings_["website"] = "Website";
        strings_["report_bug"] = "Report Bug";
        strings_["save_settings"] = "Save Settings";
        strings_["reset_to_defaults"] = "Reset to Defaults";
        
        // Wallet settings
        strings_["save_z_transactions"] = "Save shielded tx history";
        strings_["auto_shield"] = "Auto-shield";
        strings_["use_tor"] = "Use Tor";
        strings_["keep_daemon"] = "Keep daemon running";
        strings_["stop_external"] = "Stop external daemon";
        strings_["verbose_logging"] = "Verbose logging";
        strings_["screenshot_sweep"] = "Run screenshot sweep";
        strings_["screenshot_sweep_full"] = "Full UI sweep";
        strings_["screenshot_open_dir"] = "Open location";
        strings_["sweep_current_theme_only"] = "Current theme only";
        strings_["tt_sweep_current_theme_only"] = "Sweep only the active theme instead of cycling every theme";
        strings_["screenshot_sweep_desc"] = "Cycles every theme across every tab and saves a screenshot of each into per-tab subfolders under the config directory's screenshots folder (overwriting the previous sweep). Runs for a few seconds.";
        strings_["mine_when_idle"] = "Mine when idle";
        strings_["setup_wizard"] = "Run Setup Wizard…";
        
        // RPC / Explorer settings
        strings_["rpc_connection"] = "RPC Connection...";
        strings_["rpc_host"] = "Host";
        strings_["rpc_port"] = "Port";
        strings_["rpc_user"] = "Username";
        strings_["rpc_pass"] = "Password";
        strings_["transaction_url"] = "Transaction URL";
        strings_["address_url"] = "Address URL";
        strings_["custom_fees"] = "Allow custom transaction fees";
        strings_["fetch_prices"] = "Fetch price data from CoinGecko";
        strings_["block_explorer"] = "Block Explorer";
        strings_["test_connection"] = "Test Connection";
        strings_["rescan"] = "Rescan";
        
        // Settings: buttons
        strings_["settings_address_book"] = "Address Book…";
        strings_["settings_validate_address"] = "Validate Address…";
        strings_["settings_request_payment"] = "Request Payment…";
        strings_["settings_shield_mining"] = "Shield Mining…";
        strings_["settings_merge_to_address"] = "Merge to Address…";
        strings_["settings_clear_ztx"] = "Clear Z-Tx History";
        strings_["settings_import_key"] = "Import Private Key…";
        strings_["settings_import_viewkey"] = "Import Viewing Key…";
        strings_["settings_export_key"] = "Export Key…";
        strings_["settings_export_all"] = "Export All…";
        strings_["settings_backup"] = "Backup…";
        strings_["settings_export_csv"] = "Export CSV…";
        strings_["settings_encrypt_wallet"] = "Encrypt Wallet";
        strings_["settings_change_passphrase"] = "Change Passphrase";
        strings_["settings_lock_now"] = "Lock Now";
        strings_["settings_remove_encryption"] = "Remove Encryption";
        strings_["settings_set_pin"] = "Set PIN";
        strings_["settings_change_pin"] = "Change PIN";
        strings_["settings_remove_pin"] = "Remove PIN";
        strings_["settings_restart_daemon"] = "Restart daemon";
        strings_["clear_anyway"] = "Clear Anyway";
        
        // Settings: labels / text
        strings_["settings_builtin"] = "Built-in";
        strings_["settings_custom"] = "Custom";
        strings_["settings_not_found"] = "Not found";
        strings_["settings_idle_after"] = "after";
        strings_["settings_not_encrypted"] = "Not encrypted";
        strings_["settings_locked"] = "Locked";
        strings_["settings_unlocked"] = "Unlocked";
        strings_["settings_quick_unlock_pin"] = "Quick-unlock PIN";
        strings_["settings_pin_active"] = "PIN";
        strings_["settings_encrypt_first_pin"] = "Encrypt wallet first to enable PIN";
        strings_["incorrect_pin"] = "Incorrect PIN";
        strings_["incorrect_passphrase"] = "Incorrect passphrase";
        strings_["pin_not_set"] = "PIN not set. Use passphrase to unlock.";
        strings_["restarting_after_encryption"] = "Restarting daemon after encryption...";
        strings_["force_quit"] = "Force Quit";
        strings_["force_quit_warning"] = "This will immediately kill the daemon without a clean shutdown. May require a blockchain resync.";
        strings_["force_quit_confirm_title"] = "Force Quit?";
        strings_["force_quit_confirm_msg"] = "This will immediately kill the daemon without a clean shutdown.\nThis may corrupt the blockchain index and require a resync.";
        strings_["force_quit_yes"] = "Force Quit";
        strings_["reduce_motion"] = "Reduce Motion";
        strings_["tt_reduce_motion"] = "Disable animated transitions and balance lerp for accessibility";
        strings_["ago"] = "ago";
        strings_["wizard_daemon_start_failed"] = "Failed to start daemon \xe2\x80\x94 it will be retried automatically";
        // First-run wizard (app_wizard.cpp). Bootstrap/appearance labels reuse existing keys; these are
        // the wizard-specific strings.
        strings_["wiz_welcome_title"] = "Welcome to ObsidianDragon!";
        strings_["wiz_welcome_sub"] = "A few quick choices and your full node is ready.";
        strings_["wiz_step1"] = "Step 1";
        strings_["wiz_step2"] = "Step 2";
        strings_["wiz_step3"] = "Step 3";
        strings_["wiz_appearance"] = "Appearance";
        strings_["wiz_theme_builtin"] = "Built-in";
        strings_["wiz_theme_custom"] = "Custom";
        strings_["wiz_theme_invalid"] = " (invalid)";
        strings_["wiz_lowspec_desc"] = "Disable all heavy visual effects";
        strings_["wiz_acrylic"] = "Acrylic glass effects";
        strings_["wiz_acrylic_desc"] = "Translucent blur on panels (Off disables)";
        strings_["wiz_level"] = "Level:";
        strings_["wiz_off"] = "Off";
        strings_["wiz_theme_effects"] = "Theme visual effects";
        strings_["wiz_theme_effects_desc"] = "Animated borders, color wash";
        strings_["wiz_ui_opacity_desc"] = "Card & sidebar transparency (1.0 = solid)";
        strings_["wiz_scanline_desc"] = "CRT scanline effect in console";
        strings_["wiz_bootstrap"] = "Bootstrap";
        strings_["wiz_bootstrap_desc"] = "Download a blockchain bootstrap to dramatically speed up initial sync.\n\nYour existing wallet.dat will NOT be modified or replaced.";
        strings_["wiz_skip"] = "Skip";
        strings_["wiz_bootstrap_failed"] = "Bootstrap failed";
        strings_["wiz_download_failed"] = "Download Failed";
        strings_["wiz_ext_daemon_running"] = "External daemon running";
        strings_["wiz_ext_daemon_warning"] = "It must be stopped before downloading a bootstrap, otherwise chain data could be corrupted.";
        strings_["wiz_stop_daemon"] = "Stop Daemon";
        strings_["wiz_daemon_sending_stop"] = "Sending stop command...";
        strings_["wiz_daemon_waiting_stop"] = "Waiting for daemon to shut down...";
        strings_["wiz_daemon_stopped_ok"] = "Daemon stopped.";
        strings_["wiz_daemon_stop_failed"] = "Daemon did not stop \xe2\x80\x94 try manually.";
        strings_["wiz_encryption"] = "Encryption";
        strings_["wiz_pin_title"] = "Quick-Unlock PIN";
        strings_["wiz_already_encrypted"] = "Wallet is already encrypted";
        strings_["wiz_already_encrypted_desc"] = "Your wallet is protected with a passphrase. No further action is needed.";
        strings_["wiz_continue"] = "Continue";
        strings_["wiz_encrypt_desc"] = "Encrypt your wallet to protect private keys with a passphrase.";
        strings_["wiz_encrypt_warning"] = "If you lose your passphrase, you lose access to your funds.";
        strings_["wiz_passphrase"] = "Passphrase:";
        // --- Encrypt / change-passphrase dialogs (settings) ---
        strings_["enc_desc"] = "Encrypting your wallet protects your private keys with a passphrase. After encryption, the daemon will restart.";
        strings_["enc_confirm"] = "Confirm:";
        strings_["enc_encrypting"] = "Encrypting wallet...";
        strings_["enc_wait"] = "Please wait, do not close the application.";
        strings_["enc_success"] = "Wallet encrypted successfully!";
        strings_["enc_pin_desc"] = "A 4-8 digit PIN lets you unlock your wallet without typing the full passphrase every time.";
        strings_["enc_pin_set_ok"] = "PIN set successfully";
        strings_["enc_pin_vault_fail"] = "Failed to create PIN vault";
        strings_["enc_pin_skipped"] = "PIN skipped. You can set one later in Settings.";
        strings_["change_pass_title"] = "Change Passphrase";
        strings_["change_pass_current"] = "Current Passphrase:";
        strings_["change_pass_new"] = "New Passphrase:";
        strings_["change_pass_confirm"] = "Confirm New:";
        // --- Remove-encryption (decrypt) dialog (settings) ---
        strings_["decrypt_title"] = "Remove Wallet Encryption";
        strings_["decrypt_warning"] = "This will remove encryption from your wallet. Your private keys will be stored unprotected on disk.";
        strings_["decrypt_desc"] = "The wallet will be exported, the daemon restarted with a fresh unencrypted wallet, and all keys re-imported. This may take several minutes depending on wallet size.";
        strings_["decrypt_step_unlock"] = "Unlocking wallet";
        strings_["decrypt_step_export"] = "Exporting wallet keys";
        strings_["decrypt_step_stop"] = "Stopping daemon";
        strings_["decrypt_step_backup"] = "Backing up encrypted wallet";
        strings_["decrypt_step_restart"] = "Restarting daemon";
        strings_["decrypt_wait_restart"] = "Waiting for the daemon to finish starting up...";
        strings_["decrypt_wait_general"] = "Please wait. The daemon is exporting keys, restarting, and re-importing. This may take several minutes.";
        strings_["decrypt_success_title"] = "Wallet decrypted successfully!";
        strings_["decrypt_success_desc"] = "Your wallet is now unencrypted. A backup of the encrypted wallet was saved as wallet.dat.encrypted.bak in your data directory.";
        strings_["decrypt_error_title"] = "Decryption failed";
        strings_["try_again"] = "Try Again";
        // --- PIN setup / change / remove dialogs (settings) ---
        strings_["pin_setup_desc"] = "Set a 4-8 digit PIN for quick wallet unlock. Your wallet passphrase will be encrypted with this PIN and stored locally.";
        strings_["pin_wallet_passphrase"] = "Wallet Passphrase:";
        strings_["pin_new_label"] = "New PIN (4-8 digits):";
        strings_["pin_change_desc"] = "Change your unlock PIN. You need your current PIN and a new PIN.";
        strings_["pin_current_label"] = "Current PIN:";
        strings_["pin_confirm_new_label"] = "Confirm New PIN:";
        strings_["pin_remove_desc"] = "Enter your current PIN to confirm removal. You will need to use your full passphrase to unlock.";
        strings_["wiz_confirm"] = "Confirm:";
        strings_["wiz_strength_weak"] = "Weak";
        strings_["wiz_strength_fair"] = "Fair";
        strings_["wiz_strength_good"] = "Good";
        strings_["wiz_strength_strong"] = "Strong";
        strings_["wiz_strength"] = "Strength: %s";
        strings_["wiz_pass_too_short"] = "Passphrase must be at least 8 characters (%zu/8)";
        strings_["wiz_pass_mismatch"] = "Passphrases do not match";
        strings_["wiz_pass_spaces"] = "Passphrase has leading/trailing spaces \xe2\x80\x94 remove them";
        strings_["wiz_encrypt_continue"] = "Encrypt & Continue";
        strings_["wiz_encrypt_bg"] = "Encryption will complete in the background";
        strings_["wiz_skip_confirm"] = "Continue WITHOUT encryption? Keys will be stored unencrypted \xe2\x80\x94 click Skip again to confirm.";
        strings_["wiz_pin_optional"] = "Quick-Unlock PIN (optional)";
        strings_["wiz_pin_label"] = "PIN (4-8 digits):";
        strings_["wiz_pin_confirm"] = "Confirm PIN:";
        strings_["wiz_pin_invalid"] = "PIN must be 4-8 digits";
        strings_["wiz_pin_mismatch"] = "PINs do not match";
        strings_["settings_data_dir"] = "Data Dir";
        strings_["settings_wallet_size_label"] = "Wallet Size";
        strings_["wallet_size_warn"] = "This wallet file is large. Consolidating your notes can curb further growth.";
        strings_["tt_wallet_size_warn"] = "Shielded wallets grow with each note's witness data — merging many notes into one address reduces it. Back up first.";
        strings_["wallet_size_consolidate"] = "Consolidate notes\xE2\x80\xA6";
        strings_["settings_debug_changed"] = "Debug categories changed \xe2\x80\x94 restart daemon to apply";
        strings_["settings_auto_detected"] = "Auto-detected from DRAGONX.conf";
        strings_["settings_visual_effects"] = "Visual Effects";
        strings_["settings_acrylic_level"] = "Acrylic Level:";
        strings_["settings_noise_opacity"] = "Noise Opacity:";
        strings_["settings_privacy"] = "Privacy";
        strings_["settings_other"] = "Other";
        strings_["settings_rpc_connection"] = "RPC Connection";
        strings_["settings_configure_rpc"] = "Configure connection to dragonxd daemon";
        strings_["settings_wallet_maintenance"] = "Wallet Maintenance";
        strings_["settings_wallet_info"] = "Wallet Info";
        strings_["settings_block_explorer_urls"] = "Block Explorer URLs";
        strings_["settings_configure_explorer"] = "Configure external block explorer links";
        strings_["settings_auto_lock"] = "Auto-lock";
        strings_["timeout_off"] = "Off";
        strings_["timeout_1min"] = "1 min";
        strings_["timeout_5min"] = "5 min";
        strings_["timeout_15min"] = "15 min";
        strings_["timeout_30min"] = "30 min";
        strings_["timeout_1hour"] = "1 hour";
        strings_["slider_off"] = "Off";
        strings_["settings_wallet_file_size"] = "Wallet file size: %s";
        strings_["settings_wallet_location"] = "Wallet location: %s";
        strings_["settings_rpc_note"] = "Note: Connection settings are usually auto-detected from DRAGONX.conf";
        strings_["settings_explorer_hint"] = "URLs should include a trailing slash. The txid/address will be appended.";
        strings_["settings_connection"] = "Connection";
        strings_["settings_reduce_transparency"] = "Reduce transparency";
        strings_["settings_save_shielded_local"] = "Save shielded transaction history locally";
        strings_["settings_auto_shield_funds"] = "Auto-shield transparent funds";
        strings_["settings_use_tor_network"] = "Use Tor for network connections";
        strings_["settings_gradient_bg"] = "Gradient bg";
        
        // Settings: tooltips
        strings_["tt_theme_hotkey"] = "Hotkey: Ctrl+Left/Right to cycle themes";
        strings_["tt_layout_hotkey"] = "Hotkey: Left/Right arrow keys to cycle Balance layouts";
        strings_["tt_language"] = "Interface language for the wallet UI";
        strings_["tt_scan_themes"] = "Scan for new themes.\nPlace theme folders in:\n%s";
        strings_["tt_low_spec"] = "Disable all heavy visual effects\nHotkey: Ctrl+Shift+Down";
        strings_["tt_simple_bg"] = "Use a simple gradient for the background\nHotkey: Ctrl+Up";
        strings_["tt_simple_bg_alt"] = "Use a gradient version of the theme background image\nHotkey: Ctrl+Up";
        strings_["tt_scanline"] = "CRT scanline effect in console";
        strings_["tt_theme_effects"] = "Shimmer, glow, hue-cycling per theme";
        strings_["tt_animate_avatars"] = "Play animated (GIF / WebP) contact avatars; off shows the first frame only";
        strings_["tt_blur"] = "Blur amount (0% = off, 100% = maximum)";
        strings_["tt_noise"] = "Grain texture intensity (0% = off, 100% = maximum)";
        strings_["tt_ui_opacity"] = "Card and sidebar opacity (100% = fully opaque, lower = more see-through)";
        strings_["tt_window_opacity"] = "Background opacity (lower = desktop visible through window)";
        strings_["tt_font_scale"] = "Scale all text and UI (1.0x = default, up to 1.5x). Hotkey: Alt + Scroll Wheel";
        strings_["tt_custom_theme"] = "Custom theme active";
        strings_["tt_address_book"] = "Manage saved addresses for quick sending";
        strings_["tt_validate"] = "Check if a DragonX address is valid";
        strings_["tt_request_payment"] = "Generate a payment request with QR code";
        strings_["tt_shield_mining"] = "Move transparent mining rewards to a shielded address";
        strings_["tt_merge"] = "Consolidate multiple UTXOs into one address";
        strings_["tt_clear_ztx"] = "Delete locally cached z-transaction history";
        strings_["tt_save_ztx"] = "Store z-address transaction history locally for faster loading";
        strings_["tt_auto_shield"] = "Automatically move transparent balance to shielded addresses for privacy";
        strings_["tt_tor"] = "Route daemon connections through the Tor network for anonymity";
        strings_["tt_keep_daemon"] = "Daemon will still stop when running the setup wizard";
        strings_["tt_stop_external"] = "Applies when connecting to a daemon\nyou started outside this wallet";
        strings_["stratum_host_section"] = "MINING POOL HOSTING";
        strings_["stratum_host"] = "Host a mining pool (stratum)";
        strings_["tt_stratum_host"] = "Run a RandomX stratum pool server on this node so other RandomX miners can point at this computer. Requires a v1.3.0+ node and a daemon restart to apply.";
        strings_["stratum_host_hint"] = "Miners connect to this computer on port 22769 (RPC port + 1000) with a RandomX stratum miner. Restart the daemon to apply.";
        strings_["stratum_allowip_hint"] = "Allow miners from IP or CIDR (blank = this computer only)";
        strings_["stratum_expose_warn"] = "Opens a mining port to the network you allow — only use on a trusted LAN.";
        strings_["tt_verbose"] = "Log detailed connection diagnostics,\ndaemon state, and port owner info\nto the Console tab";
        strings_["tt_mine_idle"] = "Automatically start mining when the\nsystem is idle (no keyboard/mouse input)";
        strings_["tt_idle_delay"] = "How long to wait before starting mining";
        strings_["tt_wizard"] = "Re-run the initial setup wizard\nDaemon will be restarted";
        strings_["tt_download_bootstrap"] = "Download blockchain bootstrap to speed up sync\nExisting block data will be replaced";
        // --- Full-node Node & Security tooltips ---
        strings_["tt_rpc_toggle"] = "Show or hide the read-only RPC connection details (host, port, user, password) for the daemon";
        strings_["tt_daemon_refresh"] = "Re-read the installed and bundled dragonxd version, size, and date shown above";
        // --- Lite wallet Node & Security tooltips ---
        strings_["tt_lite_lifecycle_toggle"] = "Show or hide the create / open / restore controls for managing your lite wallet file";
        strings_["tt_lite_lifecycle_op"] = "Choose whether to create a new wallet, open an existing one, or restore one from a seed phrase";
        strings_["tt_lite_wallet_path"] = "Path or name of the wallet file to open or restore into";
        strings_["tt_lite_restore_seed"] = "The 24-word recovery seed phrase to restore this wallet from; hidden as you type";
        strings_["tt_lite_restore_birthday"] = "Block height the wallet was created at; scanning starts here. Use 0 or the earliest height if unsure";
        strings_["tt_lite_restore_account"] = "HD account index to restore; leave 0 unless you used multiple accounts under this seed";
        strings_["tt_lite_restore_overwrite"] = "Replace an existing wallet file with this restore. Warning: overwrites the current wallet data";
        strings_["tt_lite_lifecycle_pass"] = "Passphrase to unlock or set on the wallet during this create / open / restore operation";
        strings_["tt_lite_lifecycle_run"] = "Run the selected create / open / restore operation with the values above";
        strings_["tt_lite_show_seed"] = "Reveal this wallet's recovery seed phrase and birthday. Anyone with the seed can spend your funds";
        strings_["tt_lite_show_keys"] = "Reveal this wallet's private spending keys. Anyone with a key can spend the funds it controls";
        strings_["tt_lite_copy"] = "Copy the revealed secret to the clipboard";
        strings_["tt_lite_save_seed_file"] = "Write the seed and birthday to an owner-only file (lite-seed-backup.txt) in the config folder";
        strings_["tt_lite_hide_wipe"] = "Hide the revealed secret and securely wipe it from memory";
        strings_["tt_lite_import_key"] = "Paste a private spending or viewing key to import; its history appears after the next sync";
        strings_["tt_lite_import_key_btn"] = "Import the entered private key into this wallet; funds and history appear after the next sync";
        strings_["tt_lite_encrypt_pass"] = "Passphrase to encrypt the wallet with. If lost, the wallet cannot be unlocked or recovered";
        strings_["tt_lite_encrypt"] = "Encrypt the wallet with the passphrase above; it locks immediately and requires the passphrase to unlock";
        strings_["tt_lite_unlock_pass"] = "Enter your passphrase to unlock the encrypted wallet";
        strings_["tt_lite_unlock"] = "Unlock the encrypted wallet using the passphrase above";
        strings_["tt_lite_lock"] = "Lock the wallet now; a passphrase is required to unlock and any chat session is torn down";
        strings_["tt_lite_decrypt_pass"] = "Enter your passphrase to remove encryption from the wallet";
        strings_["tt_lite_remove_encrypt"] = "Remove encryption and store the wallet unprotected; no passphrase will be required to open it";
        // --- Chat & Contacts tooltips ---
        strings_["tt_chat_emoji_style"] = "Render emoji in monochrome outline or full color";
        strings_["tt_chat_bubble_style"] = "Message bubble shape: rounded, square, or minimal (flat, borderless)";
        strings_["tt_chat_bubble_accent"] = "Accent color for your outgoing message bubbles (or follow the current theme)";
        strings_["tt_chat_density"] = "Spacing between messages: Comfortable adds more padding; Compact fits more on screen";
        strings_["tt_chat_font_size"] = "Scale chat message text from 0.8x to 1.5x. Affects only the Chat tab, not the rest of the app";
        strings_["tt_chat_poll_rate"] = "How often to check for new and 0-conf messages (0.5-15 s). Faster is more responsive but uses more CPU";
        strings_["tt_chat_timestamp"] = "Timestamp format for this tab only: follow the app-wide clock, or force 24-hour or 12-hour";
        strings_["tt_chat_enter_sends"] = "When on, Enter sends the message and Shift+Enter adds a newline; when off, Enter adds a newline";
        // --- Debug Options tooltips ---
        strings_["tt_screenshot_sweep"] = "Cycle every theme across every tab, saving a screenshot of each into the config screenshots folder (overwrites the last sweep)";
        strings_["tt_screenshot_sweep_full"] = "Like the theme sweep but also captures every modal / dialog / flow using temporary offline demo wallet data";
        strings_["tt_screenshot_open_dir"] = "Open the screenshots folder (under the config directory) in your file manager";
        strings_["tt_seed_demo_chat"] = "Inject sample conversations into the Chat tab so a sweep captures its UI; in-memory only, gone on restart";
        strings_["download_bootstrap"] = "Download Bootstrap";
        strings_["download"] = "Download";
        strings_["retry"] = "Retry";
        strings_["bootstrap_desc"] = "Download a blockchain bootstrap to dramatically speed up initial sync. This downloads a snapshot of the blockchain and extracts it into your data directory.";
        strings_["bootstrap_warning"] = "Existing block data (blocks, chainstate, notarizations) will be deleted and replaced. Your wallet.dat will NOT be modified or deleted.";
        strings_["bootstrap_trust_warning"] = "Only use bootstrap.dragonx.is or bootstrap2.dragonx.is. Using files from untrusted sources could compromise your node.";
        strings_["bootstrap_mirror"] = "Mirror";
        strings_["bootstrap_mirror_tooltip"] = "Download from mirror (bootstrap2.dragonx.is).\nUse this if the main download is slow or failing.";
        strings_["bootstrap_downloading"] = "Downloading bootstrap...";
        strings_["bootstrap_verifying"] = "Verifying checksums...";
        strings_["bootstrap_extracting"] = "Extracting blockchain data...";
        strings_["bootstrap_wallet_protected"] = "(wallet.dat is protected)";
        strings_["bootstrap_daemon_stopping"] = "Daemon stopping...";
        strings_["bootstrap_daemon_running"] = "Daemon running";
        strings_["bootstrap_daemon_stopped"] = "Daemon stopped";
        strings_["bootstrap_success"] = "Bootstrap Complete";
        strings_["bootstrap_success_desc"] = "Blockchain data has been extracted successfully. Start the daemon to begin syncing from the bootstrap point.";
        strings_["bootstrap_restart_daemon"] = "Restart Daemon";
        strings_["bootstrap_failed"] = "Bootstrap Failed";
        strings_["tt_open_dir"] = "Click to open in file explorer";
        strings_["settings_open_data_dir"] = "Open data folder";
        strings_["tt_open_data_dir"] = "Open the folder with your wallet and blockchain data in the file manager";
        strings_["settings_open_app_dir"] = "Open app folder";
        strings_["tt_open_app_dir"] = "Open the ObsidianDragon folder (settings, themes, logs) in the file manager";
        strings_["tt_rpc_host"] = "Hostname of the DragonX daemon";
        strings_["tt_rpc_user"] = "RPC authentication username";
        strings_["tt_rpc_port"] = "Port for daemon RPC connections";
        strings_["tt_rpc_pass"] = "RPC authentication password";
        strings_["tt_test_conn"] = "Verify the RPC connection to the daemon";
        strings_["tt_rescan"] = "Rescan the blockchain for missing transactions";
        strings_["tt_delete_blockchain"] = "Delete all blockchain data and start a fresh sync. Your wallet.dat and config are preserved.";
        strings_["delete_blockchain"] = "Delete Blockchain";
        strings_["delete_blockchain_confirm"] = "Delete & Resync";
        strings_["confirm_delete_blockchain_title"] = "Delete Blockchain Data";
        strings_["confirm_delete_blockchain_msg"] = "This will stop the daemon, delete all blockchain data (blocks, chainstate, peers), and start a fresh sync from scratch. This can take several hours to complete.";
        strings_["confirm_delete_blockchain_safe"] = "Your wallet.dat, config, and transaction history are safe and will not be deleted.";
        strings_["confirm_rescan_title"] = "Rescan Blockchain";
        strings_["confirm_rescan_msg"] = "This restarts the daemon and re-scans the entire blockchain for your wallet's transactions. It can take a long time and the wallet stays offline until it finishes.";
        strings_["confirm_rescan_safe"] = "Your wallet.dat and blockchain data are not deleted — only re-scanned.";
        strings_["rescan_detecting"] = "Checking which blocks your node has on disk…";
        strings_["rescan_bootstrapped_msg"] = "Your node was bootstrapped, so blocks below the snapshot aren't on disk and a rescan from genesis would fail. Rescan from a height your snapshot includes to reconcile your wallet's spent balance. Your wallet.dat and chain data are not deleted.";
        strings_["rescan_from_height"] = "Rescan from block height:";
        strings_["repair_wallet"] = "Repair";
        strings_["tt_repair_wallet"] = "Wipe and rebuild the wallet's transaction records from the blockchain (fixes notes that fail to send after a rescan)";
        strings_["confirm_repair_wallet_title"] = "Repair Wallet";
        strings_["confirm_repair_wallet_msg"] = "This restarts the daemon with -zapwallettxes=2: it deletes all of the wallet's transaction and note records, then rebuilds them from the blockchain. Use this when transactions fail to build (\"Invalid sapling spend proof\" / \"shielded requirements not met\") even after a full rescan. It takes a long time and the wallet stays offline until it finishes.";
        strings_["confirm_repair_wallet_safe"] = "Your keys, addresses and balance are preserved — only the cached transaction records are rebuilt.";
        strings_["daemon_binary"] = "Daemon binary";
        strings_["daemon_updates_label"] = "UPDATES";
        strings_["daemon_maintenance_label"] = "MAINTENANCE";
        strings_["daemon_installed"] = "Installed";
        strings_["daemon_bundled"] = "Bundled";
        strings_["daemon_not_installed"] = "not installed";
        strings_["daemon_none_bundled"] = "none in this build";
        strings_["daemon_status_match"] = "Installed binary matches the bundled version.";
        strings_["daemon_status_differ"] = "Installed binary differs from the bundled version.";
        strings_["daemon_status_missing"] = "No daemon installed — install the bundled version.";
        // Compact status shown right-aligned on the DAEMON BINARY heading row.
        strings_["daemon_status_ok"]   = "Up to date";
        strings_["daemon_status_diff"] = "Version differs";
        strings_["daemon_status_none"] = "Not installed";
        strings_["daemon_install_bundled"] = "Install bundled";
        strings_["tt_daemon_install_bundled"] = "Stop the node, overwrite the installed dragonxd with the version bundled in this wallet build, then restart";
        strings_["confirm_reinstall_daemon_title"] = "Install Bundled Daemon";
        strings_["confirm_reinstall_daemon_msg"] = "This stops the daemon, overwrites the installed dragonxd (and dragonx-cli/dragonx-tx) with the versions bundled in this wallet build, then restarts the node. Use this to recover or update the node binary.";
        strings_["confirm_reinstall_daemon_safe"] = "Your wallet, keys and blockchain data are not touched — only the daemon program files are replaced.";
        strings_["daemon_update_prompt_title"] = "Update the node daemon?";
        strings_["daemon_update_body"] = "This wallet build bundles a newer DragonX node than the one currently installed. Updating replaces the installed dragonxd (and dragonx-cli/dragonx-tx), then stops and restarts the node so the new version takes effect. Recommended — a newer node can add features (e.g. seed-phrase support) the old one lacks.";
        strings_["daemon_update_safe"] = "Your wallet, keys and blockchain data are not touched — only the daemon program files are replaced. If you deliberately run a custom node, choose Keep current.";
        strings_["daemon_update_now"] = "Update now";
        strings_["daemon_update_keep"] = "Keep current";
        strings_["confirm_restart_daemon_title"] = "Restart Daemon";
        strings_["confirm_restart_daemon_msg"] = "This stops and restarts the daemon to apply the changed options. The wallet will briefly disconnect and reconnect.";
        strings_["lite_maintenance"] = "Maintenance";
        strings_["lite_redownload_blocks"] = "Redownload blocks";
        strings_["lite_redownload_desc"] = "Re-fetch all blocks from the lite server (use if your balance or history looks wrong).";
        strings_["lite_redownload_running"] = "Re-downloading blocks…";
        strings_["tt_lite_redownload"] = "Re-download and re-scan all blocks from the lite server";
        strings_["confirm_lite_redownload_title"] = "Redownload Blocks";
        strings_["confirm_lite_redownload_msg"] = "This clears the wallet's downloaded block data and re-fetches and re-scans every block from the lite server. It can take a while; the wallet shows sync progress until it finishes.";
        strings_["confirm_lite_redownload_safe"] = "Your wallet, keys, and seed are not affected — only the block data is re-downloaded.";
        // Lite wallet lifecycle / backup / security section
        strings_["lite_servers_network_tab"] = "Lite servers are managed in the Network tab.";
        strings_["lite_wallet_request"] = "Lite wallet request";
        strings_["lite_action"] = "Action";
        strings_["lite_op_create"] = "Create";
        strings_["lite_op_open"] = "Open";
        strings_["lite_op_restore"] = "Restore";
        strings_["lite_wallet_label"] = "Wallet";
        strings_["lite_seed_label"] = "Seed";
        strings_["lite_word_count"] = "%d / 24 words";
        strings_["lite_birthday_label"] = "Birthday";
        strings_["lite_birthday_hint"] = "Block height to start scanning from. Leave 0 if unknown (slower full scan).";
        strings_["lite_account_label"] = "Account";
        strings_["lite_overwrite"] = "Overwrite";
        strings_["lite_passphrase_label"] = "Passphrase";
        strings_["lite_validate"] = "Validate";
        strings_["lite_working"] = "Working…";
        strings_["lite_enter_wallet_path"] = "Enter a wallet path";
        strings_["lite_enter_all_seed_words"] = "Enter all 24 seed words to restore (got %d)";
        strings_["lite_could_not_start"] = "Could not start the operation";
        strings_["lite_backend_unavailable"] = "Lite wallet backend unavailable";
        strings_["lite_wallet_ready"] = "Wallet ready";
        strings_["lite_backup_keys"] = "Backup & keys";
        strings_["lite_show_seed"] = "Show seed";
        strings_["lite_seed_warning"] = "Seed phrase — the ONLY way to restore your wallet. Write it down, store it offline, never share it.";
        strings_["lite_show_private_keys"] = "Show private keys";
        strings_["lite_private_keys_warning"] = "Private keys — anyone with these can spend your funds";
        strings_["lite_birthday_backup"] = "Birthday: %llu  (back this up too)";
        strings_["lite_copy"] = "Copy";
        strings_["lite_save_to_file"] = "Save to file";
        strings_["lite_saved_to"] = "Saved (plaintext, owner-only) to ";
        strings_["lite_could_not_write"] = "Could not write ";
        strings_["lite_hide_wipe"] = "Hide & wipe";
        strings_["lite_import_key_label"] = "Import key";
        strings_["lite_import"] = "Import";
        strings_["lite_key_imported"] = "Key imported — run a sync to scan its history";
        strings_["lite_security"] = "Security";
        strings_["lite_encrypt_wallet"] = "Encrypt wallet";
        strings_["lite_wallet_encrypted"] = "Wallet encrypted";
        strings_["lite_unlock"] = "Unlock";
        strings_["lite_wallet_unlocked"] = "Wallet unlocked";
        strings_["lite_unlock_failed"] = "Unlock failed";
        strings_["lite_lock_now"] = "Lock now";
        strings_["lite_wallet_locked"] = "Wallet locked";
        strings_["lite_lock_failed"] = "Lock failed";
        strings_["lite_remove_encryption"] = "Remove encryption";
        strings_["lite_encryption_removed"] = "Encryption removed";
        strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
        strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
        strings_["tt_lock"] = "Lock the wallet immediately";
        strings_["tt_remove_encrypt"] = "Remove encryption and store wallet unprotected";
        strings_["tt_auto_lock"] = "Lock wallet after this much inactivity";
        strings_["tt_set_pin"] = "Set a 4-8 digit PIN for quick unlock";
        strings_["tt_change_pin"] = "Change your unlock PIN";
        strings_["tt_remove_pin"] = "Remove PIN and require passphrase to unlock";
        strings_["tt_tx_url"] = "Base URL for viewing transactions in a block explorer";
        strings_["tt_addr_url"] = "Base URL for viewing addresses in a block explorer";
        strings_["tt_custom_fees"] = "Enable manual fee entry when sending transactions";
        strings_["tt_fetch_prices"] = "Retrieve DRGX market prices from CoinGecko API";
        strings_["tt_block_explorer"] = "Open the DragonX block explorer in your browser";
        strings_["tt_website"] = "Open the DragonX website";
        strings_["tt_report_bug"] = "Report an issue on the project tracker";
        strings_["tt_save_settings"] = "Save all settings to disk";
        strings_["tt_reset_settings"] = "Reload settings from disk (undo unsaved changes)";
        strings_["tt_debug_collapse"] = "Collapse debug logging options";
        strings_["tt_debug_expand"] = "Expand debug logging options";
        strings_["tt_restart_daemon"] = "Restart the daemon to apply debug logging changes";
        
        // Settings: additional tooltips (keys/data row)
        strings_["tt_import_key"] = "Import a private key (zkey or tkey) into this wallet";
        strings_["tt_import_viewkey"] = "Import a shielded viewing key to watch an address (read-only)";
        strings_["tt_export_key"] = "Export the private key for the selected address";
        strings_["tt_export_all"] = "Export all private keys to a file";
        strings_["tt_backup"] = "Create a backup of your wallet.dat file";
        strings_["tt_export_csv"] = "Export transaction history as a CSV spreadsheet";
        
        // Settings: about / debug
        strings_["settings_about_text"] = "A shielded cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui for a lightweight, portable experience.";
        strings_["settings_copyright"] = "Copyright 2024-2026 DragonX Developers  |  GPLv3 License";
        strings_["debug_logging"] = "DEBUG OPTIONS";
        strings_["settings_debug_select"] = "Select categories to enable daemon debug logging (-debug= flags).";
        strings_["settings_debug_restart_note"] = "Changes take effect after restarting the daemon.";
        // Debug-options gate (confirmation + optional re-auth)
        strings_["debug_gate_title"] = "Show debug options?";
        strings_["debug_gate_warning"] = "These are advanced diagnostic and node-tuning options. They can expose sensitive information and change how your node runs. Only continue if you know what you're doing.";
        strings_["debug_gate_pin_prompt"] = "Enter your unlock PIN to continue:";
        strings_["debug_gate_pass_prompt"] = "Enter your wallet passphrase to continue:";
        strings_["debug_gate_confirm"] = "Show debug options";
        strings_["debug_gate_incorrect"] = "Incorrect PIN or passphrase.";
        strings_["debug_gate_verifying"] = "Verifying\xE2\x80\xA6";
        
        // Settings window (legacy dialog) descriptions
        strings_["settings_language_note"] = "Note: Some text requires restart to update";
        strings_["settings_solid_colors_desc"] = "Use solid colors instead of blur effects (accessibility)";
        strings_["settings_gradient_desc"] = "Replace textured backgrounds with smooth gradients";
        strings_["settings_save_shielded_desc"] = "Stores z-addr transactions in a local file for viewing";
        strings_["settings_auto_shield_desc"] = "Automatically move transparent funds to shielded addresses";
        strings_["settings_tor_desc"] = "Route all connections through Tor for enhanced privacy";
        strings_["settings_rescan_desc"] = "Rescan blockchain for missing transactions";
        strings_["settings_clear_ztx_long"] = "Clear Saved Z-Transaction History";
        strings_["settings_clear_ztx_desc"] = "Delete locally stored shielded transaction data";
        strings_["settings_wallet_not_found"] = "Wallet file not found";
        
        // Balance tab: address actions
        strings_["hide_zero_balances"] = "Hide 0 Balances";
        strings_["restore_address"] = "Restore Address";
        strings_["hide_address"] = "Hide Address";
        strings_["remove_favorite"] = "Remove Favorite";
        strings_["favorite_address"] = "Favorite Address";
        strings_["show_hidden"] = "Show Hidden (%d)";
        strings_["filter"] = "Filter...";
        strings_["no_addresses_yet"] = "No addresses yet";
        strings_["showing_x_of_y"] = "Showing %d of %d addresses";
        strings_["set_label"] = "Set Label";
        strings_["copied"] = "Copied!";
        strings_["hidden_tag"] = " (hidden)";
        strings_["z_address"] = "Z-Address";
        strings_["t_address"] = "T-Address";
        strings_["shielded_address"] = "Shielded Address";
        strings_["transparent_address"] = "Transparent Address";
        strings_["label_placeholder"] = "e.g. Savings, Mining...";
        strings_["choose_icon"] = "Choose Icon";
        strings_["clear_icon"] = "Clear Icon";
        strings_["search_icons"] = "Search icons...";
        strings_["no_icons_found"] = "No icons match your search.";
        strings_["transfer_funds"] = "Transfer Funds";
        strings_["transfer_to"] = "Transfer to:";
        strings_["address_reorder_hint"] = "Drop on a row's edge to reorder, or its centre to transfer";
        strings_["deshielding_warning"] = "Warning: This will de-shield funds from a private (Z) address to a transparent (T) address.";
        strings_["shielding_notice"] = "Note: This will shield funds from a transparent (T) address to a private (Z) address.";
        strings_["result_preview"] = "Result Preview";
        strings_["sender_balance"] = "Sender: %.8f \xe2\x86\x92 %.8f DRGX";
        strings_["recipient_balance"] = "Recipient: %.8f \xe2\x86\x92 %.8f DRGX";
        strings_["insufficient_funds"] = "Insufficient funds for this amount plus fee.";
        strings_["sends_full_balance_warning"] = "This sends the full balance. The sending address will have a zero balance.";
        strings_["confirm_transfer"] = "Confirm Transfer";
        strings_["transfer_sent"] = "Transfer Sent";
        strings_["transfer_sent_desc"] = "Your transfer has been submitted to the network.";
        strings_["transfer_failed"] = "Transfer Failed";
        
        // Misc dialog strings
        strings_["shield_operation_id"] = "Operation ID: %s";
        strings_["peers_peer_label"] = "Peer: %s";
        strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
        strings_["backup_source"] = "Source: %s";
        strings_["export_keys_progress"] = "Exporting %d/%d...";
        strings_["import_key_progress"] = "Importing %d/%d...";
        strings_["block_click_copy"] = "Click to copy";
        strings_["confirm_clear_ztx_title"] = "Confirm Clear Z-Tx History";
        strings_["confirm_clear_ztx_warning1"] = "Clearing z-transaction history may cause your shielded balance to show as 0 until a wallet rescan is performed.";
        strings_["confirm_clear_ztx_warning2"] = "If this happens, you will need to re-import your z-address private keys with rescan enabled to recover your balance.";
        
        // Send tab
        strings_["sending_from"] = "SENDING FROM";
        strings_["recent_sends"] = "RECENT SENDS";
        strings_["recipient"] = "RECIPIENT";
        strings_["memo_optional"] = "MEMO (OPTIONAL)";
        strings_["no_recent_sends"] = "No recent sends";
        strings_["network_fee"] = "NETWORK FEE";
        strings_["amount_details"] = "AMOUNT DETAILS";
        strings_["not_connected_to_daemon"] = "Not connected to daemon";
        strings_["select_source_address"] = "Select a source address...";
        strings_["no_addresses_with_balance"] = "No addresses with balance";
        strings_["blockchain_syncing"] = "Blockchain syncing (%.1f%%)... Balances may be inaccurate.";
        strings_["wallet_empty"] = "Your wallet is empty";
        strings_["wallet_empty_hint"] = "Switch to Receive to get your address and start receiving funds.";
        strings_["go_to_receive"] = "Go to Receive";
        strings_["review_send"] = "Review Send";
        strings_["fee_low"] = "Low";
        strings_["fee_normal"] = "Normal";
        strings_["fee_high"] = "High";
        strings_["submitting_transaction"] = "Submitting transaction...";
        strings_["processing_transaction"] = "Processing transaction...";
        strings_["tx_progress_submitting"] = "Submitting transaction to daemon";
        strings_["tx_progress_waiting_ops"] = "Waiting for operation (%d)";
        strings_["tx_progress_balances"] = "Refreshing balances";
        strings_["tx_progress_history"] = "Refreshing history";
        strings_["tx_progress_finalizing"] = "Finalizing transaction";
        strings_["transaction_sent_msg"] = "Transaction sent!";
        strings_["copy_error"] = "Copy Error";
        strings_["dismiss"] = "Dismiss";
        strings_["clear_form_confirm"] = "Clear all form fields?";
        strings_["yes_clear"] = "Yes, Clear";
        strings_["keep"] = "Keep";
        strings_["undo_clear"] = "Undo Clear";
        
        // Receive tab
        strings_["recent_received"] = "RECENT RECEIVED";
        strings_["payment_request"] = "PAYMENT REQUEST";
        strings_["copy"] = "Copy";
        strings_["new"] = "+ New";
        strings_["share"] = "Share";
        strings_["select_receiving_address"] = "Select a receiving address...";
        strings_["no_addresses_match"] = "No addresses match filter";
        strings_["no_recent_receives"] = "No recent receives";
        strings_["waiting_for_daemon"] = "Waiting for daemon connection...";
        strings_["addresses_appear_here"] = "Your receiving addresses will appear here once connected.";
        strings_["loading_addresses"] = "Loading addresses...";
        strings_["clear_request"] = "Clear Request";
        strings_["copy_uri"] = "Copy URI";
        strings_["qr_unavailable"] = "QR unavailable";
        strings_["received_label"] = "Received";
        
        // Transactions tab
        strings_["no_transactions"] = "No transactions found";
        strings_["loading_transactions"] = "Loading transactions";
        strings_["tx_loading_queued"] = "Queued transaction refresh";
        strings_["tx_loading_enriching_sends"] = "Checking sent transaction details (%d)";
        strings_["tx_loading_scanning_shielded"] = "Scanning shielded history (%d addresses)";
        strings_["tx_loading_refreshing_cached"] = "Refreshing wallet history (%d cached)";
        strings_["tx_loading_fetching_transparent"] = "Fetching transparent history";
        strings_["tx_loading_history_progress"] = "Loading older history (%d%%)";
        strings_["no_matching"] = "No matching transactions";
        strings_["transaction_id"] = "TRANSACTION ID";
        strings_["search_placeholder"] = "Search...";
        strings_["all_filter"] = "All";
        strings_["sent_filter"] = "Sent";
        strings_["received_filter"] = "Received";
        strings_["mined_filter"] = "Mined";
        strings_["chat_filter"] = "Chat";
        strings_["sort_date_newest"] = "Newest first";
        strings_["sort_date_oldest"] = "Oldest first";
        strings_["sort_amount_high"] = "Largest amount";
        strings_["sort_amount_low"] = "Smallest amount";
        strings_["export_csv"] = "Export CSV";
        strings_["transactions_upper"] = "TRANSACTIONS";
        strings_["received_upper"] = "RECEIVED";
        strings_["sent_upper"] = "SENT";
        strings_["mined_upper"] = "MINED";
        strings_["from_upper"] = "FROM";
        strings_["to_upper"] = "TO";
        strings_["shielded_to"] = "SHIELDED TO";
        strings_["address_upper"] = "ADDRESS";
        strings_["memo_upper"] = "MEMO";
        strings_["shielded_type"] = "Shielded";
        strings_["tx_chat_badge"] = "Message";
        strings_["recv_type"] = "Recv";
        strings_["sent_type"] = "Sent";
        strings_["immature_type"] = "Immature";
        strings_["mined_type"] = "Mined";
        strings_["mature"] = "Mature";
        strings_["copy_txid"] = "Copy TxID";
        strings_["view_details"] = "View Details";
        strings_["full_details"] = "Full Details";
        strings_["showing_transactions"] = "Showing %d\xe2\x80\x93%d of %d transactions (total: %zu)";
        strings_["txs_count"] = "%d txs";
        strings_["conf_count"] = "%d conf";
        strings_["confirmations_display"] = "%d confirmations  |  %s";
        strings_["mark_mining_address"] = "Mark as mining address";
        strings_["unmark_mining_address"] = "Unmark mining address";
        strings_["mining_tag"] = " · Mining";
        
        // Balance Tab
        strings_["summary"] = "Summary";
        strings_["shielded"] = "Shielded";
        strings_["transparent"] = "Transparent";
        strings_["total"] = "Total";
        strings_["unconfirmed"] = "Unconfirmed";
        strings_["recent_transactions"] = "RECENT TRANSACTIONS";
        strings_["view_all"] = "View All";
        strings_["no_transactions_yet"] = "No transactions yet";
        strings_["privacy_great"] = "Great privacy!";
        strings_["privacy_medium"] = "Consider shielding more";
        strings_["privacy_low"] = "Low privacy — shield funds";
        strings_["balance_history_collecting"] = "Balance history — collecting data...";
        strings_["balance_shielded_fmt"] = "Shielded: %.8f";
        strings_["balance_transparent_fmt"] = "Transparent: %.8f";
        strings_["total_balance_label"] = "Total Balance";
        strings_["balance_syncing_pct"] = "Syncing %.1f%%";
        strings_["balance_mining_rate"] = "Mining %s";
        strings_["balance_layout_switched"] = "Layout: %s";
        strings_["byte_count_fmt"] = "%zu / %zu bytes";
        strings_["quick_send"] = "Quick Send";
        strings_["quick_receive"] = "Quick Receive";
        strings_["tile_click_to_open"] = "Click to open";
        strings_["your_addresses"] = "Your Addresses";
        strings_["z_addresses"] = "Z-Addresses";
        strings_["t_addresses"] = "T-Addresses";
        strings_["no_addresses"] = "No addresses found. Create one using the buttons above.";
        strings_["new_z_address"] = "New Z-Address";
        strings_["new_t_address"] = "New T-Address";
        strings_["type"] = "Type";
        strings_["address"] = "Address";
        strings_["copy_address"] = "Copy Full Address";
        strings_["send_from_this_address"] = "Send From This Address";
        strings_["export_private_key"] = "Export Private Key";
        strings_["export_viewing_key"] = "Export Viewing Key";
        strings_["show_qr_code"] = "Show QR Code";
        strings_["not_connected"] = "Not connected to daemon...";
        // Lite build: there is no daemon — these replace the daemon-centric "not connected"
        // strings when no wallet is open (isConnected() tracks the lite wallet in lite builds).
        strings_["lite_no_wallet"] = "No wallet open — create or open one in Settings";
        strings_["lite_no_wallet_short"] = "No wallet open";
        // Lite first-run welcome prompt (shown when no wallet file exists yet).
        strings_["lite_welcome_title"] = "Welcome to ObsidianDragon Lite";
        strings_["lite_welcome_msg"] = "You don't have a wallet yet. Create a new one or restore from a recovery phrase.";
        strings_["lite_welcome_create"] = "Create new wallet";
        strings_["lite_welcome_restore"] = "Restore from seed";
        strings_["lite_welcome_later"] = "Later";
        strings_["lite_welcome_created"] = "Wallet created — back up your recovery phrase now in Settings → Backup & keys";
        strings_["lite_welcome_restore_hint"] = "Restore your wallet under Settings → Lite wallet request";
        strings_["lite_welcome_create_failed"] = "Could not create wallet";
        strings_["lite_restore_title"] = "Restore from seed phrase";
        strings_["lite_restore_intro"] = "Enter your recovery seed phrase. The wallet will be restored and then synced from the lite server.";
        strings_["lite_restore_seed_label"] = "Seed phrase (words separated by spaces)";
        strings_["lite_restore_birthday_label"] = "Birthday block (optional — 0 scans from the start, slower)";
        strings_["lite_restore_btn"] = "Restore wallet";
        strings_["lite_restore_ok"] = "Wallet restored — syncing from the lite server…";
        // Lite send-time unlock prompt.
        strings_["lite_unlock_title"] = "Unlock wallet";
        strings_["lite_unlock_msg"] = "Enter your passphrase to unlock the wallet for spending.";
        strings_["lite_unlock_btn"] = "Unlock";
        strings_["lite_unlock_ok"] = "Wallet unlocked — you can send now";
        strings_["lite_unlock_failed"] = "Unlock failed — wrong passphrase?";

        // Send Tab
        strings_["pay_from"] = "Pay From";
        strings_["send_to"] = "Send To";
        strings_["send_contacts_button"] = "Pick from contacts";
        strings_["amount"] = "Amount";
        strings_["memo"] = "Memo (optional, encrypted)";
        strings_["miner_fee"] = "Miner Fee";
        strings_["fee"] = "Fee";
        strings_["send_transaction"] = "Send Transaction";
        strings_["clear"] = "Clear";
        strings_["select_address"] = "Select address...";
        strings_["paste"] = "Paste";
        strings_["max"] = "Max";
        strings_["available"] = "Available";
        strings_["invalid_address"] = "Invalid address format";
        strings_["memo_z_only"] = "Note: Memos are only available when sending to shielded (z) addresses";
        strings_["characters"] = "characters";
        strings_["from"] = "From";
        strings_["to"] = "To";
        strings_["sending"] = "Sending transaction";
        strings_["confirm_send"] = "Confirm Send";
        strings_["confirm_transaction"] = "Confirm Transaction";
        strings_["confirm_and_send"] = "Confirm & Send";
        strings_["cancel"] = "Cancel";

        // Wallet-switch "stop the running node?" confirmation
        strings_["switch_stopnode_title"] = "Stop the running node?";
        strings_["switch_stopnode_warn"] = "A node is already running that this wallet didn't start.";
        strings_["switch_stopnode_body"] = "Switching wallets restarts the node on the wallet you selected. The running node will be stopped and relaunched on the new wallet — if you kept it running on purpose, it comes back up automatically.";
        strings_["switch_stopnode_confirm"] = "Stop node & switch";
        // Wallet-switch live progress modal
        strings_["switch_progress_title"] = "Switching wallet";
        strings_["switch_progress_failed_title"] = "Wallet switch failed";
        strings_["switch_progress_stopping"] = "Stopping the current node";
        strings_["switch_progress_starting"] = "Starting the node on the new wallet";
        strings_["switch_progress_reconnecting"] = "Reconnecting";
        strings_["switch_progress_hint"] = "A graceful shutdown can take up to a minute.";
        strings_["switch_progress_background"] = "Continue in background";
        strings_["switch_progress_from_label"] = "from";
        strings_["switch_progress_elapsed"] = "Elapsed";
        strings_["switch_progress_default_wallet"] = "Default wallet";
        strings_["switch_progress_external_wallet"] = "External wallet";
        strings_["switch_corrupt_body"] = "This wallet appears corrupt — the node couldn't open it. Restore it from a backup, re-create it, or try to repair it.";
        strings_["switch_corrupt_repair"] = "Try to repair (salvage)";

        // Block-database recovery (offered when the node aborts on an unreadable/format-mismatched block DB).
        strings_["block_db_reindex_title"] = "Rebuild block database?";
        strings_["block_db_reindex_warn"] = "The node can't read its block database.";
        strings_["block_db_reindex_body"] = "This usually happens after a daemon update changes the on-disk format, or if the block index is damaged. Your wallet and coins are safe — the node just can't load the chain, so balances show as zero.\n\nRebuilding re-reads your existing block files and can take a while (it also rescans your wallet). Nothing is downloaded.";
        strings_["block_db_reindex_confirm"] = "Rebuild block database";
        strings_["block_db_reindex_notify"] = "The node can't read its block database (often after a daemon update). Rebuild it to restore your balance — see the prompt, or Settings › Node.";
        strings_["block_db_reindex_started"] = "Rebuilding the block database from your blocks — this can take a while.";

        // Wallet auto-recovery warning (the node moved wallet.dat aside and loaded a salvaged copy).
        // Empty-active-wallet-with-funded-sibling warning (App::renderEmptyWalletWarningDialog).
        strings_["empty_wallet_warning_title"] = "This wallet is empty";
        strings_["empty_wallet_warning_headline"] = "You may have opened the wrong wallet.";
        strings_["empty_wallet_warning_body"] = "This wallet has no addresses and no funds, but another wallet file in your DragonX folder holds keys. Your coins are most likely in it, not lost. Open the wallet manager to switch to the wallet that holds your funds.";
        strings_["empty_wallet_keys_suffix"] = "keys";
        strings_["empty_wallet_open_manager"] = "Open wallet manager";
        strings_["empty_wallet_warning_dismiss"] = "Don't warn again for this wallet";
        strings_["empty_wallet_warning_dismiss_tip"] = "Stops this warning for the current wallet file only. If you switch to a different empty wallet later, it can warn again.";
        // Salvage-backup variant of the same modal (a funded wallet.<ts>.bak from an earlier auto-repair).
        strings_["empty_wallet_salvage_title"] = "Your wallet may have been repaired";
        strings_["empty_wallet_salvage_headline"] = "Your coins are safe in a backup file.";
        strings_["empty_wallet_salvage_body"] = "This wallet is empty because an earlier automatic repair set your original wallet aside as a backup. Your coins are almost certainly in that backup, not lost. Restore it to load your funds again — nothing is deleted; the current file is kept aside first.";
        strings_["empty_wallet_restore"] = "Restore my wallet";
        strings_["wallet_recovered_title"] = "Your wallet file needs a quick repair";
        strings_["wallet_recovered_safety"] = "Your coins are safe.";
        strings_["wallet_recovered_warn"] = "When the app started, it found that your wallet file didn't pass its consistency check — this usually happens after an app update or an unclean shutdown. The app already protected your data: it set the old file aside and loaded a repaired copy so you're not stuck.";
        strings_["wallet_recovered_body"] = "Nothing has been deleted. Your original wallet is still saved on your computer as a dated backup file, and every option below only copies or renames files — it never erases one. Your keys are never regenerated, only re-read.\n\nThe repaired copy that's loaded now may be missing a few recent transactions, so your balance can look a little low until you finish below and it re-scans.";
        strings_["wallet_recovered_open_folder"] = "Show me the files";
        strings_["wallet_recovered_open_folder_sub"] = "Opens the wallet data folder so you can inspect the backup files yourself — nothing is changed.";
        strings_["wallet_recovered_dismiss"] = "Not now — keep the repaired copy";
        strings_["wallet_recovered_dismiss_sub"] = "No files change. You can reopen this anytime from the status bar; your original stays safely backed up either way.";
        strings_["wallet_recovered_restore"] = "Restore the original file instead";
        strings_["wallet_recovered_restore_sub"] = "Puts your largest untouched backup back in place, verbatim, then re-scans — slightly faster, but only as complete as that one file was. Your current file is kept as a dated backup either way.";
        strings_["wallet_recovered_notify"] = "Your wallet file needed a repair — your original was safely backed up. Open the app to review your options.";
        strings_["wallet_degraded_notify"] = "Your wallet opened in reduced-function mode: existing funds are safe and spendable, but creating new addresses and shielding are disabled. Back up your seed phrase and restore it to fully repair the wallet.";
        strings_["autoshield_by_node"] = "Your node auto-shields mined coinbase for you.";
        strings_["autoshield_off_backup_seed"] = "Mined coinbase isn't being auto-shielded yet. Back up your seed phrase (Settings \xE2\x86\x92 Backup & Data) so your node can safely turn it on.";
        strings_["autoshield_off_generic"] = "Your node isn't auto-shielding mined coinbase right now.";
        // In-dialog recovery lifecycle (Offer → Working → Done/Failed) + disclosures.
        strings_["wallet_recovery_working_label"] = "Working";
        strings_["wallet_recovery_done"] = "Done";
        strings_["wallet_recovery_other_options"] = "Other options";
        strings_["wallet_recovery_details_label"] = "Show technical details";
        strings_["wallet_recovery_try_other"] = "Try the other option";
        strings_["wallet_recovery_success_body"] = "The app loaded your repaired wallet and is re-scanning to total your balance — this can take a few minutes. It reads every record it can, but on rare damaged files it may recover slightly fewer — or occasionally more — addresses than before. Once the re-scan finishes, check your balance and history look right.";
        strings_["wallet_recovery_success_restore"] = "Your largest backup file is back in place and loading now, and the app is re-scanning. It's restored verbatim, so it's exactly as complete as that file was — check your balance once the re-scan finishes.";
        strings_["wallet_recovery_failure_title"] = "The repair didn't go through";
        strings_["wallet_recovery_failure_body"] = "The repair ran, but its result didn't pass verification (it couldn't be read, or had no addresses), so it was discarded automatically before it ever replaced anything. Your wallet is exactly as it was before you clicked — nothing on disk changed.";
        strings_["wallet_recovery_whats_happened"] = "What happened?";
        // Choice-card layout: two side-by-side cards (recommended one highlighted) + quiet footer links.
        strings_["wallet_recovery_rebuild_card"] = "Repair automatically";
        strings_["wallet_recovery_restore_card"] = "Restore original";
        strings_["wallet_recovery_rebuild_card_desc"] = "Reads every recoverable record into a clean file, then restarts. The most thorough option.";
        strings_["wallet_recovery_restore_card_desc"] = "Puts your largest untouched backup back, verbatim \xE2\x80\x94 only as complete as that file was.";
        strings_["wallet_recovery_recommended"] = "RECOMMENDED";
        strings_["wallet_recovery_repair_go"] = "Repair";
        strings_["wallet_recovery_restore_go"] = "Restore";
        strings_["wallet_recovery_notnow_short"] = "Not now";
        strings_["wallet_recovery_decide_later"] = "Decide later";
        strings_["wallet_recovery_decide_later_tip"] = "Closes this and keeps the copy that's loaded now. Nothing is changed, and you can repair anytime \xE2\x80\x94 the status bar keeps a \xE2\x80\x9CWallet repair available\xE2\x80\x9D link.";
        strings_["wallet_recovery_files_label"] = "What happens to my files?";
        strings_["wallet_recovery_files_detail"] = "Your original wallet is still here \xE2\x80\x94 the app renamed it to a dated backup (wallet.<numbers>.bak) in your data folder and hasn't deleted anything. \xE2\x80\x9CRepair\xE2\x80\x9D reads every record from your fullest wallet into a brand-new clean file. \xE2\x80\x9CRestore\xE2\x80\x9D copies your largest backup back exactly as it is. The copy loaded right now is kept as a backup too.";
        // Post-repair rescan screen (shown while the node restarts + re-scans, before it answers RPC).
        strings_["wallet_recovery_rescan_title"] = "Finishing your wallet repair";
        strings_["wallet_recovery_rescan_body"] = "Re-scanning the blockchain to rebuild your balance and transaction history. This can take several minutes — you don't need to do anything, and please don't restart the node while it's running.";
        strings_["wallet_recovery_rescan_elapsed"] = "Working for %s";
        strings_["wallet_recovery_rescan_size"] = "Rebuilt wallet is now %s and still filling in";
        strings_["wallet_recovery_rescan_slow"] = "This is taking longer than usual, which is normal for a large wallet. It's safe to leave it running — you can watch progress under Advanced \xE2\x96\xB8 Console.";
        strings_["sb_finishing_repair"] = "Finishing wallet repair — re-scanning…";
        // One-click "Restore original wallet" flow.
        strings_["wallet_restore_started"] = "Restoring your original file — please don't close this window.";
        strings_["wallet_restore_busy"] = "The node is busy restarting — try again in a moment.";
        strings_["wallet_restore_ok"] = "Original wallet restored. The node is loading it now.";
        strings_["wallet_restore_no_backup"] = "Couldn't find a wallet.<timestamp>.bak to restore. Nothing was changed.";
        strings_["wallet_restore_bad_backup"] = "The backup wallet file looks unreadable, so it was NOT restored — your current wallet is unchanged. Restore from your own backup instead.";
        strings_["wallet_restore_stop_failed"] = "The node didn't stop in time, so nothing was changed. Try again.";
        strings_["wallet_restore_move_failed"] = "Couldn't set the current wallet aside — nothing was changed.";
        strings_["wallet_restore_copy_failed"] = "Couldn't install the backup wallet; your current wallet was left in place.";
        strings_["wallet_restore_no_restart"] = "Your original wallet was restored, but the node didn't restart — start it from Settings.";
        // One-click "Rebuild wallet database" flow (fixes a BDB-inconsistent wallet that keeps getting salvaged).
        strings_["wallet_recovered_rebuild"] = "Repair automatically (recommended)";
        strings_["wallet_recovered_rebuild_sub"] = "Re-reads every recoverable record from your fullest wallet file and writes a clean new one, then restarts. The most thorough option — your current file is kept as a dated backup either way.";
        strings_["wallet_rebuild_started"] = "Repairing your wallet file — please don't close this window.";
        strings_["wallet_rebuild_ok"] = "Wallet database rebuilt — the node is loading it and rescanning for your balance.";
        strings_["wallet_rebuild_no_helper"] = "The wallet-rebuild helper isn't available in this build. Use Restore, or rebuild manually.";
        strings_["wallet_rebuild_no_source"] = "Couldn't find a readable wallet to rebuild. Nothing was changed.";
        strings_["wallet_rebuild_failed"] = "The rebuild didn't produce a valid wallet, so nothing was changed. Your wallet is untouched.";
        strings_["wallet_rebuild_install_failed"] = "Couldn't install the rebuilt wallet; your current wallet was left in place.";

        // Receive Tab
        strings_["receiving_addresses"] = "Your Receiving Addresses";
        strings_["new_z_shielded"] = "New z-Address (Shielded)";
        strings_["new_t_transparent"] = "New t-Address (Transparent)";
        strings_["address_details"] = "Address Details";
        strings_["view_on_explorer"] = "View on Explorer";
        strings_["qr_code"] = "QR Code";
        strings_["show_qr"] = "Show QR";
        strings_["hide_qr"] = "Hide QR";
        strings_["request_payment"] = "Request Payment";
        
        // Transactions Tab
        strings_["date"] = "Date";
        strings_["status"] = "Status";
        strings_["confirmations"] = "Confirmations";
        strings_["confirmed"] = "Confirmed";
        strings_["pending"] = "Pending";
        strings_["sent"] = "sent";
        strings_["received"] = "received";
        strings_["mined"] = "mined";
        
        // Mining Tab
        strings_["mining_control"] = "Mining Control";
        strings_["start_mining"] = "Start Mining";
        strings_["stop_mining"] = "Stop Mining";
        strings_["mining_threads"] = "Mining Threads";
        strings_["mining_threads_input_tooltip"] = "Type an exact thread count (press Enter to apply)";
        strings_["mining_threads_minus_tooltip"] = "Fewer threads";
        strings_["mining_threads_plus_tooltip"] = "More threads";
        strings_["mining_statistics"] = "Mining Statistics";
        strings_["local_hashrate"] = "Local Hashrate";
        strings_["network_hashrate"] = "Network Hashrate";
        strings_["difficulty"] = "Difficulty";
        strings_["est_time_to_block"] = "Est. Time to Block";
        strings_["mining_off"] = "Mining is OFF";
        strings_["mining_on"] = "Mining is ON";
        
        // Peers Tab
        strings_["connected_peers"] = "Connected Peers";
        strings_["banned_peers"] = "Banned Peers";
        strings_["ip_address"] = "IP Address";
        strings_["version"] = "Version";
        strings_["height"] = "Height";
        strings_["ping"] = "Ping";
        strings_["ban"] = "Ban";
        strings_["unban"] = "Unban";
        strings_["clear_all_bans"] = "Clear All Bans";
        
        // Market Tab
        strings_["price_chart"] = "Price Chart";
        strings_["current_price"] = "Current Price";
        strings_["24h_change"] = "24h Change";
        strings_["24h_volume"] = "24h Volume";
        strings_["market_cap"] = "Market Cap";
        
        // Settings
        strings_["general"] = "General";
        strings_["display"] = "Display";
        strings_["network"] = "Network";
        strings_["theme"] = "Theme";
        strings_["language"] = "Language";
        strings_["clock_format"] = "Clock format";
        strings_["tt_clock_format"] = "24-hour or 12-hour clock, used across the app. The Chat tab can override it in its own settings.";
        strings_["dragonx_green"] = "DragonX (Green)";
        strings_["dark"] = "Dark";
        strings_["light"] = "Light";
        strings_["allow_custom_fees"] = "Allow custom fees";
        strings_["use_embedded_daemon"] = "Use embedded dragonxd";
        strings_["save"] = "Save";
        strings_["close"] = "Close";
        
        // Menu
        strings_["file"] = "File";
        strings_["edit"] = "Edit";
        strings_["view"] = "View";
        strings_["help"] = "Help";
        strings_["import_private_key"] = "Import Private Key...";
        strings_["backup_wallet"] = "Backup Wallet...";
        strings_["exit"] = "Exit";
        strings_["about_dragonx"] = "About ObsidianDragon";
        strings_["refresh_now"] = "Refresh Now";
        
        // Dialogs
        strings_["about"] = "About";
        strings_["import"] = "Import";
        strings_["export"] = "Export";
        strings_["copy_to_clipboard"] = "Copy to Clipboard";
        
        // Status
        strings_["connected"] = "Connected";
        strings_["disconnected"] = "Disconnected";
        strings_["connecting"] = "Connecting...";
        strings_["syncing"] = "Syncing...";
        strings_["block"] = "Block";
        strings_["no_addresses_available"] = "No addresses available";

        // Status bar
        strings_["sb_warming_up"] = "Warming up...";
        strings_["sb_block"] = "Block: %d";
        strings_["sb_peers"] = "Peers: %zu";
        strings_["sb_net_ghs"] = "Net: %.2f GH/s";
        strings_["sb_net_mhs"] = "Net: %.2f MH/s";
        strings_["sb_net_khs"] = "Net: %.2f KH/s";
        strings_["sb_net_hs"] = "Net: %.1f H/s";
        strings_["sb_mining_hs"] = "%.1f H/s";
        strings_["sb_syncing_eta"] = "Syncing %.1f%% (%d left, %.0f blk/s, ~%s)";
        strings_["sb_syncing_basic"] = "Syncing %.1f%% (%d left)";
        strings_["sb_rescanning_pct"] = "Rescanning %.0f%%";
        strings_["sb_rescanning"] = "Rescanning";
        strings_["sb_building_witnesses_pct"] = "Rebuilding witnesses %.0f%%";
        strings_["sb_building_witnesses"] = "Setting witnesses";
        strings_["sb_witness_cache"] = "Rebuilding witnesses";
        strings_["sb_importing_keys"] = "Importing keys";
        strings_["sb_daemon_not_found"] = "Daemon not found";
        strings_["sb_loading_config"] = "Loading configuration...";
        strings_["sb_waiting_config"] = "Waiting for daemon config...";
        strings_["sb_no_conf"] = "No DRAGONX.conf found";
        strings_["sb_starting_daemon"] = "Starting dragonxd...";
        strings_["sb_connecting_daemon"] = "Connecting to dragonxd...";
        strings_["sb_auth_failed"] = "Auth failed — check rpcuser/rpcpassword";
        strings_["sb_waiting_daemon"] = "Waiting for dragonxd to start...";
        strings_["sb_waiting_daemon_err"] = "Waiting for dragonxd — %s";
        strings_["sb_connecting_external"] = "Connecting to external daemon...";
        strings_["sb_connecting_generic"] = "Connecting to daemon...";
        strings_["sb_connecting_err"] = "Connecting to daemon — %s";
        strings_["sb_daemon_crashed"] = "Daemon crashed %d times";
        strings_["sb_daemon_start_failed"] = "Couldn't start dragonxd";
        strings_["sb_block_db_unreadable"] = "Block database unreadable — rebuild required";
        strings_["sb_wallet_needs_recovery"] = "Wallet repair available";
        // Persistent node-status banner (App::renderNodeStatusBanner).
        strings_["node_banner_offline_title"] = "Not connected to the DragonX node";
        strings_["node_banner_no_peers_title"] = "Connected, but no network peers — the node can't sync";
        strings_["node_banner_crashed_title"] = "The node stopped unexpectedly";
        strings_["node_banner_lite_open_failed"] = "Couldn't open your wallet";
        strings_["node_banner_reconnect"] = "Reconnect";
        strings_["node_banner_restart"] = "Restart node";
        // Refresh-staleness badge (W6-2) on the Total Balance card.
        strings_["data_stale_prefix"] = "Updated";
        strings_["data_stale_tooltip"] =
            "Balance may be out of date — the wallet hasn't received a fresh update recently. "
            "Check your node connection.";
        // Persistent alert-history panel (status-bar bell).
        strings_["alerts_history_tooltip"] = "Recent alerts";
        strings_["alerts_recent"] = "RECENT ALERTS";
        strings_["alerts_none"] = "No alerts yet";
        strings_["alerts_clear"] = "Clear alert history";
        strings_["daemon_port_busy_warn"] =
            "Port " DRAGONX_DEFAULT_RPC_PORT " is in use but isn't responding as a DragonX node. "
            "Close the program using it (or free the port), then restart — the wallet can't start "
            "its own node while the port is taken.";
        strings_["sb_extracting_sapling"] = "Extracting Sapling parameters...";
        strings_["sb_sapling_failed"] = "Failed to extract Sapling parameters.";
        strings_["sb_sapling_not_found"] = "Sapling parameters not found.";
        strings_["sb_daemon_extract_failed"] = "Failed to write daemon files — check free disk space and permissions.";
        strings_["sb_daemon_files_failed"] = "Failed to write daemon files to %s — check free disk space and permissions.";
        strings_["loading_stall_title"] = "Taking longer than expected";
        strings_["loading_stall_body"] = "Initializing for %.0fs — normal after an update or first launch. Connects automatically when ready.";
        strings_["loading_stall_hint"] = "Stuck? Settings → Restart Daemon, or check the Console.";
        strings_["sb_plaintext_remote_blocked"] = "Refusing to send RPC credentials over plaintext to a remote host. Add rpcallowplaintext=1 to DRAGONX.conf to allow it, or enable TLS with rpctls=1.";
        strings_["rpc_plaintext_remote_warning"] = "Remote RPC is using plaintext HTTP. Add rpctls=1 to DRAGONX.conf if your daemon supports TLS.";
        strings_["settings_open_log_folder"] = "Open log folder";
        strings_["settings_copy_diagnostics"] = "Copy diagnostics";
        strings_["settings_diagnostics_copied"] = "Diagnostics copied to clipboard";
        strings_["settings_rpc_ok"] = "RPC connection OK";
        strings_["settings_rpc_error_prefix"] = "RPC error: ";
        strings_["settings_not_connected"] = "Not connected to daemon";
        strings_["settings_theme_refreshed"] = "Theme list refreshed";
        strings_["settings_saved"] = "Settings saved";
        strings_["settings_reloaded"] = "Settings reloaded from disk";
        strings_["settings_ztx_cleared"] = "Z-transaction history cleared";
        strings_["settings_ztx_not_found"] = "No history file found";
        strings_["tt_open_log_folder"] = "Open the folder containing the debug and crash logs";
        strings_["tt_copy_diagnostics"] = "Copy a support snapshot (version, daemon/wallet/log state — no secrets) to the clipboard";
        strings_["sb_dragonxd_running"] = "dragonxd running";
        strings_["sb_dragonxd_stopping"] = "Stopping dragonxd...";
        strings_["sb_dragonxd_stopped"] = "dragonxd stopped";
        strings_["sb_restarting_daemon"] = "Restarting daemon...";
        
        // Errors & Messages
        strings_["error"] = "Error";
        strings_["success"] = "Success";
        strings_["warning"] = "Warning";
        strings_["amount_exceeds_balance"] = "Amount exceeds balance";
        strings_["transaction_sent"] = "Transaction sent successfully";

        // --- Common / Shared ---
        strings_["add"] = "Add";
        strings_["address_copied"] = "Address copied to clipboard";
        strings_["address_label"] = "Address:";
        strings_["amount_label"] = "Amount:";
        strings_["date_label"] = "Date:";
        strings_["delete"] = "Delete";
        strings_["fee_label"] = "Fee:";
        strings_["file_save_location"] = "File will be saved in: ~/.config/ObsidianDragon/";
        strings_["hide"] = "Hide";
        strings_["label"] = "Label:";
        strings_["loading"] = "Loading...";
        strings_["memo_label"] = "Memo:";
        strings_["notes"] = "Notes";
        strings_["notes_optional"] = "Notes (optional):";
        strings_["output_filename"] = "Output filename:";
        strings_["paste_from_clipboard"] = "Paste from Clipboard";
        strings_["show"] = "Show";
        strings_["time_days_ago"] = "%d days ago";
        strings_["time_hours_ago"] = "%d hours ago";
        strings_["time_minutes_ago"] = "%d minutes ago";
        strings_["time_seconds_ago"] = "%d seconds ago";
        strings_["unknown"] = "Unknown";
        strings_["validating"] = "Validating...";
        strings_["warning_upper"] = "WARNING!";

        // --- About Dialog ---
        strings_["about_block_explorer"] = "Block Explorer";
        strings_["about_block_height"] = "Block Height:";
        strings_["about_build_date"] = "Build Date:";
        strings_["about_build_type"] = "Build Type:";
        strings_["about_chain"] = "Chain:";
        strings_["about_connections"] = "Connections:";
        strings_["about_credits"] = "Credits";
        strings_["about_source"] = "Source";
        strings_["about_daemon"] = "Daemon:";
        strings_["about_debug"] = "Debug";
        strings_["about_edition"] = "ImGui Edition";
        strings_["about_github"] = "GitHub";
        strings_["about_imgui"] = "ImGui:";
        strings_["about_license"] = "License";
        strings_["about_license_text"] = "This software is released under the GNU General Public License v3 (GPLv3). You are free to use, modify, and distribute this software under the terms of the license.";
        strings_["about_peers_count"] = "%zu peers";
        strings_["about_release"] = "Release";
        strings_["about_title"] = "About ObsidianDragon";
        strings_["about_version"] = "Version:";
        strings_["about_website"] = "Website";

        // --- Help & FAQ ---
        strings_["faq"] = "FAQ";
        strings_["faq_title"] = "Help & FAQ";
        strings_["faq_intro"] = "Answers about your wallet and the DragonX node. Search, or browse by topic below.";
        strings_["faq_intro_lite"] = "Answers about your Lite wallet. Search, or browse by topic below.";
        strings_["faq_search_hint"] = "Search the FAQ\xE2\x80\xA6";
        strings_["faq_open_tooltip"] = "Help & FAQ";
        strings_["faq_no_results"] = "No results. Try a different search term.";
        strings_["faq_group_wallet"] = "Wallet";
        strings_["faq_group_daemon"] = "Daemon";

        // Wallet subcategory titles
        strings_["faq_w_gs_title"] = "Getting Started";
        strings_["faq_w_addr_title"] = "Addresses & Privacy";
        strings_["faq_w_send_title"] = "Sending & Receiving";
        strings_["faq_w_bal_title"] = "Balance & Sync";
        strings_["faq_w_sec_title"] = "Security & Encryption";
        strings_["faq_w_seed_title"] = "Seed Phrase & Backup";
        strings_["faq_w_chat_title"] = "Chat & Contacts";
        strings_["faq_w_set_title"] = "Settings & Appearance";
        // Daemon subcategory titles
        strings_["faq_d_node_title"] = "The Full Node";
        strings_["faq_d_sync_title"] = "Sync & Blockchain";
        strings_["faq_d_mgmt_title"] = "Node Management";
        strings_["faq_d_upd_title"] = "Updating the Node";
        strings_["faq_d_mine_title"] = "Mining & Pools";
        strings_["faq_d_net_title"] = "Peers & Network";
        strings_["faq_d_perf_title"] = "Storage & Performance";
        strings_["faq_d_trbl_title"] = "Troubleshooting";

        // Wallet > Getting Started
        strings_["faq_w_gs_1_q"] = "What is ObsidianDragon?";
        strings_["faq_w_gs_1_a"] = "ObsidianDragon is a full-node wallet for DragonX (DRGX). It manages your coins and, on the desktop build, runs a DragonX full node (the daemon) in the background so your wallet verifies the blockchain itself instead of trusting a third-party server.\n\nThink of it as two parts working together: the wallet (keys, balances, sending) and the node (the blockchain and network). The questions here are split the same way \xE2\x80\x94 see the Wallet and Daemon tabs above.";
        strings_["faq_w_gs_2_q"] = "How do I create a new wallet?";
        strings_["faq_w_gs_2_a"] = "On first launch the setup wizard creates a wallet for you automatically. New wallets are backed by a secret recovery phrase (a list of words). Write that phrase down and keep it offline \xE2\x80\x94 it is the only way to restore your funds if this computer is lost.\n\nYou can review or back up the phrase any time from Settings > Backup & Data > Seed phrase.";
        strings_["faq_w_gs_3_q"] = "How do I restore a wallet I already have?";
        strings_["faq_w_gs_3_a"] = "Use the seed-phrase restore flow if you have a recovery phrase. (On the full-node build you can also copy an existing wallet.dat file into the wallet's data directory before launch.)\n\nAfter restoring, the wallet re-scans to find your past transactions, so your balance and history may take a while to appear the first time.";
        strings_["faq_w_gs_4_q"] = "What does the first-run setup do?";
        strings_["faq_w_gs_4_a"] = "The wizard lets you pick an appearance/theme, set up encryption and a PIN, and \xE2\x80\x94 on the full-node build \xE2\x80\x94 optionally download a bootstrap to speed up the first sync. You can skip any step and change all of these later in Settings.";

        // Wallet > Addresses & Privacy
        strings_["faq_w_addr_1_q"] = "What's the difference between transparent and shielded addresses?";
        strings_["faq_w_addr_1_a"] = "Transparent addresses (they start with R or t) work like most coins: the amounts and addresses are public on the blockchain.\n\nShielded addresses (z-addresses, starting with zs) use zero-knowledge cryptography \xE2\x80\x94 the amount, sender, and receiver are encrypted on-chain. Balances held in shielded addresses are private.";
        strings_["faq_w_addr_2_q"] = "Which address type should I use?";
        strings_["faq_w_addr_2_a"] = "Prefer shielded (z) addresses whenever possible \xE2\x80\x94 they keep your balance and payment history private. DragonX is a privacy coin and shielded is the default for received funds.\n\nUse a transparent address only when a service you interact with cannot handle shielded addresses.";
        strings_["faq_w_addr_3_q"] = "Should I reuse an address or make a new one?";
        strings_["faq_w_addr_3_a"] = "For shielded addresses, reuse is fine and does not leak history. For transparent addresses, using a fresh address per payment improves privacy. Create new addresses from the Receive tab.";
        strings_["faq_w_addr_4_q"] = "What is 'shielding'?";
        strings_["faq_w_addr_4_a"] = "Shielding moves coins from a transparent address into a shielded one, making them private. Newly mined coins arrive transparent and are shielded for you automatically.\n\nYou can also shield manually from the wallet; a shield is just a special transaction, so it takes a normal confirmation time to complete.";

        // Wallet > Sending & Receiving
        strings_["faq_w_send_1_q"] = "How do I send funds?";
        strings_["faq_w_send_1_a"] = "Open the Send tab, paste the recipient's address, enter an amount, and confirm. If the wallet is encrypted you'll be asked to unlock it for the transaction.\n\nSends to shielded addresses are private; sends to transparent addresses are public.";
        strings_["faq_w_send_2_q"] = "What fee do I pay?";
        strings_["faq_w_send_2_a"] = "DragonX fees are very low and are set automatically. The fee is shown before you confirm. You do not normally need to change it.";
        strings_["faq_w_send_3_q"] = "Can I attach a message to a payment?";
        strings_["faq_w_send_3_a"] = "Yes \xE2\x80\x94 when sending to a shielded (z) address you can include an encrypted memo. Only the recipient can read it. Transparent addresses do not support memos.";
        strings_["faq_w_send_4_q"] = "I sent a payment but it says pending \xE2\x80\x94 why?";
        strings_["faq_w_send_4_a"] = "A transaction is 'pending' until it is mined into a block and gains confirmations. This usually takes a minute or two. Shielded transactions also need your wallet to be synced to build the proof.\n\nIf a send stays pending unusually long, check that your wallet is connected and synced (see the status bar at the bottom of the window).";

        // Wallet > Balance & Sync
        strings_["faq_w_bal_1_q"] = "Why is my balance 0 or not updating?";
        strings_["faq_w_bal_1_a"] = "While your wallet is still syncing, your balance is incomplete and may read 0 \xE2\x80\x94 it hasn't scanned all of your transactions yet. It fills in once syncing finishes.\n\nWatch the status bar at the bottom: it shows the connection state and block height. Once syncing is complete, your balance is accurate.";
        strings_["faq_w_bal_2_q"] = "What are confirmations?";
        strings_["faq_w_bal_2_a"] = "Each new block mined on top of the block containing your transaction adds one confirmation. More confirmations mean the payment is more firmly settled. Received funds become spendable after the first confirmation.";
        strings_["faq_w_bal_3_q"] = "What's the difference between total and spendable balance?";
        strings_["faq_w_bal_3_a"] = "Total includes funds that are still confirming or are temporarily locked (for example, coins in the middle of being shielded). Spendable is what you can send right now. They converge as transactions confirm.";

        // Wallet > Security & Encryption
        strings_["faq_w_sec_1_q"] = "How do I encrypt my wallet?";
        strings_["faq_w_sec_1_a"] = "Open Settings > Node & Security and set a passphrase (the SECURITY section). Encryption protects your private keys on disk, so someone with access to the files still cannot spend your coins.\n\nChoose a strong passphrase and don't lose it \xE2\x80\x94 there is no way to recover an encrypted wallet without it.";
        strings_["faq_w_sec_2_q"] = "What is the PIN / lock screen?";
        strings_["faq_w_sec_2_a"] = "The PIN locks the app's screen so balances and actions are hidden when you step away. It's a convenience lock on top of encryption; you set it up during the wizard or in Settings, after encrypting the wallet.";
        strings_["faq_w_sec_3_q"] = "I forgot my passphrase \xE2\x80\x94 can it be recovered?";
        strings_["faq_w_sec_3_a"] = "No. Wallet encryption cannot be bypassed. If you still have your seed recovery phrase, you can restore the wallet from it into a fresh wallet and set a new passphrase. Without either the passphrase or the seed phrase, the funds cannot be recovered.";

        // Wallet > Seed Phrase & Backup
        strings_["faq_w_seed_1_q"] = "How do I back up my recovery phrase?";
        strings_["faq_w_seed_1_a"] = "Go to Settings > Backup & Data > Seed phrase. Write the words down on paper in order and store them somewhere safe and offline. Anyone with the phrase can spend your coins, so never store it in a photo, email, or cloud note.";
        strings_["faq_w_seed_2_q"] = "My wallet has no recovery phrase \xE2\x80\x94 can I add one?";
        strings_["faq_w_seed_2_a"] = "Older (legacy) wallets weren't seed-based. The wallet can migrate a legacy wallet into a modern seed-backed one: it creates a new seed wallet and sweeps your funds into it. Look for 'Migrate to seed\xE2\x80\xA6' in Settings > Backup & Data. This feature needs the current daemon version.";
        strings_["faq_w_seed_3_q"] = "How do I restore from my recovery phrase?";
        strings_["faq_w_seed_3_a"] = "Use the seed-restore flow when setting up a wallet and enter your words in order. Your wallet then re-scans to rebuild your balance and history, which can take a while the first time.";
        strings_["faq_w_seed_4_q"] = "Should I also back up wallet.dat?";
        strings_["faq_w_seed_4_a"] = "Your seed phrase is the primary backup and is enough to restore everything. A copy of your wallet file is a convenient secondary backup that also preserves labels and settings. Keep any backup offline and private.";

        // Wallet > Chat & Contacts
        strings_["faq_w_chat_1_q"] = "What is the Chat feature?";
        strings_["faq_w_chat_1_a"] = "Chat is an encrypted, on-chain messenger built into the wallet. Messages are sent as private shielded memos, so only you and your contact can read them.";
        strings_["faq_w_chat_2_q"] = "How does my chat identity work?";
        strings_["faq_w_chat_2_a"] = "Your chat identity is derived from your wallet's recovery phrase, so it travels with your wallet \xE2\x80\x94 restore the wallet and your identity comes back. You don't create a separate account or password.";
        strings_["faq_w_chat_3_q"] = "How do contacts work?";
        strings_["faq_w_chat_3_a"] = "Add a contact by their address in the Contacts tab, optionally with a name and avatar. Contacts can be kept private to the current wallet or shared across all wallets you open on this computer.";
        strings_["faq_w_chat_4_q"] = "How do I hide, delete, or block a conversation?";
        strings_["faq_w_chat_4_a"] = "Open a conversation and use the icons in its header. Hide (the eye) drops it from the list but keeps every message \xE2\x80\x94 a new message un-hides it. Delete (the trash) opens a dialog: 'Delete' clears the history on this device (if that person messages you again, the conversation comes back), while 'Delete & block' also stops their future messages until you unblock them from the 'Blocked' list above the conversation list. Everything here is local to this device \xE2\x80\x94 the messages stay on the blockchain and the other person keeps their own copy, so it isn't an 'unsend'.";
        // ---- Lite-variant FAQ (ObsidianDragonLite): swapped-in answers + a Lite Wallet subcategory ----
        strings_["faq_l_gs_1_q"] = "What is ObsidianDragonLite?";
        strings_["faq_l_gs_1_a"] = "ObsidianDragonLite is the lightweight DragonX wallet. Instead of running a full node, it connects to a DragonX lite server, so it starts fast and doesn't download the whole blockchain.\n\nIt manages your keys, balances, and sending just like the full wallet \xE2\x80\x94 see the 'Lite Wallet' section below for how the server connection works and the privacy tradeoff.";
        strings_["faq_l_sec_1_a"] = "Open Settings > Wallet and set a passphrase in the security section. Encryption protects your private keys on disk, so someone with access to the files still cannot spend your coins.\n\nChoose a strong passphrase and don't lose it \xE2\x80\x94 there is no way to recover an encrypted wallet without it.";
        strings_["faq_l_lite_title"] = "Lite Wallet";
        strings_["faq_l_lite_1_q"] = "How is the Lite wallet different from the full wallet?";
        strings_["faq_l_lite_1_a"] = "The Lite wallet talks to a DragonX lite server instead of running its own full node. That makes it fast to start and light on disk and bandwidth, because it doesn't download or verify the entire blockchain itself. Your private keys always stay on your device \xE2\x80\x94 they are never sent to the server.";
        strings_["faq_l_lite_2_q"] = "How do I choose or change the server?";
        strings_["faq_l_lite_2_a"] = "Open Settings and pick a server. You can switch servers at any time and the wallet re-syncs from the new one. If a server is slow or unreachable, try another.";
        strings_["faq_l_lite_3_q"] = "Is the Lite wallet as private as the full node?";
        strings_["faq_l_lite_3_a"] = "Your keys never leave your device, and shielded amounts stay encrypted. But the lite server does see which addresses your wallet asks about and your IP address, so it can link your addresses together \xE2\x80\x94 a convenience-for-privacy tradeoff. For the most privacy, use the full-node wallet, which verifies the chain itself and doesn't reveal your addresses to a server.";

        // Wallet > Settings & Appearance
        strings_["faq_w_set_1_q"] = "How do I change the theme?";
        strings_["faq_w_set_1_a"] = "Open Settings > Appearance to pick a theme and accent. Several light and dark skins are included, and effects like blur can be toggled off for lower-powered machines.";
        strings_["faq_w_set_2_q"] = "Can I change the language?";
        strings_["faq_w_set_2_a"] = "Yes \xE2\x80\x94 Settings > Appearance has a language selector. The wallet ships with several translations; anything not yet translated falls back to English.";
        strings_["faq_w_set_3_q"] = "The text is too small (or too large) \xE2\x80\x94 can I scale it?";
        strings_["faq_w_set_3_a"] = "Use the font-scale option in Settings > Appearance. It scales the whole interface, which is handy on high-resolution (HiDPI) displays where the app might otherwise render small.";
        strings_["faq_w_set_4_q"] = "How do I show fiat prices?";
        strings_["faq_w_set_4_a"] = "Enable price fetching in Settings. The wallet then shows an approximate fiat value alongside balances and can display a small market chart. Prices are informational only.";

        // Daemon > The Full Node
        strings_["faq_d_node_1_q"] = "What is the daemon (dragonxd)?";
        strings_["faq_d_node_1_a"] = "The daemon, dragonxd, is the DragonX full node. It downloads and verifies the entire blockchain, relays transactions to the network, and answers the wallet's queries. Running your own node means you don't have to trust anyone else's server.";
        strings_["faq_d_node_2_q"] = "Embedded vs external node \xE2\x80\x94 what's the difference?";
        strings_["faq_d_node_2_a"] = "By default the wallet launches and manages its own bundled node (embedded) \xE2\x80\x94 you don't have to do anything. If you already run dragonxd yourself, the wallet can connect to that external node instead. The wallet detects which situation it's in and behaves accordingly.";
        strings_["faq_d_node_3_q"] = "Why run a full node at all?";
        strings_["faq_d_node_3_a"] = "A full node validates every rule of the blockchain independently, so your wallet trusts math instead of a third party. It also strengthens the network. The trade-off is disk space and an initial sync.";

        // Daemon > Sync & Blockchain
        strings_["faq_d_sync_1_q"] = "What does 'Processing blocks' at startup mean?";
        strings_["faq_d_sync_1_a"] = "On launch the node loads and validates blocks before it can serve the wallet. The 'Processing blocks / Applying blocks to build the current chain state' screen is that warm-up. It's normal; the wallet becomes usable once the node finishes and reports its height.";
        strings_["faq_d_sync_2_q"] = "What is 'Rebuilding witness cache'?";
        strings_["faq_d_sync_2_a"] = "For your shielded funds the node keeps cryptographic 'witnesses' that let you spend privately. After certain restarts or updates it rebuilds this cache by re-scanning recent blocks. On a wallet with many transactions this can take several minutes and use extra memory.\n\nIt is not stuck \xE2\x80\x94 let it finish. Force-quitting in the middle just makes it restart the rebuild next time.";
        strings_["faq_d_sync_3_q"] = "Why is syncing slow when I'm almost caught up?";
        strings_["faq_d_sync_3_a"] = "Near the chain tip, work that scans your wallet (checking balances and notes) competes with the node for the same internal lock, which can slow down connecting the final blocks on a large wallet. Recent versions throttle that scanning so the node can catch up. Staying on a lighter tab (or just waiting) lets it finish faster.";
        strings_["faq_d_sync_4_q"] = "How long does the initial sync take?";
        strings_["faq_d_sync_4_a"] = "The first sync downloads and verifies the whole chain and can take a while depending on your connection and disk. You can speed it up dramatically by enabling the bootstrap download in the setup wizard, which fetches a recent verified copy of the chain data.";

        // Daemon > Node Management
        strings_["faq_d_mgmt_1_q"] = "How do I start or stop the node?";
        strings_["faq_d_mgmt_1_a"] = "The embedded node starts automatically with the wallet and stops when appropriate, so you normally don't manage it by hand. Advanced controls (including restarting the daemon) live in Settings > Node & Security.";
        strings_["faq_d_mgmt_2_q"] = "What does 'close external daemon on exit' do?";
        strings_["faq_d_mgmt_2_a"] = "If you connect the wallet to a node you started yourself, this option decides whether closing the wallet also shuts that node down. Leave it off if you want your node to keep running after you close the wallet.";
        strings_["faq_d_mgmt_3_q"] = "Where is the blockchain and wallet data stored?";
        strings_["faq_d_mgmt_3_a"] = "Node and wallet data live in the DragonX data directory under your user profile (for example, in AppData on Windows or your home folder on Linux/macOS). The blockchain is the large part; keep enough free disk space for it to grow.";

        // Daemon > Updating the Node
        strings_["faq_d_upd_1_q"] = "How do I update the node?";
        strings_["faq_d_upd_1_a"] = "Open Settings > Node & Security > Daemon binary and use 'Check for updates\xE2\x80\xA6'. The wallet downloads the latest verified node build and installs it; the new version takes effect the next time the daemon starts.";
        strings_["faq_d_upd_2_q"] = "Can I install a specific node version?";
        strings_["faq_d_upd_2_a"] = "Yes \xE2\x80\x94 the update dialog lists every release so you can pick a specific or older build. Be cautious downgrading: an older node may not accept blockchain data written by a newer one and could need a re-index.";
        strings_["faq_d_upd_3_q"] = "Is the update safe?";
        strings_["faq_d_upd_3_a"] = "Every downloaded node archive is verified against a checksum and a cryptographic signature before it's installed. If verification fails, the wallet refuses the update.";

        // Daemon > Mining & Pools
        strings_["faq_d_mine_1_q"] = "How do I mine DragonX?";
        strings_["faq_d_mine_1_a"] = "The Mining tab lets you mine with your CPU. DragonX uses the RandomX algorithm, which is designed for regular processors. Set the number of threads and start \xE2\x80\x94 rewards accrue to your wallet.";
        strings_["faq_d_mine_2_q"] = "Solo vs pool mining \xE2\x80\x94 which should I choose?";
        strings_["faq_d_mine_2_a"] = "Solo mining sends rewards straight to you but pays only when you find a block, which is infrequent unless you have a lot of hashrate. Pool mining shares work with others for smaller, steadier payouts. The Mining tab supports both.";
        strings_["faq_d_mine_3_q"] = "How do I update the miner?";
        strings_["faq_d_mine_3_a"] = "The Mining tab's pool section has an 'Update miner\xE2\x80\xA6' button that downloads, verifies, and installs the latest optimized DragonX miner build. Like the node updater, each download is checksum- and signature-verified before install.";
        strings_["faq_d_mine_4_q"] = "Can I host a mining pool?";
        strings_["faq_d_mine_4_a"] = "The current node can run a built-in stratum server so other miners can point at your machine. There's a toggle for it under Settings > Node & Security. By default it only listens locally; exposing it to other computers requires opening it up deliberately.";

        // Daemon > Peers & Network
        strings_["faq_d_net_1_q"] = "The wallet shows no peers or connections \xE2\x80\x94 what's wrong?";
        strings_["faq_d_net_1_a"] = "Right after launch the node needs a moment to find peers, so a brief '0 peers' is normal. If it persists, check your internet connection and that a firewall isn't blocking the node. The node finds peers automatically through built-in seeds.";
        strings_["faq_d_net_2_q"] = "Is my connection to the network encrypted?";
        strings_["faq_d_net_2_a"] = "Yes \xE2\x80\x94 DragonX nodes talk to each other over TLS, so peer connections are encrypted. The wallet also talks to its own node over a secure local channel.";

        // Daemon > Storage & Performance
        strings_["faq_d_perf_1_q"] = "How much disk does the node use, and can I tune memory?";
        strings_["faq_d_perf_1_a"] = "The blockchain is the large item and grows over time, so keep several gigabytes free. The node uses a database cache for speed; the bundled defaults are tuned for typical machines. Advanced users can adjust the node's database cache by editing dbcache in its config file (DRAGONX.conf).";
        strings_["faq_d_perf_2_q"] = "How do I make the initial sync faster?";
        strings_["faq_d_perf_2_a"] = "Enable the bootstrap download (offered in the setup wizard) to fetch a recent, verified copy of the chain instead of validating every block from scratch. A fast disk (SSD) also helps a lot.";

        // Daemon > Troubleshooting
        strings_["faq_d_trbl_1_q"] = "The node seems stuck on 'Activating best chain' \xE2\x80\x94 is it frozen?";
        strings_["faq_d_trbl_1_a"] = "Usually not. On a large wallet the node can spend several minutes rebuilding shielded witnesses or applying blocks, during which it looks paused and may be slow to answer. Give it time \xE2\x80\x94 the debug log (Settings) shows steady progress if it's working.\n\nAvoid force-quitting during this phase; it restarts the work from scratch next launch.";
        strings_["faq_d_trbl_2_q"] = "What is 'degraded mode'?";
        strings_["faq_d_trbl_2_a"] = "If a wallet file is recovered but part of its key data is missing, the node may open it in a limited 'degraded' mode where it can't derive new addresses or shield funds. The safest fix is to restore from your seed recovery phrase into a fresh wallet.";
        strings_["faq_d_trbl_3_q"] = "When should I re-index or re-scan?";
        strings_["faq_d_trbl_3_a"] = "A re-scan makes the wallet re-read the chain to rediscover your transactions (useful after importing keys). A re-index rebuilds the node's blockchain database and is only needed if that database is corrupted or incompatible after a version change. Both can take a while; start them from Settings > Node & Security.";
        strings_["faq_d_trbl_4_q"] = "The node is using a lot of memory \xE2\x80\x94 is that normal?";
        strings_["faq_d_trbl_4_a"] = "Memory use spikes during heavy work like a witness rebuild or an initial sync, then drops back down once it finishes. Sustained high memory at idle is unusual \xE2\x80\x94 restarting the wallet clears it. On a low-RAM machine, make sure other memory-heavy apps aren't competing.";

        // --- Address Book Dialog ---
        strings_["address_book_add"] = "Add Address";
        strings_["address_book_add_new"] = "Add New";
        strings_["contact_global"] = "Show in every wallet (global contact)";
        strings_["contact_global_tt"] = "On: this contact stays visible no matter which wallet you load. Off: it belongs to the current wallet only.";
        // Contact edit dialog: live preview + avatar picker
        strings_["contact_preview_name"] = "Contact name";
        strings_["contact_preview_addr"] = "Address will appear here";
        strings_["contact_avatar"] = "AVATAR";
        strings_["contact_avatar_badge"] = "Badge";
        strings_["contact_avatar_icon"] = "Icon";
        strings_["contact_avatar_image"] = "Image";
        strings_["contact_avatar_badge_hint"] = "The badge is chosen automatically from the address type.";
        strings_["contact_avatar_shielded"] = "Shielded";
        strings_["contact_avatar_transparent"] = "Transparent";
        strings_["contact_avatar_choose"] = "Choose image\xE2\x80\xA6";
        strings_["contact_avatar_remove"] = "Remove";
        strings_["contact_avatar_image_hint"] = "The image is copied into the app so it stays available if the original moves.";
        strings_["contact_avatar_copy_failed"] = "Could not copy that image.";
        strings_["contact_wallet_loading"] = "The wallet is still loading — tick \"Show in every wallet\", or try again in a moment.";
        strings_["contact_avatar_bad_image"] = "That image couldn't be loaded.";
        strings_["contact_global_badge_tt"] = "Global contact — visible in every wallet";
        strings_["address_book_added"] = "Address added to book";
        strings_["address_book_count"] = "%zu addresses saved";
        strings_["address_book_count_one"] = "%zu address saved";
        strings_["address_book_deleted"] = "Entry deleted";
        strings_["address_book_edit"] = "Edit Address";
        strings_["address_book_empty"] = "No saved addresses. Click 'Add New' to add one.";
        strings_["address_book_exists"] = "Address already exists in book";
        strings_["address_book_title"] = "Address Book";
        strings_["address_book_update_failed"] = "Failed to update - address may be duplicate";
        strings_["address_book_updated"] = "Address updated";

        // --- Backup Dialog ---
        strings_["backup_backing_up"] = "Backing up...";
        strings_["backup_create"] = "Create Backup";
        strings_["backup_created"] = "Wallet backup created";
        strings_["backup_description"] = "Create a backup of your wallet.dat file. This file contains all your private keys and transaction history. Store the backup in a secure location.";
        strings_["backup_destination"] = "Backup destination:";
        strings_["backup_warn"] = "This file holds all your private keys \xE2\x80\x94 keep it somewhere safe.";
        strings_["backup_overwrite_confirm"] = "A file already exists there \xE2\x80\x94 Save again to overwrite it.";
        strings_["backup_tip_external"] = "Store backups on external drives or cloud storage";
        strings_["backup_tip_multiple"] = "Create multiple backups in different locations";
        strings_["backup_tip_test"] = "Test restoring from backup periodically";
        strings_["backup_tips"] = "Tips:";
        strings_["backup_title"] = "Backup Wallet";
        strings_["backup_wallet_not_found"] = "Warning: wallet.dat not found at expected location";

        // --- Block Info Dialog ---
        strings_["block_bits"] = "Bits:";
        strings_["block_click_next"] = "Click to view next block";
        strings_["block_click_prev"] = "Click to view previous block";
        strings_["block_get_info"] = "Get Block Info";
        strings_["block_hash"] = "Block Hash:";
        strings_["block_height"] = "Block Height:";
        strings_["block_info_title"] = "Block Information";
        strings_["block_merkle_root"] = "Merkle Root:";
        strings_["block_nav_next"] = "Next >>";
        strings_["block_nav_prev"] = "<< Previous";
        strings_["block_next"] = "Next Block:";
        strings_["block_previous"] = "Previous Block:";
        strings_["block_size"] = "Size:";
        strings_["block_timestamp"] = "Timestamp:";
        strings_["block_transactions"] = "Transactions:";

        // --- Console Tab ---
        strings_["console_auto_scroll"] = "Auto-scroll";
        strings_["console_available_commands"] = "Available commands:";
        strings_["console_quit_note"] = "'quit'/'exit' aren't needed here — just close the window.";
        strings_["lite_console_help_passthrough"] = "Any other input runs as a lite-wallet console command.";
        strings_["lite_console_backend_commands"] = "Backend commands:";
        strings_["console_no_output"] = "(no output)";
        strings_["console_backend_unavailable"] = "No backend";
        strings_["console_last_error"] = "Last error:";
        strings_["console_not_connected_lite"] = "Error: no wallet open";
        strings_["console_stop_confirm_node"] = "'stop' will shut down the node and disconnect the wallet. Type 'stop' again to confirm.";
        strings_["console_capturing_output"] = "Capturing daemon output...";
        strings_["console_clear"] = "Clear";
        strings_["console_clear_console"] = "Clear Console";
        strings_["console_cleared"] = "Console cleared";
        strings_["console_click_commands"] = "Click commands above to insert them";
        strings_["console_click_insert"] = "Click to insert";
        strings_["console_click_insert_params"] = "Click to insert with parameters";
        strings_["console_close"] = "Close";
        strings_["console_commands"] = "Commands";
        strings_["console_common_rpc"] = "Common RPC commands:";
        strings_["console_completions"] = "Completions:";
        strings_["console_connected"] = "Connected to daemon";
        strings_["console_copy_all"] = "Copy All";
        strings_["console_copy_selected"] = "Copy";
        strings_["console_daemon"] = "Daemon";
        strings_["console_daemon_error"] = "Daemon error!";
        strings_["console_daemon_started"] = "Daemon started";
        strings_["console_daemon_stopped"] = "Daemon stopped";
        strings_["daemon_version"] = "Daemon";
        strings_["console_disconnected"] = "Disconnected from daemon";
        strings_["console_errors"] = "Errors";
        strings_["console_filter_hint"] = "Filter output...";
        strings_["console_help_clear"] = "  clear         - Clear the console";
        strings_["console_help_getbalance"] = "  getbalance    - Show transparent balance";
        strings_["console_help_getblockcount"] = "  getblockcount - Show current block height";
        strings_["console_help_getinfo"] = "  getinfo       - Show node information";
        strings_["console_help_getmininginfo"] = "  getmininginfo - Show mining status";
        strings_["console_help_getpeerinfo"] = "  getpeerinfo   - Show connected peers";
        strings_["console_help_gettotalbalance"] = "  gettotalbalance - Show total balance";
        strings_["console_help_help"] = "  help          - Show this help message";
        strings_["console_help_setgenerate"] = "  setgenerate   - Control mining";
        strings_["console_help_stop"] = "  stop          - Stop the daemon";
        strings_["console_line_count"] = "%zu lines";
        strings_["console_matches"] = "matches";
        strings_["console_copy_value"] = "Copy";
        strings_["console_new_lines"] = "%d new lines";
        strings_["console_no_daemon"] = "No daemon";
        strings_["console_not_connected"] = "Error: Not connected to daemon";
        strings_["console_rpc_reference"] = "RPC Command Reference";
        strings_["console_backend_reference"] = "Backend Command Reference";
        strings_["console_rpc_trace"] = "RPC";
        strings_["console_app"] = "App";
        strings_["console_show_app_output"] = "Show [app] wallet log lines";
        strings_["console_search_commands"] = "Search commands...";
        strings_["console_select_all"] = "Select All";
        strings_["console_show_daemon_output"] = "Show daemon output";
        strings_["console_show_errors_only"] = "Show errors only";
        strings_["console_show_rpc_ref"] = "Show RPC command reference";
        strings_["console_show_backend_ref"] = "Show backend command reference";
        strings_["console_show_rpc_trace"] = "Show app RPC calls";
        strings_["console_showing_lines"] = "Showing %zu of %zu lines";
        strings_["console_starting_node"] = "Starting node...";
        strings_["console_status_error"] = "Error";
        strings_["console_status_running"] = "Running";
        strings_["console_status_starting"] = "Starting";
        strings_["console_status_stopped"] = "Stopped";
        strings_["console_status_stopping"] = "Stopping";
        strings_["console_status_unknown"] = "Unknown";
        strings_["console_tab_completion"] = "Tab for completion";
        strings_["console_type_help"] = "Type 'help' for available commands";
        strings_["console_welcome"] = "Welcome to ObsidianDragon Console";
        strings_["console_zoom_in"] = "Zoom in";
        strings_["console_zoom_out"] = "Zoom out";
        strings_["console_toggle_accents"] = "Toggle line color accents";
        strings_["console_toggle_text_color"] = "Toggle line text colors";
        strings_["console_auto_focus"] = "Focus input on open";
        strings_["console_toggle_auto_focus"] = "Place the cursor in the command box when you open the Console tab";
        strings_["console_accents"] = "Color accents";
        strings_["console_text_colors"] = "Text colors";
        strings_["console_cat_control"] = "Control";
        strings_["console_cat_network"] = "Network";
        strings_["console_cat_blockchain"] = "Blockchain";
        strings_["console_cat_mining"] = "Mining";
        strings_["console_cat_wallet"] = "Wallet";
        strings_["console_cat_raw_transactions"] = "Raw Transactions";
        strings_["console_cat_utility"] = "Utility";
        strings_["console_cat_sync"] = "Sync";
        strings_["console_cat_send"] = "Send";
        strings_["console_cat_keys"] = "Keys & Security";
        strings_["console_cat_advanced"] = "Advanced";
        strings_["console_ref_search_hint"] = "Search by name or task\xE2\x80\xA6";
        strings_["console_ref_parameters"] = "Parameters";
        strings_["console_ref_no_params"] = "Takes no parameters.";
        strings_["console_ref_optional"] = "optional";
        strings_["console_ref_value"] = "value";
        strings_["console_ref_example"] = "Example";
        strings_["console_ref_builds"] = "Builds";
        strings_["console_ref_destructive"] = "Consequential";
        strings_["console_ref_run_confirm"] = "Run %s now? This is a consequential command.";
        strings_["console_ref_cancel"] = "Cancel";
        strings_["console_ref_run"] = "Run";
        strings_["console_ref_insert"] = "Insert into console";
        strings_["console_ref_insert_run"] = "Insert & run";
        strings_["console_ref_select_hint"] = "Select a command to see what it does.";
        strings_["console_ref_no_match"] = "No commands match.";

        // --- Export All Keys Dialog ---
        strings_["export_keys_btn"] = "Export Keys";
        strings_["export_keys_danger"] = "DANGER: This will export ALL private keys from your wallet! Anyone with access to this file can steal your funds. Store it securely and delete after use.";
        strings_["export_keys_include_t"] = "Include T-addresses (transparent)";
        strings_["export_keys_include_z"] = "Include Z-addresses (shielded)";
        strings_["export_keys_options"] = "Export options:";
        strings_["export_keys_success"] = "Keys exported successfully";
        strings_["export_keys_select_type"] = "Select at least one address type";
        strings_["export_keys_not_connected"] = "Not connected to the daemon";
        strings_["export_keys_none_addrs"] = "No addresses to export";
        strings_["export_keys_none_result"] = "No keys exported (0 of %d) \xE2\x80\x94 unlock the wallet and try again.";
        strings_["export_keys_none_toast"] = "No keys could be exported \xE2\x80\x94 is the wallet unlocked?";
        strings_["export_keys_write_fail"] = "Failed to write the key file.";
        strings_["export_keys_partial"] = "Exported %d of %d keys \xE2\x80\x94 incomplete (some had no spending key, or the wallet is locked).";
        strings_["export_keys_partial_toast"] = "Partial export: %d of %d keys";
        strings_["export_keys_title"] = "Export All Private Keys";

        // --- Export Transactions Dialog ---
        strings_["export_tx_count"] = "Export %zu transactions to CSV file.";
        strings_["export_tx_file_fail"] = "Failed to create CSV file";
        strings_["export_tx_none"] = "No transactions to export";
        strings_["export_tx_success"] = "Transactions exported successfully";
        strings_["export_tx_title"] = "Export Transactions to CSV";

        // --- Import Key Dialog ---
        strings_["import_key_btn"] = "Import Key(s)";
        strings_["import_key_formats"] = "Supported key formats:";
        strings_["import_key_full_rescan"] = "(0 = full rescan)";
        strings_["import_key_label"] = "Private Key(s):";
        strings_["import_key_no_valid"] = "No valid keys found in input";
        strings_["import_key_rescan"] = "Rescan blockchain after import";
        strings_["import_key_start_height"] = "Start height:";
        strings_["import_key_success"] = "Keys imported successfully";
        strings_["import_key_t_format"] = "T-address WIF private keys";
        strings_["import_key_title"] = "Import Private Key";
        strings_["import_key_tooltip"] = "Enter one or more private keys, one per line.\nSupports both z-address and t-address keys.\nLines starting with # are treated as comments.";
        strings_["import_key_warning"] = "Warning: Never share your private keys! Importing keys from untrusted sources can compromise your wallet.";
        strings_["import_key_z_format"] = "Z-address spending keys (secret-extended-key-...)";
        strings_["import_key_warn"] = "Only import a key you own \xE2\x80\x94 it grants access to its funds.";
        strings_["import_key_need_node"] = "Connect a running node to import a key.";
        strings_["import_key_field"] = "Key";
        strings_["import_key_reveal_tip"] = "Show/hide the key";
        strings_["import_key_type_tkey"] = "Transparent private key";
        strings_["import_key_type_zspend"] = "Shielded spending key";
        strings_["import_key_type_zview"] = "Shielded viewing key (watch-only)";
        strings_["import_key_type_unknown"] = "Unrecognized key format";
        strings_["import_key_rescanning"] = "Importing & rescanning \xE2\x80\x94 this can take several minutes";
        strings_["import_key_done"] = "Imported. Wallet is rescanning.";
        strings_["import_key_address"] = "Address:";
        strings_["import_key_import"] = "Import";
        // Viewing-key (watch-only) import — separate button + dialog mode.
        strings_["import_viewkey_title"] = "Import Viewing Key";
        strings_["import_viewkey_note"] = "Watch-only: a viewing key reveals an address's balance and transactions but cannot spend its funds.";
        strings_["import_viewkey_field"] = "Viewing key";
        strings_["import_key_wrong_type"] = "This looks like a viewing key. Use \"Import Viewing Key\" instead.";
        strings_["import_viewkey_wrong_type"] = "This looks like a spending key. Use \"Import Private Key\" instead.";
        strings_["import_scan_label"] = "Scan from block height (optional)";
        strings_["import_scan_hint"] = "0 = rescan from the start";
        strings_["import_scan_transparent"] = "Transparent keys always rescan fully";
        strings_["import_scan_tip"] = "current height";
        strings_["paste_clip_empty"] = "Clipboard is empty";
        // Sweep (import a spending key, then move all its funds to your own address).
        strings_["sweep_toggle"] = "Sweep to my wallet (don't keep the key)";
        strings_["sweep_caveat"] = "Imports the key to sign one transaction moving all its funds to your address. The key stays in your wallet with an empty balance.";
        strings_["sweep_dest_label"] = "Send swept funds to";
        strings_["sweep_dest_new"] = "New shielded address (recommended)";
        strings_["sweep_button"] = "Sweep";
        strings_["sweep_done"] = "Done \xE2\x80\x94 funds swept to your address.";
        strings_["sweep_to"] = "Swept to:";
        strings_["sweep_tx"] = "Transaction:";

        // --- Key Export Dialog ---
        strings_["key_export_fetching"] = "Fetching key from wallet...";
        strings_["key_export_failed"] = "Couldn't export the key \xE2\x80\x94 unlock the wallet (if encrypted) and try again.";
        strings_["key_export_private_key"] = "Private Key:";
        strings_["key_export_private_warning"] = "Keep this key SECRET! Anyone with this key can spend your funds. Never share it online or with untrusted parties.";
        strings_["key_export_reveal"] = "Reveal Key";
        strings_["key_export_viewing_key"] = "Viewing Key:";
        strings_["key_export_viewing_warning"] = "This viewing key allows others to see your incoming transactions and balance, but NOT spend your funds. Share only with trusted parties.";

        // --- Market Tab ---
        strings_["market_12h"] = "12h";
        strings_["market_18h"] = "18h";
        strings_["market_24h"] = "24h";
        strings_["market_col_name"] = "Name";
        strings_["market_col_value"] = "Value";
        strings_["market_col_trend"] = "Trend";
        strings_["market_24h_volume"] = "24H VOLUME";
        strings_["market_6h"] = "6h";
        strings_["market_iv_live"] = "Live";
        strings_["market_iv_1h"] = "1H";
        strings_["market_iv_1d"] = "1D";
        strings_["market_iv_1w"] = "1W";
        strings_["market_iv_1m"] = "1M";
        strings_["market_updated"] = "\xc2\xb7 Updated %s";
        strings_["market_vol_short"] = "Vol";
        strings_["market_cap_short"] = "Cap";
        strings_["market_attribution"] = "Price data from CoinGecko";
        strings_["market_btc_price"] = "BTC PRICE";
        strings_["market_no_history"] = "No price history available";
        strings_["market_chart_loading"] = "Loading price history";
        strings_["market_style_line"] = "Switch to line chart";
        strings_["market_style_candle"] = "Switch to candlesticks";
        strings_["market_style_line_label"] = "Line";
        strings_["market_style_candle_label"] = "Candlestick";
        strings_["market_settings_title"] = "Market settings";
        strings_["market_settings_tip"] = "Market options";
        strings_["market_opt_chart_style"] = "Chart style";
        strings_["market_no_price"] = "No price data";
        strings_["market_now"] = "Now";
        strings_["market_pct_shielded"] = "%.0f%% Shielded";
        strings_["market_portfolio"] = "PORTFOLIO";
        strings_["portfolio_all_funds"] = "All funds";
        strings_["portfolio_manage"] = "Manage\xE2\x80\xA6";
        strings_["portfolio_icon"] = "Icon";
        strings_["portfolio_color"] = "Color";
        strings_["portfolio_no_icon"] = "None";
        strings_["portfolio_custom_color"] = "Custom color\xE2\x80\xA6";
        strings_["portfolio_outline_opacity"] = "Outline opacity";
        strings_["portfolio_price"] = "Price";
        strings_["portfolio_price_usd"] = "Market \xC2\xB7 USD";
        strings_["portfolio_price_btc"] = "Market \xC2\xB7 BTC";
        strings_["portfolio_price_drgx"] = "DRGX only";
        strings_["portfolio_price_manual"] = "Manual";
        strings_["portfolio_manual_price"] = "Price / DRGX";
        strings_["portfolio_currency"] = "Currency";
        strings_["portfolio_show"] = "Show:";
        strings_["portfolio_show_value"] = "Value";
        strings_["portfolio_show_24h"] = "24h";
        strings_["portfolio_show_sparkline"] = "Sparkline";
        strings_["portfolio_spark_min"] = "Minute";
        strings_["portfolio_spark_hour"] = "Hour";
        strings_["portfolio_spark_day"] = "Day";
        strings_["portfolio_spark_week"] = "Week";
        strings_["portfolio_spark_month"] = "Month";
        strings_["portfolio_appearance"] = "Appearance";
        strings_["portfolio_addresses_hdr"] = "Addresses";
        strings_["portfolio_search"] = "Search addresses\xE2\x80\xA6";
        strings_["portfolio_search_icons"] = "Search icons\xE2\x80\xA6";
        strings_["portfolio_funded"] = "Funded";
        strings_["portfolio_select_all"] = "All";
        strings_["portfolio_select_shown"] = "Select all";
        strings_["portfolio_group_name"] = "Group name";
        strings_["portfolio_no_addr_match"] = "No addresses match";
        strings_["portfolio_manage_title"] = "Manage portfolio";
        strings_["portfolio_add_entry"] = "Add entry";
        strings_["portfolio_wallet_loading"] = "Wait until the wallet finishes loading to add a group.";
        strings_["portfolio_new_entry"] = "New entry";
        strings_["portfolio_label"] = "Label";
        strings_["portfolio_addresses_sel"] = "%d selected";
        strings_["portfolio_all_shielded"] = "All shielded";
        strings_["portfolio_all_transparent"] = "All transparent";
        strings_["portfolio_clear_sel"] = "Clear";
        strings_["portfolio_no_entries"] = "No custom entries yet. Add one to track a group of addresses.";
        strings_["portfolio_style_label"] = "Portfolio style";
        strings_["portfolio_style_compact"] = "Table";
        strings_["portfolio_style_detailed"] = "Cards";
        strings_["portfolio_style_featured"] = "Spotlight";
        strings_["portfolio_edit"] = "Edit";
        strings_["portfolio_delete"] = "Delete";
        strings_["portfolio_save"] = "Save";
        strings_["portfolio_cancel"] = "Cancel";
        strings_["portfolio_revert"] = "Revert";
        strings_["portfolio_close"] = "Close";
        strings_["portfolio_save_need_name"] = "Enter a name to save this group.";
        strings_["portfolio_save_need_address"] = "Add at least one address to save.";
        strings_["portfolio_save_need_price"] = "Enter a manual price above 0 to save.";
        strings_["portfolio_untitled"] = "Untitled";
        strings_["portfolio_detail_empty"] = "Select a group on the left, or add one, to edit it.";
        strings_["portfolio_add_to"] = "Add to portfolio";
        strings_["portfolio_remove_from"] = "Remove from portfolio";
        strings_["market_24h_change"] = "24h";
        strings_["market_price_loading"] = "Loading price data...";
        strings_["market_price_unavailable"] = "Price data unavailable";
        strings_["market_refresh_price"] = "Refresh price data";
        strings_["market_trade_on"] = "Trade on %s";

        // --- Mining Tab ---
        strings_["mining_active"] = "Active";
        strings_["mining_address_copied"] = "Mining address copied";
        strings_["mining_all_time"] = "All Time";
        strings_["mining_already_saved"] = "Pool URL already saved";
        strings_["mining_block_copied"] = "Block hash copied";
        strings_["mining_chart_1m_ago"] = "1m ago";
        strings_["mining_chart_5m_ago"] = "5m ago";
        strings_["mining_chart_now"] = "Now";
        strings_["mining_chart_start"] = "Start";
        strings_["mining_click"] = "Click";
        strings_["mining_click_copy_address"] = "Click to copy address";
        strings_["mining_click_copy_block"] = "Click to copy block hash";
        strings_["mining_click_copy_difficulty"] = "Click to copy difficulty";
        strings_["mining_connected"] = "Connected";
        strings_["mining_connecting"] = "Connecting...";
        strings_["mining_difficulty_copied"] = "Difficulty copied";
        strings_["mining_est_block"] = "Est. Block";
        strings_["mining_est_daily"] = "Est. Daily";
        strings_["mining_filter_all"] = "All";
        strings_["mining_filter_tip_all"] = "Show all earnings";
        strings_["mining_filter_tip_pool"] = "Show pool earnings only";
        strings_["mining_filter_tip_solo"] = "Show solo earnings only";
        strings_["mining_idle_off_tooltip"] = "Enable idle mining";
        strings_["mining_idle_on_tooltip"] = "Disable idle mining";
        strings_["mining_idle_scale_on_tooltip"] = "Thread scaling: ON\nClick to switch to start/stop mode";
        strings_["mining_idle_scale_off_tooltip"] = "Start/stop mode: ON\nClick to switch to thread scaling mode";
        strings_["mining_idle_gpu_on_tooltip"] = "GPU-aware: ON\nGPU activity (video, games) prevents idle mining\nClick for unrestricted mode";
        strings_["mining_idle_gpu_off_tooltip"] = "Unrestricted: ON\nOnly keyboard/mouse input determines idle state\nClick to enable GPU-aware detection";
        strings_["mining_idle_threads_active_tooltip"] = "Threads when user is active";
        strings_["mining_idle_threads_idle_tooltip"] = "Threads when system is idle";
        strings_["mining_local_hashrate"] = "Local Hashrate";
        strings_["mining_mine"] = "Mine";
        strings_["mining_mining_addr"] = "Mining Addr";
        strings_["mining_network"] = "Network";
        strings_["mining_no_blocks_yet"] = "No blocks found yet";
        strings_["mining_no_payouts_yet"] = "No pool payouts yet";
        strings_["mining_no_saved_addresses"] = "No saved addresses";
        strings_["mining_no_saved_pools"] = "No saved pools";
        strings_["mining_open_in_explorer"] = "Open in explorer";
        strings_["mining_payout_address"] = "Payout Address";
        strings_["mining_payout_tooltip"] = "Address to receive mining rewards";
        strings_["mining_payout_invalid"] = "Not a valid DragonX address — fix it before starting, or mining rewards are lost.";
        strings_["mining_est_daily_pool_sub"] = "rough solo-equivalent, before pool fee";
        strings_["mining_generate_z_address_hint"] = "Generate a Z address in the Receive tab to use as your payout address";
        strings_["mining_pool_needs_payout_tooltip"] = "Enter a payout address first (generate a Z address)";
        strings_["mining_pool"] = "Pool";
        strings_["mining_payout_foreign"] = "⚠ This payout address isn't in your current wallet — mined rewards would go to a different wallet. Update it if you switched wallets.";
        strings_["mining_pool_hashrate"] = "Pool Hashrate";
        strings_["mining_pool_url"] = "Pool URL";
        // Pool selection mode + auto-balance (mining tab).
        strings_["mining_select_manual"] = "Manual";
        strings_["mining_select_auto"] = "Auto-balance";
        strings_["mining_manual_desc"] = "Manual: mine to the pool you pick from the list below.";
        strings_["mining_auto_balance_desc"] = "Spreads miners across the official pools by hashrate to help decentralize the network. Checks each pool periodically.";
        strings_["mining_suggested_pools"] = "Suggested pools";
        strings_["mining_pools_header"] = "POOLS";
        strings_["mining_pool_fee"] = "Fee";
        strings_["mining_mining_here"] = "mining here";
        strings_["mining_refresh"] = "Refresh";
        strings_["mining_auto_balanced_to"] = "Auto-balanced mining to";
        strings_["mining_recent_blocks"] = "RECENT BLOCKS";
        strings_["mining_recent_payouts"] = "RECENT POOL PAYOUTS";
        strings_["mining_remove"] = "Remove";
        strings_["mining_reset_defaults"] = "Reset Defaults";
        strings_["mining_benchmark_tooltip"] = "Find optimal thread count for this CPU";
        strings_["mining_benchmark_testing"] = "Testing";
        strings_["mining_benchmark_cooling"] = "Cooling";
        strings_["mining_benchmark_stabilizing"] = "Stabilizing";
        strings_["mining_benchmark_cancel"] = "Cancel benchmark";
        strings_["mining_benchmark_result"] = "Optimal";
        strings_["mining_benchmark_dismiss"] = "Dismiss";
        strings_["mining_save_payout_address"] = "Save payout address";
        strings_["mining_save_pool_url"] = "Save pool URL";
        strings_["mining_saved_addresses"] = "Saved Addresses:";
        strings_["mining_saved_pools"] = "Saved Pools:";
        strings_["mining_shares"] = "Shares";
        strings_["mining_show_chart"] = "Chart";
        strings_["mining_show_log"] = "Log";
        strings_["mining_solo"] = "Solo";
        strings_["mining_starting"] = "Starting...";
        strings_["mining_starting_tooltip"] = "Miner is starting...";
        strings_["mining_stop"] = "Stop";
        strings_["mining_stop_solo_for_pool"] = "Stop solo mining before starting pool mining";
        strings_["mining_stop_solo_for_pool_settings"] = "Stop solo mining to change pool settings";
        strings_["mining_stopping"] = "Stopping...";
        strings_["mining_stopping_tooltip"] = "Miner is stopping...";
        strings_["mining_syncing_tooltip"] = "Blockchain is syncing...";
        strings_["mining_to_save"] = "to save";
        strings_["mining_today"] = "Today";
        strings_["mining_uptime"] = "Uptime";
        strings_["mining_yesterday"] = "Yesterday";

        // --- Miner (xmrig) updater ---
        strings_["xmrig_update_button"]      = "Update miner…";
        strings_["xmrig_update_short"]       = "Update";
        strings_["xmrig_releases"]           = "xmrig releases";
        strings_["xmrig_current"]            = "Current:";
        strings_["xmrig_none"]               = "none";
        strings_["xmrig_update_title"]       = "Update Miner";
        strings_["xmrig_stop_mining_first"]  = "Stop mining before updating the miner.";
        strings_["xmrig_checking"]           = "Checking for the latest miner…";
        strings_["xmrig_unavailable_title"]  = "Miner updates unavailable";
        strings_["xmrig_unavailable_body"]   = "No miner build is available for this platform.";
        strings_["xmrig_update_available"]   = "A new miner is available";
        strings_["xmrig_up_to_date"]         = "The miner is up to date";
        strings_["xmrig_latest"]             = "Latest:";
        strings_["xmrig_installed"]          = "Installed:";
        strings_["xmrig_version"]            = "Version:";
        strings_["xmrig_verify_note"]        = "The download is checked against the release's published SHA-256 checksum before install.";
        strings_["xmrig_download_install"]   = "Download & install";
        strings_["xmrig_reinstall"]          = "Reinstall";
        strings_["xmrig_downloading"]        = "Downloading…";
        strings_["xmrig_verifying"]          = "Verifying…";
        strings_["xmrig_installing"]         = "Installing…";
        strings_["xmrig_installed_ok"]       = "Miner installed";
        strings_["xmrig_update_failed"]      = "Update failed";
        strings_["xmrig_unknown_error"]      = "Unknown error.";
        strings_["xmrig_browse_releases"]    = "Browse all releases…";
        strings_["xmrig_loading_releases"]   = "Loading releases…";
        strings_["xmrig_latest_badge"]       = "latest";
        strings_["xmrig_status_current"]     = "This version is installed";
        strings_["xmrig_status_latest"]      = "Latest version";
        strings_["xmrig_status_older"]       = "Older than your installed version";
        strings_["xmrig_released"]           = "Released:";
        strings_["xmrig_no_notes"]           = "No release notes for this version.";
        strings_["xmrig_install_this"]       = "Install this version";
        strings_["xmrig_downgrade_note"]     = "Installing a different miner version replaces the current one; stop mining first, then it takes effect on the next start.";
        strings_["xmrig_active_tt"]          = "The currently installed (active) miner";
        strings_["xmrig_latest_tt"]          = "Newest available version";
        strings_["xmrig_prerelease_tt"]      = "Pre-release / testing build";

        // --- Shared release picker ("Browse all releases") ---
        strings_["upd_select_version"]       = "Select a version to install";
        strings_["upd_install"]              = "Install";
        strings_["upd_reinstall"]            = "Reinstall";
        strings_["upd_prerelease"]           = "pre-release";
        strings_["upd_installed_badge"]      = "installed";
        strings_["upd_no_build_platform"]    = "No build for this platform";
        strings_["upd_back"]                 = "Back";

        // --- Daemon (full node) updater — Settings → daemon binary panel ---
        strings_["daemon_update_check"]            = "Check for updates…";
        strings_["tt_daemon_update_check"]         = "Download and verify the latest dragonxd full node from the project Gitea, then restart to apply";
        strings_["daemon_update_title"]            = "Update Node";
        strings_["daemon_update_checking"]         = "Checking for the latest node…";
        strings_["daemon_update_unavailable_title"]= "Node updates unavailable";
        strings_["daemon_update_unavailable_body"] = "No node build is available for this platform.";
        strings_["daemon_update_available"]        = "A new node version is available";
        strings_["daemon_update_up_to_date"]       = "The node is up to date";
        strings_["daemon_update_latest"]           = "Latest:";
        strings_["daemon_update_installed"]        = "Installed:";
        strings_["daemon_update_version"]          = "Version:";
        strings_["daemon_update_verify_note"]      = "The download is verified against the release's published SHA-256 and a pinned ed25519 signature before install.";
        strings_["daemon_update_download_install"] = "Download & install";
        strings_["daemon_update_reinstall"]        = "Reinstall";
        strings_["daemon_update_downloading"]      = "Downloading…";
        strings_["daemon_update_verifying"]        = "Verifying…";
        strings_["daemon_update_installing"]       = "Installing…";
        strings_["daemon_update_installed_ok"]     = "Node installed";
        strings_["daemon_update_restart_note"]     = "Restart the daemon to start running the new version.";
        strings_["daemon_update_restart_now"]      = "Restart daemon now";
        strings_["daemon_update_later"]            = "Later";
        strings_["daemon_update_failed"]           = "Update failed";
        strings_["daemon_update_unknown_error"]    = "Unknown error.";
        strings_["daemon_update_browse"]           = "Browse all releases…";
        strings_["daemon_update_loading"]          = "Loading releases…";
        strings_["daemon_update_downgrade_note"]   = "Older versions may be incompatible with your current chain data. Installing a different version takes effect after a daemon restart.";
        strings_["daemon_update_latest_badge"]     = "latest";
        strings_["daemon_update_status_current"]   = "This version is installed";
        strings_["daemon_update_status_latest"]    = "Latest version";
        strings_["daemon_update_status_older"]     = "Older than your installed version";
        strings_["daemon_update_released"]         = "Released:";
        strings_["daemon_update_no_notes"]         = "No release notes for this version.";
        strings_["daemon_update_install_this"]     = "Install this version";
        strings_["daemon_update_active_tt"]        = "The currently installed (active) node";
        strings_["daemon_update_latest_tt"]        = "Newest available version";
        strings_["daemon_update_prerelease_tt"]    = "Pre-release / testing build";

        // --- Lite Network tab (server browser) ---
        strings_["lite_net_title"]        = "Lite Servers";
        strings_["lite_net_intro"]        = "Pick a server to use, or let the wallet choose one at random. Changes apply immediately.";
        strings_["lite_net_use_random"]   = "Use a random server each time";
        strings_["lite_net_random_active"] = "Random server selection is active.";
        strings_["lite_net_refresh"]      = "Refresh";
        strings_["lite_net_add"]          = "Add";
        strings_["lite_net_add_url_hint"] = "https://your-lite-server";
        strings_["lite_net_add_label_hint"] = "Label (optional)";
        strings_["lite_net_invalid_url"]  = "Enter a valid http(s):// URL.";
        strings_["lite_net_official"]     = "Official";
        strings_["lite_net_custom"]       = "Custom";
        strings_["lite_net_in_use"]       = "In use";
        strings_["lite_net_offline"]      = "offline";
        strings_["lite_net_checking"]     = "checking…";
        strings_["lite_net_hide"]         = "Hide";
        strings_["lite_net_unhide"]       = "Unhide";
        strings_["lite_net_show_hidden"]  = "Show hidden servers";
        strings_["lite_net_hidden_section"] = "Hidden servers";
        strings_["lite_net_connected"]    = "Connected";
        strings_["lite_net_connecting"]   = "Connecting";
        strings_["lite_net_disconnected"] = "Not connected";
        strings_["lite_net_syncing"]      = "Syncing";
        strings_["lite_net_synced"]       = "Synced";
        strings_["lite_net_random_server"] = "Random server";
        strings_["lite_net_sync_label"]   = "Sync";
        strings_["lite_net_no_wallet"]    = "No wallet open";

        // --- Peers Tab ---
        strings_["peers_avg_ping"] = "Avg Ping";
        strings_["peers_ban_24h"] = "Ban Peer 24h";
        strings_["peers_ban_score"] = "Ban Score: %d";
        strings_["peers_banned"] = "Banned";
        strings_["peers_banned_count"] = "Banned: %d";
        strings_["peers_best_block"] = "Best Block";
        strings_["peers_blockchain"] = "BLOCKCHAIN";
        strings_["peers_blocks"] = "Blocks";
        strings_["peers_blocks_left"] = "%d blocks left";
        strings_["peers_clear_all_bans"] = "Clear All Bans";
        strings_["peers_click_copy"] = "Click to copy";
        strings_["peers_connected"] = "Connected";
        strings_["peers_connected_count"] = "Connected: %d";
        strings_["peers_copy_ip"] = "Copy IP";
        strings_["peers_dir_in"] = "In";
        strings_["peers_dir_out"] = "Out";
        strings_["peers_hash_copied"] = "Hash copied";
        strings_["peers_hashrate"] = "Hashrate";
        strings_["peers_in_out"] = "In/Out";
        strings_["peers_longest"] = "Longest";
        strings_["peers_longest_chain"] = "Longest Chain";
        strings_["peers_memory"] = "Memory";
        strings_["peers_no_banned"] = "No banned peers";
        strings_["peers_no_connected"] = "No connected peers";
        strings_["peers_no_tls"] = "No TLS";
        strings_["peers_notarized"] = "Notarized";
        strings_["peers_p2p_port"] = "P2P Port";
        strings_["peers_protocol"] = "Protocol";
        strings_["peers_received"] = "Received";
        strings_["peers_refresh"] = "Refresh";
        strings_["peers_refresh_tooltip"] = "Refresh peer list";
        strings_["peers_refreshing"] = "Refreshing...";
        strings_["peers_sent"] = "Sent";
        strings_["peers_tt_id"] = "ID: %d";
        strings_["peers_tt_received"] = "Received: %s";
        strings_["peers_tt_sent"] = "Sent: %s";
        strings_["peers_tt_services"] = "Services: %s";
        strings_["peers_tt_start_height"] = "Start Height: %d";
        strings_["peers_tt_synced"] = "Synced H/B: %d/%d";
        strings_["peers_tt_tls_cipher"] = "TLS: %s";
        strings_["peers_unban"] = "Unban";
        strings_["peers_upper"] = "PEERS";
        strings_["peers_version"] = "Version";

        // --- QR Popup Dialog ---
        strings_["qr_failed"] = "Failed to generate QR code";
        strings_["qr_title"] = "QR Code";

        // --- Receive Tab ---
        strings_["click_copy_address"] = "Click to copy address";
        strings_["click_copy_uri"] = "Click to copy URI";
        strings_["generating"] = "Generating";
        strings_["failed_create_shielded"] = "Failed to create shielded address";
        strings_["failed_create_transparent"] = "Failed to create transparent address";
        strings_["new_shielded_created"] = "New shielded address created";
        strings_["new_transparent_created"] = "New transparent address created";
        strings_["payment_request_copied"] = "Payment request copied";
        strings_["payment_uri_copied"] = "Payment URI copied";

        // --- Request Payment Dialog ---
        strings_["request_amount"] = "Amount (optional):";
        strings_["request_copy_uri"] = "Copy URI";
        strings_["request_description"] = "Generate a payment request that others can scan or copy. The QR code contains your address and optional amount/memo.";
        strings_["request_label"] = "Label (optional):";
        strings_["request_memo"] = "Memo (optional):";
        strings_["request_payment_uri"] = "Payment URI:";
        strings_["request_receive_address"] = "Receive Address:";
        strings_["request_select_address"] = "Select address...";
        strings_["request_shielded_addrs"] = "-- Shielded Addresses --";
        strings_["request_title"] = "Request Payment";
        strings_["request_transparent_addrs"] = "-- Transparent Addresses --";
        strings_["request_uri_copied"] = "Payment URI copied to clipboard";

        // --- Send Tab ---
        strings_["send_amount"] = "Amount";
        strings_["send_amount_details"] = "AMOUNT DETAILS";
        strings_["send_amount_upper"] = "AMOUNT";
        strings_["send_clear_fields"] = "Clear all form fields?";
        strings_["send_copy_error"] = "Copy Error";
        strings_["send_dismiss"] = "Dismiss";
        strings_["send_error_copied"] = "Error copied to clipboard";
        strings_["send_error_prefix"] = "Error: %s";
        strings_["send_exceeds_available"] = "Exceeds available (%.8f)";
        strings_["send_fee"] = "Fee";
        strings_["send_fee_high"] = "High";
        strings_["send_fee_low"] = "Low";
        strings_["send_fee_normal"] = "Normal";
        strings_["send_form_restored"] = "Form restored";
        strings_["send_go_to_receive"] = "Go to Receive";
        strings_["send_keep"] = "Keep";
        strings_["send_network_fee"] = "NETWORK FEE";
        strings_["send_no_balance"] = "No balance";
        strings_["send_no_recent"] = "No recent sends";
        strings_["send_recent_sends"] = "RECENT SENDS";
        strings_["send_recipient"] = "RECIPIENT";
        strings_["send_select_source"] = "Select a source address...";
        strings_["send_sending_from"] = "SENDING FROM";
        strings_["send_available_note"] = "available";
        strings_["send_submitting"] = "Submitting transaction...";
        strings_["send_switch_to_receive"] = "Switch to Receive to get your address and start receiving funds.";
        strings_["send_tooltip_enter_amount"] = "Enter an amount to send";
        strings_["send_tooltip_exceeds_balance"] = "Amount exceeds available balance";
        strings_["send_tooltip_in_progress"] = "Transaction already in progress";
        strings_["send_tooltip_invalid_address"] = "Enter a valid recipient address";
        strings_["send_tooltip_not_connected"] = "Not connected to daemon";
        strings_["send_tooltip_select_source"] = "Select a source address first";
        strings_["send_tooltip_syncing"] = "Wait for blockchain to sync";
        strings_["send_tooltip_view_only"] = "View-only address — no spending key, cannot send";
        strings_["send_total"] = "Total";
        strings_["send_tx_failed"] = "Transaction failed";
        strings_["send_tx_sent"] = "Transaction sent!";
        strings_["send_cannot_send_now"] = "Cannot send now — check connection, sync, and available balance.";
        strings_["send_tx_success"] = "Transaction sent successfully!";
        strings_["send_status_unconfirmed"] = "Transaction status could not be confirmed";
        strings_["send_err_needs_rescan"] = "Your wallet's shielded note data is out of date with the blockchain (this happens after a bootstrap or reindex). Run a full rescan via Settings -> Rescan Blockchain and let it finish completely, then try sending again.";
        strings_["send_txid_copied"] = "TxID copied to clipboard";
        strings_["send_txid_label"] = "TxID: %s";
        strings_["send_valid_shielded"] = "Valid shielded address";
        strings_["send_valid_transparent"] = "Valid transparent address";
        strings_["send_wallet_empty"] = "Your wallet is empty";
        strings_["send_yes_clear"] = "Yes, Clear";

        // --- Shield Dialog ---
        strings_["shield_check_status"] = "Check Status";
        strings_["shield_completed"] = "Operation completed successfully!";
        strings_["shield_description"] = "Shield your mining rewards by sending coinbase outputs from transparent addresses to a shielded address. This improves privacy by hiding your mining income.";
        strings_["shield_from_address"] = "From Address:";
        strings_["shield_funds"] = "Shield Funds";
        strings_["shield_in_progress"] = "Operation in progress...";
        strings_["shield_max_utxos"] = "Max UTXOs per operation";
        strings_["shield_merge_done"] = "Shield/merge completed!";
        strings_["shield_select_z"] = "Select z-address...";
        strings_["shield_no_zaddr_hint"] = "No shielded (z) address yet — create one on the Receive tab first.";
        strings_["shield_started"] = "Shield operation started";
        strings_["shield_title"] = "Shield Coinbase Rewards";
        strings_["shield_to_address"] = "To Address (Shielded):";
        strings_["shield_utxo_limit"] = "UTXO Limit:";
        strings_["shield_wildcard_hint"] = "Use '*' to shield from all transparent addresses";
        strings_["shield_submitting"] = "Submitting operation...";
        strings_["shield_op_submitted"] = "Operation submitted: ";
        strings_["shield_op_failed"] = "Operation failed: ";
        strings_["shield_error_prefix"] = "Error: ";
        strings_["shield_status_label"] = "Status: ";
        strings_["shield_status_check_error"] = "Error checking status: ";
        strings_["shield_unknown_error"] = "Unknown error";
        strings_["shield_send_failed"] = "Shield failed: ";
        strings_["merge_send_failed"] = "Merge failed: ";
        strings_["merge_description"] = "Merge multiple UTXOs into a single shielded address. This can help reduce wallet size and improve privacy.";
        strings_["merge_funds"] = "Merge Funds";
        strings_["merge_started"] = "Merge operation started";
        strings_["merge_title"] = "Merge to Address";
        // Consolidate-funds flow (rich merge modal + wallet-bloat preset).
        strings_["consolidate_title"] = "Consolidate funds";
        strings_["consolidate_desc"] = "Combine many small inputs into a single shielded note. Fewer notes means a smaller wallet file and better privacy.";
        strings_["consolidate_funds_btn"] = "Consolidate";
        strings_["merge_scope_loading"] = "Checking your inputs\xE2\x80\xA6";
        strings_["merge_scope_fmt"] = "%d transparent + %d shielded inputs  \xC2\xB7  ~%s DRGX spendable";
        strings_["merge_source"] = "Consolidate";
        strings_["merge_src_transparent"] = "Transparent";
        strings_["merge_src_shielded"] = "Shielded";
        strings_["merge_src_both"] = "Both";
        strings_["merge_batch_fmt"] = "Merges up to %d inputs per run \xE2\x80\x94 repeat to finish the rest.";
        strings_["merge_advanced"] = "Advanced";
        strings_["merge_max_inputs"] = "Max inputs per batch";
        strings_["merge_fee_hint"] = "Network fee for this transaction.";
        strings_["merge_create_zaddr"] = "Create shielded address";
        strings_["merge_creating"] = "Creating address\xE2\x80\xA6";
        strings_["merge_addr_created"] = "Shielded address created.";
        strings_["merge_confirm_fmt"] = "Consolidate ~%s DRGX from %d input(s) into %s?";
        strings_["merge_confirm_btn"] = "Confirm";
        strings_["merge_back"] = "Back";
        strings_["merge_progress"] = "Consolidating\xE2\x80\xA6 this can take a few minutes. You can close this window.";
        strings_["merge_no_spendable"] = "No spendable inputs to consolidate yet.";
        strings_["done"] = "Done";

        // --- Transaction Details Dialog ---
        strings_["tx_confirmations"] = "%d confirmations";
        strings_["tx_details_title"] = "Transaction Details";
        strings_["tx_from_address"] = "From Address:";
        strings_["tx_id_label"] = "Transaction ID:";
        strings_["tx_immature"] = "IMMATURE";
        strings_["tx_mined"] = "MINED";
        strings_["tx_received"] = "RECEIVED";
        strings_["tx_sent"] = "SENT";
        strings_["tx_to_address"] = "To Address:";
        strings_["tx_view_explorer"] = "View on Explorer";

        // --- Validate Address Dialog ---
        strings_["validate_btn"] = "Validate";
        strings_["validate_description"] = "Enter a DragonX address to check if it's valid and whether it belongs to this wallet.";
        strings_["validate_invalid"] = "INVALID";
        strings_["validate_is_mine"] = "This wallet owns this address";
        strings_["validate_not_mine"] = "Not owned by this wallet";
        strings_["validate_ownership"] = "Ownership:";
        strings_["validate_results"] = "Results:";
        strings_["validate_results_placeholder"] = "Results will appear here";
        strings_["validate_shielded_type"] = "Shielded (z-address)";
        strings_["validate_status"] = "Status:";
        strings_["validate_title"] = "Validate Address";
        strings_["validate_transparent_type"] = "Transparent (t-address)";
        strings_["validate_type"] = "Type:";
        strings_["validate_valid"] = "VALID";

        // Misc dialog/tab strings
        strings_["ram_wallet_gb"] = "Wallet:  %.1f GB";
        strings_["ram_wallet_mb"] = "Wallet:  %.0f MB";
        strings_["ram_daemon_gb"] = "Daemon:  %.1f GB  (%s)";
        strings_["ram_daemon_mb"] = "Daemon:  %.0f MB  (%s)";
        strings_["ram_system_gb"] = "System:  %.1f / %.0f GB";
        strings_["shield_operation_id"] = "Operation ID: %s";
        strings_["peers_peer_label"] = "Peer: %s";
        strings_["error_format"] = "Error: %s";
        strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
        strings_["key_export_viewing_keys_zonly"] = "Viewing keys are only available for shielded (z) addresses";
        strings_["backup_source"] = "Source: %s";
        strings_["export_keys_progress"] = "Exporting %d/%d...";
        strings_["import_key_progress"] = "Importing %d/%d...";
        strings_["click_to_copy"] = "Click to copy";
        strings_["block_hash_copied"] = "Block hash copied";

        // Explorer tab
        strings_["explorer"] = "Explorer";
        strings_["explorer_search"] = "Search";
        strings_["explorer_chain_stats"] = "Chain";
        strings_["explorer_mempool"] = "Mempool";
        strings_["explorer_mempool_txs"] = "Transactions";
        strings_["explorer_mempool_size"] = "Size";
        strings_["explorer_recent_blocks"] = "Recent Blocks";
        strings_["explorer_block_detail"] = "Block";
        strings_["explorer_block_height"] = "Height";
        strings_["explorer_block_hash"] = "Hash";
        strings_["explorer_block_txs"] = "Transactions";
        strings_["explorer_block_size"] = "Size";
        strings_["explorer_block_time"] = "Time";
        strings_["explorer_block_merkle"] = "Merkle Root";
        strings_["explorer_tx_outputs"] = "Outputs";
        strings_["explorer_tx_size"] = "Size";
        strings_["explorer_txid"] = "TxID:";
        strings_["explorer_prev_block"] = "Previous block";
        strings_["explorer_next_block"] = "Next block";
        // --- Antivirus (Windows Defender) help dialog (Windows-only) ---
        strings_["av_title"] = "Windows Defender Blocked Miner";
        strings_["av_intro"] = "Mining software is often flagged as potentially unwanted. Follow these steps to enable pool mining:";
        strings_["av_step1"] = "Step 1: Add Exclusion";
        strings_["av_step1_b1"] = "Open Windows Security > Virus & threat protection";
        strings_["av_step1_b2"] = "Click Manage settings > Exclusions > Add or remove";
        strings_["av_step1_b3"] = "Add folder: %APPDATA%\\ObsidianDragon\\";
        strings_["av_step2"] = "Step 2: Restore from Quarantine (if needed)";
        strings_["av_step2_b1"] = "Windows Security > Protection history";
        strings_["av_step2_b2"] = "Find xmrig.exe and click Restore";
        strings_["av_step3"] = "Step 3: Restart wallet and try again";
        strings_["av_open_security"] = "Open Windows Security";
        strings_["explorer_invalid_query"] = "Enter a block height or 64-character hash";
        strings_["explorer_invalid_response"] = "Invalid response from daemon";
        strings_["explorer_hash_not_found"] = "No block or transaction found for this hash";
        strings_["explorer_not_connected"] = "Not connected to daemon — cannot look up a block or transaction hash";
        strings_["explorer_no_results"] = "No matching cached blocks";

        // ---- i18n audit 2026-09: wrap previously-hardcoded UI strings ----
        // app_security.cpp — encryption / PIN / lock flow
        strings_["sec_restart_daemon_for_encryption"] = "Please restart your daemon for encryption to take effect.";
        strings_["sec_encrypting_wallet"] = "Encrypting wallet...";
        strings_["sec_wallet_encrypted_restarting_daemon"] = "Wallet encrypted. Restarting daemon...";
        strings_["sec_wallet_encrypted_successfully"] = "Wallet encrypted successfully";
        strings_["sec_encryption_failed_prefix"] = "Encryption failed: ";
        strings_["sec_wallet_encrypted_and_pin_set"] = "Wallet encrypted & PIN set";
        strings_["sec_wallet_encrypted_but_pin_vault_failed"] = "Wallet encrypted but PIN vault failed";
        strings_["sec_couldnt_lock_wallet"] = "Couldn't lock the wallet — it is still unlocked. Check the daemon connection.";
        strings_["sec_changing_passphrase"] = "Changing passphrase...";
        strings_["sec_passphrase_changed_successfully"] = "Passphrase changed successfully";
        strings_["sec_failed_prefix"] = "Failed: ";
        strings_["sec_encryption_did_not_complete"] = "Wallet encryption did not complete — your wallet is NOT encrypted. Open Settings to finish encrypting it.";
        strings_["sec_wallet_locked_title"] = "Wallet Locked";
        strings_["sec_too_many_attempts_wait"] = "Too many attempts. Wait %.0f seconds...";
        strings_["sec_mode_passphrase"] = " Passphrase";
        strings_["sec_use_passphrase_instead"] = "Use passphrase instead";
        strings_["sec_use_pin_instead"] = "Use PIN instead";
        strings_["sec_unlocking_fmt"] = "Unlocking%s";
        strings_["sec_unlock_button"] = "Unlock";
        strings_["sec_not_connected_to_daemon"] = "Not connected to daemon";
        strings_["sec_unlock_failed_prefix"] = "Unlock failed: ";
        strings_["sec_incorrect_passphrase_decrypt"] = "Incorrect passphrase";
        strings_["sec_importing_keys_rescanning"] = "Importing keys & rescanning blockchain — wallet is usable while this runs";
        strings_["sec_encrypted_backup_suffix"] = "\nEncrypted backup: wallet.dat.encrypted.bak";
        strings_["sec_wallet_decrypted_all_keys_imported"] = "Wallet decrypted successfully! All keys imported.";
        strings_["sec_total_elapsed_fmt"] = "Total elapsed: %dm %02ds";
        strings_["sec_verifying_passphrase"] = "Verifying passphrase...";
        strings_["sec_incorrect_passphrase_pin_setup"] = "Incorrect passphrase";
        strings_["sec_pin_set_successfully"] = "PIN set successfully";
        strings_["sec_failed_to_create_vault"] = "Failed to create vault";
        strings_["sec_not_connected_to_daemon_pin"] = "Not connected to daemon";
        strings_["sec_changing_pin"] = "Changing PIN...";
        strings_["sec_pin_changed_successfully"] = "PIN changed successfully";
        strings_["sec_incorrect_current_pin"] = "Incorrect current PIN";
        strings_["sec_internal_error_change_pin"] = "Internal error";
        strings_["sec_verifying_pin"] = "Verifying PIN...";
        strings_["sec_pin_removed"] = "PIN removed";
        strings_["sec_incorrect_pin_remove"] = "Incorrect PIN";
        strings_["sec_internal_error_remove_pin"] = "Internal error";

        // app.cpp — wizard, seed backup, shutdown, daemon/miner lifecycle
        strings_["appx_creating_your_wallet"] = "Creating your wallet…";
        strings_["appx_create_failed_prefix"] = "Create failed: ";
        strings_["appx_back_up_seed_phrase_title"] = "Back up your seed phrase";
        strings_["appx_seed_backup_warning"] = "These 24 words are the ONLY way to restore your wallet. Write them down in order, store them offline, and never share them. If you lose them, your funds are gone forever.";
        strings_["appx_birthday_block_height"] = "Birthday (block height): %llu  —  back this up too.";
        strings_["appx_ive_written_it_down"] = "I've written it down";
        strings_["appx_copy"] = "Copy";
        strings_["appx_skip_anyway"] = "Skip anyway";
        strings_["appx_skip"] = "Skip";
        strings_["appx_seed_not_backed_up_warning"] = "You have not backed up your seed — funds could be lost. Skip anyway?";
        strings_["appx_confirm_your_backup"] = "Confirm your backup";
        strings_["appx_tap_words_in_order"] = "Tap the words in the correct order to confirm you saved them.";
        strings_["appx_progress_n_of_n"] = "Progress: %d / %d";
        strings_["appx_not_next_word"] = "  — that's not the next word";
        strings_["appx_done"] = "Done";
        strings_["appx_wallet_created_and_backed_up"] = "Wallet created and backed up.";
        strings_["appx_back"] = "Back";
        strings_["appx_restoring_your_wallet"] = "Restoring your wallet…";
        strings_["appx_recovery_phrase_word_count"] = "Recovery phrase should be 24 words — you have %d.";
        strings_["appx_could_not_start_restore"] = "Could not start restore";
        strings_["appx_node_rebuilding_witness_cache"] = "Node is rebuilding its witness cache";
        strings_["appx_stopping_node_discards_rebuild"] = "Stopping the node now discards the in-progress rebuild and restarts it (several minutes) the next time you open the wallet. You can keep the node running instead.";
        strings_["appx_keep_node_running_and_quit"] = "Keep node running & quit";
        strings_["appx_stop_anyway_and_quit"] = "Stop anyway & quit";
        strings_["appx_cancel"] = "Cancel";
        strings_["appx_last_used_wallet_not_found_prefix"] = "Your last-used wallet file (";
        strings_["appx_last_used_wallet_not_found_suffix"] = ") was not found — opened the default wallet instead. If you moved it, restore it and switch back from the wallet list.";
        strings_["appx_wallet_open_failed_prefix"] = "Wallet open failed: ";
        strings_["appx_blockchain_rescan_complete"] = "Blockchain rescan complete";
        strings_["appx_miner_stopped_unexpectedly"] = "Miner stopped unexpectedly.";
        strings_["appx_miner_stopped_prefix"] = "Miner stopped: ";
        strings_["appx_pool_miner_connected_and_hashing"] = "Pool miner connected and hashing.";
        strings_["appx_bootstrap_complete_reconciling"] = "Bootstrap complete — reconciling your wallet with the new chain data.";
        strings_["appx_blockchain_data_deleted"] = "Blockchain data deleted (%d items). The daemon is restarting to re-sync from the network.";
        strings_["appx_invalid_payment_uri_prefix"] = "Invalid payment URI: ";
        strings_["appx_payment_request_loaded"] = "Payment request loaded";
        strings_["appx_fullnode_lifecycle_unavailable_lite"] = "Full-node lifecycle actions are unavailable in lite build";
        strings_["appx_blockchain_maintenance_in_progress"] = "A blockchain maintenance operation is already in progress.";
        strings_["appx_node_busy_restarting"] = "The node is busy restarting — try again in a moment.";
        strings_["appx_restarting_daemon_rescan_flag"] = "Restarting daemon with -rescan flag...";
        strings_["appx_restarting_daemon_zapwallettxes"] = "Restarting daemon with -zapwallettxes=2 (wallet repair)...";
        strings_["appx_no_bundled_daemon_to_install"] = "This build has no bundled daemon to install";
        strings_["appx_no_embedded_daemon_to_install"] = "This build has no embedded daemon to install";
        strings_["appx_daemon_reinstall_in_progress"] = "The daemon reinstall is already in progress.";
        strings_["appx_installing_bundled_daemon"] = "Installing bundled daemon — the node will stop, update, and restart...";
        strings_["appx_stopping_daemon_deleting_blockchain"] = "Stopping daemon and deleting blockchain data...";
        strings_["appx_stopping_pool_miner"] = "Stopping pool miner...";
        strings_["appx_disconnecting"] = "Disconnecting...";
        strings_["appx_sending_stop_command_to_daemon"] = "Sending stop command to daemon...";
        strings_["appx_cleaning_up"] = "Cleaning up...";
        strings_["appx_shutdown_complete"] = "Shutdown complete";
        strings_["appx_n_seconds"] = "%d seconds";
        strings_["appx_n_min_n_sec"] = "%d min %d sec";
        strings_["appx_still_status_prefix"] = "Still \"";
        strings_["appx_still_status_suffix"] = "\" — force quitting now may corrupt chain data.";
        strings_["appx_rebuilding_witness_cache_blocks_left"] = "Rebuilding witness cache %.0f%% — %d blocks left";
        strings_["appx_rebuilding_witness_cache_pct"] = "Rebuilding witness cache %.0f%%";
        strings_["appx_setting_initial_sapling_witnesses"] = "Setting initial Sapling witnesses %.0f%%";
        strings_["appx_rebuilding_sapling_note_witnesses"] = "Rebuilding Sapling note witnesses…";
        strings_["appx_syncing_pct_block_n_of_n"] = "Syncing %.1f%% — Block %d / %d";
        strings_["appx_last_block_n"] = "Last block: %d";
        strings_["appx_encrypting_wallet"] = "Encrypting wallet...";
        strings_["appx_waiting_for_daemon_to_encrypt_wallet"] = "Waiting for daemon to encrypt wallet...";
        strings_["appx_daemon_error"] = "Daemon Error";
        strings_["appx_use_settings_restart_daemon_hint"] = "Use Settings > Restart Daemon to try again";
        strings_["appx_copied_clipboard_autoclears"] = "Copied — clipboard auto-clears in 45s";
        strings_["appx_dragonxd_output"] = "dragonxd output";
        strings_["appx_theme_prefix"] = "Theme: ";
        strings_["appx_low_spec_mode_enabled"] = "Low-spec mode enabled";
        strings_["appx_low_spec_mode_disabled"] = "Low-spec mode disabled";
        strings_["appx_theme_effects_enabled"] = "Theme effects enabled";
        strings_["appx_theme_effects_disabled"] = "Theme effects disabled";
        strings_["appx_simple_background_enabled"] = "Simple background enabled";
        strings_["appx_simple_background_disabled"] = "Simple background disabled";

        // balance_tab.cpp
        strings_["baltab_shielded_amount"] = "Shielded  %.8f";
        strings_["baltab_transparent_amount"] = "Transparent  %.8f";
        strings_["baltab_market_price_4dp"] = "Market: $%.4f";
        strings_["baltab_market_price_8dp"] = "Market: $%.8f";
        strings_["baltab_pct_of_total_zaddr"] = "%.0f%% of total  ·  %d Z-addr";
        strings_["baltab_t_addresses_count"] = "%d T-addresses";
        strings_["baltab_pct_change_24h"] = "%s%.1f%% 24h";
        strings_["baltab_total_balance"] = "Total Balance";
        strings_["baltab_shielded"] = "Shielded";
        strings_["baltab_transparent"] = "Transparent";
        strings_["baltab_market"] = "Market";

        // settings_window.cpp
        strings_["swin_invalid_suffix"] = " (invalid)";
        strings_["swin_theme_list_refreshed"] = "Theme list refreshed";
        strings_["swin_connection_successful"] = "Connection successful!\ndragonxd version: ";
        strings_["swin_connection_failed"] = "Connection failed: ";
        strings_["swin_rpc_client_not_initialized"] = "RPC client not initialized";
        strings_["swin_rescan_started_from_block"] = "Rescan started from block ";
        strings_["swin_rescan_to"] = " to ";
        strings_["swin_rescan_failed"] = "Rescan failed: ";
        strings_["swin_ztx_history_cleared"] = "Z-transaction history cleared";
        strings_["swin_no_history_file_found"] = "No history file found";
        strings_["swin_settings_saved"] = "Settings saved";

        // settings_page.cpp / explorer_tab.cpp / block_info_dialog.cpp
        strings_["grpa_tab_appearance"] = "Appearance";
        strings_["grpa_tab_wallet"] = "Wallet";
        strings_["grpa_tab_backup_data"] = "Backup & Data";
        strings_["grpa_tab_node_security"] = "Node & Security";
        strings_["grpa_tab_explorer"] = "Explorer";
        strings_["grpa_tab_chat"] = "Chat";
        strings_["grpa_tab_about"] = "About";
        strings_["grpa_enter_private_key_to_import"] = "Enter a private key to import.";
        strings_["grpa_invalid_suffix"] = " (invalid)";
        strings_["grpa_seed_demo_chat"] = "Seed demo chat";
        strings_["grpa_dbg_addrman"] = "Peer address tracking and management";
        strings_["grpa_dbg_alert"] = "Alert system messages";
        strings_["grpa_dbg_bench"] = "Benchmark timings for operations";
        strings_["grpa_dbg_coindb"] = "Coin database read/write operations";
        strings_["grpa_dbg_db"] = "Berkeley DB operations";
        strings_["grpa_dbg_estimatefee"] = "Fee estimation algorithm";
        strings_["grpa_dbg_http"] = "HTTP RPC server activity";
        strings_["grpa_dbg_libevent"] = "Libevent networking library";
        strings_["grpa_dbg_lock"] = "Lock contention debugging";
        strings_["grpa_dbg_mempool"] = "Transaction memory pool activity";
        strings_["grpa_dbg_net"] = "Network connections and messages";
        strings_["grpa_dbg_paymentdisclosure"] = "Payment disclosure protocol";
        strings_["grpa_dbg_pow"] = "Proof-of-work mining activity";
        strings_["grpa_dbg_proxy"] = "SOCKS5 proxy connections";
        strings_["grpa_dbg_prune"] = "Block pruning operations";
        strings_["grpa_dbg_rand"] = "Random number generation";
        strings_["grpa_dbg_reindex"] = "Blockchain reindexing progress";
        strings_["grpa_dbg_rpc"] = "RPC command processing";
        strings_["grpa_dbg_selectcoins"] = "Coin selection for transactions";
        strings_["grpa_dbg_tor"] = "Tor integration and circuit info";
        strings_["grpa_dbg_zmq"] = "ZeroMQ notification system";
        strings_["grpa_dbg_zrpc"] = "Shielded (z-addr) RPC operations";
        strings_["grpa_sec_ago"] = "%lld sec ago";
        strings_["grpa_min_ago"] = "%lld min ago";
        strings_["grpa_hr_ago"] = "%lld hr ago";
        strings_["grpa_days_ago"] = "%lld days ago";
        strings_["grpa_showing_first_100_of"] = "... showing first 100 of %d";
        strings_["grpa_error_prefix"] = "Error: ";
        strings_["grpa_invalid_response_from_daemon"] = "Invalid response from daemon";
        strings_["grpa_current_block_paren"] = "(Current: %d)";
        strings_["grpa_unexpected_getblockhash_result"] = "unexpected getblockhash result";

        // receive / chat / send / transaction_details
        strings_["grpb_new_badge_suffix"] = "  [NEW]";
        strings_["grpb_tooltip_address_balance"] = "%s\nBalance: %.8f %s%s";
        strings_["grpb_selected_suffix"] = "\n(selected)";
        strings_["grpb_preview_msg_payment_through"] = "Did the payment go through? 🙂";
        strings_["grpb_preview_msg_yep_confirmed"] = "Yep — just confirmed ✅";
        strings_["grpb_preview_msg_sending_rest"] = "Sending the rest now 👍";
        strings_["grpb_max"] = "Max";
        strings_["grpb_undo_clear"] = "Undo Clear";
        strings_["grpb_copy"] = "Copy";

        // bootstrap / mining_* / key_export
        strings_["grpc_bootstrap_not_initialized"] = "Bootstrap not initialized";
        strings_["grpc_bootstrap_failed"] = "Bootstrap failed";
        strings_["grpc_na"] = "N/A";
        strings_["grpc_key_not_available"] = "Key not available for this address";
        strings_["grpc_benchmark_takes_secs"] = "Benchmark takes ~%ds and interrupts mining. Click again to start.";
        strings_["grpc_hashrate_fee"] = "%s  %s%% fee";
        strings_["grpc_benchmark_inconclusive"] = "Benchmark inconclusive: no hashrate samples were recorded. Check the pool connection and try again.";

        // misc pre-existing missing keys
        strings_["copied_to_clipboard"] = "Copied to clipboard";

}

const char* I18n::translate(const char* key) const
{
    if (!key) return "";
    
    auto it = strings_.find(key);
    if (it != strings_.end()) {
        return it->second.c_str();
    }
    
    // Return key if translation not found
    return key;
}

void I18n::registerLanguage(const std::string& code, const std::string& name)
{
    // Check if already registered
    for (const auto& lang : available_languages_) {
        if (lang.first == code) return;
    }
    
    available_languages_.emplace_back(code, name);
}

} // namespace util
} // namespace dragonx
