"""Streamlit UI internationalization.

Auto-detects browser language from `Accept-Language` (where available) with
manual override via a sidebar selector. Falls back to English.

Languages: en (default), ja, zh-CN, ko, es, fr, de, pt-BR.

Usage:

    from praxia.ui.i18n import t, language_selector_in_sidebar

    language_selector_in_sidebar()   # call once, near the top
    st.title(t("app.title"))
    st.caption(t("app.tagline"))

Translation strategy mirrors the landing page: top-of-funnel + tab labels +
section headings are translated; long-form English content (skill prompt
output, framework explanations) stays English (mirroring the landing page's
"key UI strings translated" approach).
"""
from __future__ import annotations

import os
from typing import Any

SUPPORTED = ["en", "ja", "zh-CN", "ko", "es", "fr", "de", "pt-BR"]

LANG_DISPLAY = {
    "en": "English",
    "ja": "日本語",
    "zh-CN": "简体中文",
    "ko": "한국어",
    "es": "Español",
    "fr": "Français",
    "de": "Deutsch",
    "pt-BR": "Português (BR)",
}

# Translation dictionary. Keys are dot-separated.
_T: dict[str, dict[str, str]] = {
    "app.title": {
        "en": "🪡 Praxia",
        "ja": "🪡 Praxia",
        "zh-CN": "🪡 Praxia",
        "ko": "🪡 Praxia",
        "es": "🪡 Praxia",
        "fr": "🪡 Praxia",
        "de": "🪡 Praxia",
        "pt-BR": "🪡 Praxia",
    },
    "app.tagline": {
        "en": "Multi-agent orchestrator with cyclic memory",
        "ja": "メモリ循環型マルチエージェント・オーケストレータ",
        "zh-CN": "带循环记忆的多智能体编排器",
        "ko": "순환 메모리를 갖춘 멀티 에이전트 오케스트레이터",
        "es": "Orquestador multi-agente con memoria cíclica",
        "fr": "Orchestrateur multi-agents avec mémoire cyclique",
        "de": "Multi-Agenten-Orchestrator mit zyklischem Speicher",
        "pt-BR": "Orquestrador multi-agente com memória cíclica",
    },
    "sidebar.user": {
        "en": "User ID (your namespace)",
        "ja": "ユーザ ID (個人ネームスペース)",
        "zh-CN": "用户 ID (您的命名空间)",
        "ko": "사용자 ID (개인 네임스페이스)",
        "es": "ID de usuario (tu espacio de nombres)",
        "fr": "ID utilisateur (votre espace de noms)",
        "de": "Benutzer-ID (Ihr Namespace)",
        "pt-BR": "ID de usuário (seu namespace)",
    },
    "sidebar.org": {
        "en": "Org ID",
        "ja": "組織 ID",
        "zh-CN": "组织 ID",
        "ko": "조직 ID",
        "es": "ID de organización",
        "fr": "ID d'organisation",
        "de": "Organisations-ID",
        "pt-BR": "ID da organização",
    },
    "sidebar.model": {
        "en": "Model",
        "ja": "モデル",
        "zh-CN": "模型",
        "ko": "모델",
        "es": "Modelo",
        "fr": "Modèle",
        "de": "Modell",
        "pt-BR": "Modelo",
    },
    "sidebar.backend": {
        "en": "Memory backend",
        "ja": "メモリバックエンド",
        "zh-CN": "记忆后端",
        "ko": "메모리 백엔드",
        "es": "Backend de memoria",
        "fr": "Backend de mémoire",
        "de": "Speicher-Backend",
        "pt-BR": "Backend de memória",
    },
    "sidebar.language": {
        "en": "Language",
        "ja": "言語",
        "zh-CN": "语言",
        "ko": "언어",
        "es": "Idioma",
        "fr": "Langue",
        "de": "Sprache",
        "pt-BR": "Idioma",
    },
    "sidebar.compact": {
        "en": "Compact mode",
        "ja": "コンパクト表示",
        "zh-CN": "紧凑模式",
        "ko": "컴팩트 모드",
        "es": "Modo compacto",
        "fr": "Mode compact",
        "de": "Kompaktansicht",
        "pt-BR": "Modo compacto",
    },
    "sidebar.view": {
        "en": "View",
        "ja": "ビュー",
        "zh-CN": "视图",
        "ko": "뷰",
        "es": "Vista",
        "fr": "Vue",
        "de": "Ansicht",
        "pt-BR": "Visão",
    },
    "sidebar.readme": {
        "en": "README",
        "ja": "README",
        "zh-CN": "README",
        "ko": "README",
        "es": "README",
        "fr": "README",
        "de": "README",
        "pt-BR": "README",
    },
    "sidebar.issues": {
        "en": "Issues",
        "ja": "Issue",
        "zh-CN": "Issue",
        "ko": "이슈",
        "es": "Issues",
        "fr": "Issues",
        "de": "Issues",
        "pt-BR": "Issues",
    },
    # ===== Mode picker labels (sidebar radio) ===============================
    "mode.flow": {
        "en": "🎬 Multi-agent flow",
        "ja": "🎬 マルチエージェントフロー",
        "zh-CN": "🎬 多智能体流程",
        "ko": "🎬 멀티에이전트 플로우",
        "es": "🎬 Flujo multi-agente",
        "fr": "🎬 Flux multi-agents",
        "de": "🎬 Multi-Agenten-Flow",
        "pt-BR": "🎬 Fluxo multi-agente",
    },
    "mode.skill": {
        "en": "🛠 Skill",
        "ja": "🛠 スキル",
        "zh-CN": "🛠 技能",
        "ko": "🛠 스킬",
        "es": "🛠 Habilidad",
        "fr": "🛠 Compétence",
        "de": "🛠 Skill",
        "pt-BR": "🛠 Habilidade",
    },
    "mode.memory": {
        "en": "🧠 Knowledge",
        "ja": "🧠 ナレッジ",
        "zh-CN": "🧠 知识",
        "ko": "🧠 지식",
        "es": "🧠 Conocimiento",
        "fr": "🧠 Connaissances",
        "de": "🧠 Wissen",
        "pt-BR": "🧠 Conhecimento",
    },
    "mode.consolidate": {
        "en": "🌙 Consolidate",
        "ja": "🌙 統合",
        "zh-CN": "🌙 整合",
        "ko": "🌙 통합",
        "es": "🌙 Consolidar",
        "fr": "🌙 Consolider",
        "de": "🌙 Konsolidieren",
        "pt-BR": "🌙 Consolidar",
    },
    "mode.dashboard": {
        "en": "📊 Dashboard",
        "ja": "📊 ダッシュボード",
        "zh-CN": "📊 仪表板",
        "ko": "📊 대시보드",
        "es": "📊 Panel",
        "fr": "📊 Tableau de bord",
        "de": "📊 Dashboard",
        "pt-BR": "📊 Painel",
    },
    "mode.prompts": {
        "en": "📝 Prompts",
        "ja": "📝 プロンプト",
        "zh-CN": "📝 提示词",
        "ko": "📝 프롬프트",
        "es": "📝 Prompts",
        "fr": "📝 Prompts",
        "de": "📝 Prompts",
        "pt-BR": "📝 Prompts",
    },
    "mode.admin": {
        "en": "⚙ Admin",
        "ja": "⚙ 管理",
        "zh-CN": "⚙ 管理",
        "ko": "⚙ 관리",
        "es": "⚙ Admin",
        "fr": "⚙ Admin",
        "de": "⚙ Admin",
        "pt-BR": "⚙ Admin",
    },
    "mode.run": {
        "en": "🎬 Run",
        "ja": "🎬 実行",
        "zh-CN": "🎬 运行",
        "ko": "🎬 실행",
        "es": "🎬 Ejecutar",
        "fr": "🎬 Exécuter",
        "de": "🎬 Ausführen",
        "pt-BR": "🎬 Executar",
    },
    "mode.preferences": {
        "en": "👤 Preferences",
        "ja": "👤 個人設定",
        "zh-CN": "👤 偏好设置",
        "ko": "👤 환경 설정",
        "es": "👤 Preferencias",
        "fr": "👤 Préférences",
        "de": "👤 Einstellungen",
        "pt-BR": "👤 Preferências",
    },
    "mode.connections": {
        "en": "🔗 Service Connections",
        "ja": "🔗 外部サービス連携",
        "zh-CN": "🔗 外部服务集成",
        "ko": "🔗 외부 서비스 연동",
        "es": "🔗 Conexiones",
        "fr": "🔗 Connexions",
        "de": "🔗 Verbindungen",
        "pt-BR": "🔗 Conexões",
    },
    "preferences.h": {
        "en": "👤 Preferences",
        "ja": "👤 個人設定",
        "zh-CN": "👤 偏好设置",
        "ko": "👤 환경 설정",
        "es": "👤 Preferencias",
        "fr": "👤 Préférences",
        "de": "👤 Einstellungen",
        "pt-BR": "👤 Preferências",
    },
    "preferences.intro": {
        "en": "Per-user view + runtime preferences. Available to everyone — no admin role required.",
        "ja": "ユーザ毎の表示 + 実行時設定。全ユーザが使用可能 — admin ロール不要。",
        "zh-CN": "每用户的视图 + 运行时偏好。所有用户可用 — 无需 admin 角色。",
        "ko": "사용자별 보기 + 런타임 환경 설정. 모든 사용자 사용 가능 — admin 역할 불필요.",
        "es": "Preferencias de vista y runtime por usuario. Disponible para todos — sin rol admin.",
        "fr": "Préférences d'affichage et runtime par utilisateur. Pour tous — pas de rôle admin requis.",
        "de": "Pro-Nutzer-Anzeige + Laufzeit-Einstellungen. Für alle verfügbar — kein admin nötig.",
        "pt-BR": "Preferências de visualização e runtime por usuário. Disponível para todos — sem papel admin.",
    },
    "preferences.language_h": {
        "en": "🌐 Language",
        "ja": "🌐 言語",
        "zh-CN": "🌐 语言",
        "ko": "🌐 언어",
        "es": "🌐 Idioma",
        "fr": "🌐 Langue",
        "de": "🌐 Sprache",
        "pt-BR": "🌐 Idioma",
    },
    "preferences.language_intro": {
        "en": "Auto-detected from browser/OS at first load. Override here for this session.",
        "ja": "初回起動時にブラウザ/OS から自動検出。このセッションで切替えたい場合のみ変更してください。",
        "zh-CN": "首次加载时从浏览器/OS 自动检测。需要本会话切换时在此覆盖。",
        "ko": "처음 로드 시 브라우저/OS 에서 자동 감지. 이 세션에서 다른 언어를 원하면 여기서 변경.",
        "es": "Auto-detectado del navegador/OS al inicio. Cambia aquí para esta sesión.",
        "fr": "Auto-détecté depuis le navigateur/OS au démarrage. Modifiez ici pour cette session.",
        "de": "Beim Laden vom Browser/OS automatisch erkannt. Hier für diese Sitzung ändern.",
        "pt-BR": "Auto-detectado do navegador/OS no início. Troque aqui para esta sessão.",
    },
    "preferences.language_label": {
        "en": "Display language",
        "ja": "表示言語",
        "zh-CN": "显示语言",
        "ko": "표시 언어",
        "es": "Idioma de la interfaz",
        "fr": "Langue d'affichage",
        "de": "Anzeigesprache",
        "pt-BR": "Idioma de exibição",
    },
    "preferences.llm_h": {
        "en": "🤖 LLM model",
        "ja": "🤖 LLM モデル",
        "zh-CN": "🤖 LLM 模型",
        "ko": "🤖 LLM 모델",
        "es": "🤖 Modelo LLM",
        "fr": "🤖 Modèle LLM",
        "de": "🤖 LLM-Modell",
        "pt-BR": "🤖 Modelo LLM",
    },
    "preferences.llm_intro": {
        "en": "Which LLM should answer your runs by default. Per-session — admin can pin a tenant default in Admin → Settings.",
        "ja": "実行時に既定で使う LLM。このセッション内のみ反映。テナント既定値の固定は admin の設定 → 永続から。",
        "zh-CN": "默认用于运行的 LLM。仅本会话生效。租户默认在 admin → 持久 中固定。",
        "ko": "기본 실행에 사용할 LLM. 이 세션에만 반영. 테넌트 기본값은 admin → 영속 에서 고정.",
        "es": "LLM que responde tus runs por defecto. Por sesión. El admin fija un default tenant en Admin → Settings.",
        "fr": "LLM par défaut pour vos runs. Par session. L'admin fixe un défaut tenant dans Admin → Settings.",
        "de": "Standard-LLM für deine Runs. Pro Sitzung. Admin setzt Tenant-Default unter Admin → Settings.",
        "pt-BR": "LLM padrão para seus runs. Por sessão. Admin fixa default do tenant em Admin → Settings.",
    },
    "preferences.model_label": {
        "en": "LLM model",
        "ja": "LLM モデル",
        "zh-CN": "LLM 模型",
        "ko": "LLM 모델",
        "es": "Modelo LLM",
        "fr": "Modèle LLM",
        "de": "LLM-Modell",
        "pt-BR": "Modelo LLM",
    },
    "preferences.model_custom": {
        "en": "Custom model string (e.g. anthropic/claude-opus-4-7)",
        "ja": "カスタムモデル文字列 (例: anthropic/claude-opus-4-7)",
        "zh-CN": "自定义模型字符串(如 anthropic/claude-opus-4-7)",
        "ko": "커스텀 모델 문자열 (예: anthropic/claude-opus-4-7)",
        "es": "Cadena de modelo personalizada (p. ej. anthropic/claude-opus-4-7)",
        "fr": "Chaîne de modèle personnalisée (ex. anthropic/claude-opus-4-7)",
        "de": "Benutzerdefinierter Modell-String (z. B. anthropic/claude-opus-4-7)",
        "pt-BR": "String de modelo personalizada (ex. anthropic/claude-opus-4-7)",
    },
    "preferences.apply_btn": {
        "en": "💾 Apply",
        "ja": "💾 適用",
        "zh-CN": "💾 应用",
        "ko": "💾 적용",
        "es": "💾 Aplicar",
        "fr": "💾 Appliquer",
        "de": "💾 Anwenden",
        "pt-BR": "💾 Aplicar",
    },
    "preferences.theme_h": {
        "en": "🎨 Color theme",
        "ja": "🎨 カラーテーマ",
        "zh-CN": "🎨 颜色主题",
        "ko": "🎨 색상 테마",
        "es": "🎨 Tema de color",
        "fr": "🎨 Thème de couleur",
        "de": "🎨 Farbthema",
        "pt-BR": "🎨 Tema de cores",
    },
    "preferences.theme_intro": {
        "en": "Auto follows your OS / browser preference. Light or Dark forces a specific theme for this user.",
        "ja": "自動: OS / ブラウザの設定に追従。ライト / ダーク: このユーザだけ強制的に固定。",
        "zh-CN": "自动: 跟随系统/浏览器。浅色 / 深色: 对此用户强制固定。",
        "ko": "자동: OS/브라우저 설정 따라감. 라이트/다크: 이 사용자에게만 고정.",
        "es": "Auto sigue la preferencia del SO/navegador. Claro u Oscuro lo fija para este usuario.",
        "fr": "Auto suit la préférence OS/navigateur. Clair ou Sombre force pour cet utilisateur.",
        "de": "Auto folgt der OS-/Browser-Einstellung. Hell oder Dunkel erzwingt das Thema.",
        "pt-BR": "Auto segue a preferência do SO/navegador. Claro ou Escuro força o tema.",
    },
    "preferences.theme_label": {
        "en": "Theme",
        "ja": "テーマ",
        "zh-CN": "主题",
        "ko": "테마",
        "es": "Tema",
        "fr": "Thème",
        "de": "Thema",
        "pt-BR": "Tema",
    },
    "preferences.theme.auto": {
        "en": "Auto (follow system)",
        "ja": "自動 (システムに従う)",
        "zh-CN": "自动(跟随系统)",
        "ko": "자동 (시스템 따라감)",
        "es": "Auto (seguir sistema)",
        "fr": "Auto (suivre le système)",
        "de": "Auto (System folgen)",
        "pt-BR": "Auto (seguir sistema)",
    },
    "preferences.theme.light": {
        "en": "☀ Light",
        "ja": "☀ ライト",
        "zh-CN": "☀ 浅色",
        "ko": "☀ 라이트",
        "es": "☀ Claro",
        "fr": "☀ Clair",
        "de": "☀ Hell",
        "pt-BR": "☀ Claro",
    },
    "preferences.theme.dark": {
        "en": "🌙 Dark",
        "ja": "🌙 ダーク",
        "zh-CN": "🌙 深色",
        "ko": "🌙 다크",
        "es": "🌙 Oscuro",
        "fr": "🌙 Sombre",
        "de": "🌙 Dunkel",
        "pt-BR": "🌙 Escuro",
    },
    "preferences.llm_moved_hint": {
        "en": "ℹ The LLM model picker has moved to **Admin → Settings** — the available models depend on which API keys the admin has configured.",
        "ja": "ℹ LLM モデルの選択は **Admin → Settings** に移動しました — 利用可能なモデルは管理者が設定した API キーに依存します。",
        "zh-CN": "ℹ LLM 模型选择已移至 **Admin → Settings** — 可用模型取决于管理员配置的 API 密钥。",
        "ko": "ℹ LLM 모델 선택은 **Admin → Settings** 로 이동했습니다 — 사용 가능한 모델은 관리자가 설정한 API 키에 따라 다릅니다.",
        "es": "ℹ La selección del LLM se movió a **Admin → Settings** — los modelos disponibles dependen de las claves API del admin.",
        "fr": "ℹ Le sélecteur de LLM a été déplacé vers **Admin → Settings** — les modèles disponibles dépendent des clés API de l'admin.",
        "de": "ℹ Die LLM-Modellauswahl ist nun unter **Admin → Settings** — verfügbare Modelle hängen von den Admin-API-Keys ab.",
        "pt-BR": "ℹ O seletor de LLM foi movido para **Admin → Settings** — os modelos disponíveis dependem das chaves API do admin.",
    },
    "preferences.applied": {
        "en": "✅ Preference applied. Reloading…",
        "ja": "✅ 設定を適用しました。再読み込み中…",
        "zh-CN": "✅ 偏好已应用,正在重新加载…",
        "ko": "✅ 환경 설정 적용됨. 재로드 중…",
        "es": "✅ Preferencia aplicada. Recargando…",
        "fr": "✅ Préférence appliquée. Rechargement…",
        "de": "✅ Einstellung angewendet. Lade neu…",
        "pt-BR": "✅ Preferência aplicada. Recarregando…",
    },
    # ===== Login screen =====================================================
    "login.user_id": {
        "en": "User ID",
        "ja": "ユーザ ID",
        "zh-CN": "用户 ID",
        "ko": "사용자 ID",
        "es": "ID de usuario",
        "fr": "ID utilisateur",
        "de": "Benutzer-ID",
        "pt-BR": "ID de usuário",
    },
    "login.org_id": {
        "en": "Organization",
        "ja": "組織",
        "zh-CN": "组织",
        "ko": "조직",
        "es": "Organización",
        "fr": "Organisation",
        "de": "Organisation",
        "pt-BR": "Organização",
    },
    "login.api_key": {
        "en": "Password",
        "ja": "パスワード",
        "zh-CN": "密码",
        "ko": "비밀번호",
        "es": "Contraseña",
        "fr": "Mot de passe",
        "de": "Passwort",
        "pt-BR": "Senha",
    },
    "login.user_id_help": {
        "en": "Your username. If admin has registered users via `praxia user create`, type that name. Otherwise any name works (single-user dev mode).",
        "ja": "ユーザ名。管理者が `praxia user create` でユーザを登録済ならその名前を入力。未登録なら何でも OK (単一ユーザ開発モード)。",
        "zh-CN": "你的用户名。若管理员已用 `praxia user create` 注册过,请输入该用户名。否则任意名称即可(单用户开发模式)。",
        "ko": "사용자명. 관리자가 `praxia user create` 로 등록했다면 해당 이름을 입력. 미등록이면 아무 이름이나 가능 (단일 사용자 개발 모드).",
        "es": "Tu nombre de usuario. Si el admin lo registró con `praxia user create`, escríbelo. Si no, cualquier nombre vale (modo dev/usuario único).",
        "fr": "Votre nom d'utilisateur. Si l'admin l'a enregistré via `praxia user create`, tapez ce nom. Sinon, n'importe quel nom convient (mode dev/mono-utilisateur).",
        "de": "Dein Benutzername. Falls der admin den Nutzer mit `praxia user create` registriert hat, diesen Namen eingeben. Sonst beliebiger Name (Einzelnutzer-Dev).",
        "pt-BR": "Seu nome de usuário. Se o admin registrou via `praxia user create`, use esse nome. Caso contrário, qualquer nome serve (modo dev/usuário único).",
    },
    "login.advanced": {
        "en": "Advanced options",
        "ja": "詳細オプション",
        "zh-CN": "高级选项",
        "ko": "고급 옵션",
        "es": "Opciones avanzadas",
        "fr": "Options avancées",
        "de": "Erweiterte Optionen",
        "pt-BR": "Opções avançadas",
    },
    "login.api_key_help": {
        "en": "The API key issued by `praxia user create` is your password. Saved only once at creation — keep it.",
        "ja": "`praxia user create` で発行された API キーがあなたのパスワードです。作成時に 1 度だけ表示されるので保管してください。",
        "zh-CN": "由 `praxia user create` 发行的 API 密钥即你的密码。仅在创建时显示一次,请妥善保存。",
        "ko": "`praxia user create` 로 발급된 API 키가 비밀번호입니다. 발급 시 1 회만 표시되므로 보관하세요.",
        "es": "La clave API emitida por `praxia user create` es tu contraseña. Mostrada solo una vez al crear.",
        "fr": "La clé API émise par `praxia user create` est votre mot de passe. Affichée une seule fois.",
        "de": "Der von `praxia user create` ausgestellte API-Key ist dein Passwort. Nur einmal angezeigt.",
        "pt-BR": "A chave API emitida por `praxia user create` é sua senha. Mostrada apenas uma vez.",
    },
    "login.api_key_placeholder": {
        "en": "praxia_xxxxx…",
        "ja": "praxia_xxxxx…",
        "zh-CN": "praxia_xxxxx…",
        "ko": "praxia_xxxxx…",
        "es": "praxia_xxxxx…",
        "fr": "praxia_xxxxx…",
        "de": "praxia_xxxxx…",
        "pt-BR": "praxia_xxxxx…",
    },
    "login.api_key_required": {
        "en": "🔒 Password required — this instance has registered users. Issue one with `praxia user create <name> --role <role>`.",
        "ja": "🔒 パスワード必須 — このインスタンスにはユーザが登録されています。`praxia user create <名前> --role <ロール>` で発行してください。",
        "zh-CN": "🔒 需要密码 — 该实例已注册用户。运行 `praxia user create <名字> --role <角色>` 发行。",
        "ko": "🔒 비밀번호 필수 — 이 인스턴스에는 사용자가 등록되어 있습니다. `praxia user create <이름> --role <역할>` 로 발급.",
        "es": "🔒 Contraseña requerida — esta instancia tiene usuarios registrados. Emite con `praxia user create <nombre> --role <rol>`.",
        "fr": "🔒 Mot de passe requis — cette instance a des utilisateurs enregistrés. Émettez via `praxia user create <nom> --role <rôle>`.",
        "de": "🔒 Passwort erforderlich — diese Instanz hat registrierte Nutzer. Mit `praxia user create <name> --role <role>` ausstellen.",
        "pt-BR": "🔒 Senha obrigatória — esta instância tem usuários registrados. Emita com `praxia user create <nome> --role <papel>`.",
    },
    "login.users_exist_hint": {
        "en": "🔒 This instance has registered users — enter your User ID and password.",
        "ja": "🔒 このインスタンスにはユーザが登録されています — User ID とパスワードを入力してください。",
        "zh-CN": "🔒 此实例已注册用户 — 请输入 User ID 与密码。",
        "ko": "🔒 이 인스턴스에는 사용자가 등록되어 있습니다 — User ID 와 비밀번호를 입력하세요.",
        "es": "🔒 Esta instancia tiene usuarios registrados — introduce tu User ID y contraseña.",
        "fr": "🔒 Cette instance a des utilisateurs enregistrés — saisissez votre User ID et mot de passe.",
        "de": "🔒 Diese Instanz hat registrierte Nutzer — User ID und Passwort eingeben.",
        "pt-BR": "🔒 Esta instância tem usuários registrados — digite seu User ID e senha.",
    },
    "login.dev_mode_hint": {
        "en": "⚠️ **Single-user dev mode** — no users registered yet. Anyone reaching this URL can sign in with any username and full access. Run `praxia user create <name> --role admin` to enable role-based gating.",
        "ja": "⚠️ **単一ユーザ開発モード** — ユーザ未登録のため、この URL にアクセスできる人なら誰でも好きなユーザ名で入って全機能利用可。`praxia user create <名前> --role admin` でロールベース制御を有効化してください。",
        "zh-CN": "⚠️ **单用户开发模式** — 尚无注册用户,因此任何能访问此 URL 的人都可用任意用户名登录并拥有完整访问权限。运行 `praxia user create <名字> --role admin` 启用角色控制。",
        "ko": "⚠️ **단일 사용자 개발 모드** — 등록 사용자 없음. 이 URL 에 접근할 수 있는 누구나 임의 사용자명으로 로그인 가능. `praxia user create <이름> --role admin` 으로 역할 기반 제어 활성화.",
        "es": "⚠️ **Modo dev/usuario-único** — sin usuarios registrados. Cualquiera con la URL puede entrar con cualquier nombre. Ejecuta `praxia user create <nombre> --role admin` para activar control por rol.",
        "fr": "⚠️ **Mode dev/mono-utilisateur** — aucun utilisateur enregistré. Quiconque atteint cette URL peut se connecter avec n'importe quel nom. Exécutez `praxia user create <nom> --role admin` pour activer le contrôle par rôle.",
        "de": "⚠️ **Einzelnutzer-Dev-Modus** — keine Nutzer registriert. Jeder mit der URL kann sich mit beliebigem Namen anmelden. `praxia user create <name> --role admin` für rollenbasierte Kontrolle.",
        "pt-BR": "⚠️ **Modo dev/usuário-único** — sem usuários registrados. Qualquer um com a URL pode entrar com qualquer nome. Execute `praxia user create <nome> --role admin` para ativar controle por papel.",
    },
    "login.security_note": {
        "en": "💡 The Streamlit UI is designed for **trusted environments** (single-user / company LAN). For multi-user / internet-exposed deployments, run `praxia serve` (FastAPI + OIDC SSO) instead.",
        "ja": "💡 Streamlit UI は **信頼環境** (単一ユーザ / 社内 LAN) 向け設計です。マルチユーザ / インターネット公開向けには `praxia serve` (FastAPI + OIDC SSO) を別途デプロイしてください。",
        "zh-CN": "💡 Streamlit UI 面向 **可信环境**(单用户/内网)。多用户或公网部署请运行 `praxia serve`(FastAPI + OIDC SSO)。",
        "ko": "💡 Streamlit UI 는 **신뢰 환경** (단일 사용자 / 사내 LAN) 용 설계. 다중 사용자 / 공개망 배포는 `praxia serve` (FastAPI + OIDC SSO) 를 사용하세요.",
        "es": "💡 La UI Streamlit está diseñada para **entornos confiables** (usuario único / LAN). Para multiusuario/internet, usa `praxia serve` (FastAPI + OIDC SSO).",
        "fr": "💡 L'UI Streamlit est conçue pour des **environnements de confiance** (mono-utilisateur / LAN). Pour multi-utilisateur / internet, utilisez `praxia serve` (FastAPI + OIDC SSO).",
        "de": "💡 Die Streamlit-UI ist für **vertrauenswürdige Umgebungen** gedacht (Einzelnutzer / Firmen-LAN). Für Multi-User / Internet: `praxia serve` (FastAPI + OIDC SSO) nutzen.",
        "pt-BR": "💡 A UI Streamlit foi feita para **ambientes confiáveis** (usuário único / LAN). Para multi-usuário/internet, use `praxia serve` (FastAPI + OIDC SSO).",
    },
    "login.sso_button": {
        "en": "🔐 Sign in with {provider}",
        "ja": "🔐 {provider} でサインイン",
        "zh-CN": "🔐 使用 {provider} 登录",
        "ko": "🔐 {provider} 로 로그인",
        "es": "🔐 Iniciar sesión con {provider}",
        "fr": "🔐 Se connecter avec {provider}",
        "de": "🔐 Mit {provider} anmelden",
        "pt-BR": "🔐 Entrar com {provider}",
    },
    "login.sso_or": {
        "en": "or",
        "ja": "または",
        "zh-CN": "或",
        "ko": "또는",
        "es": "o",
        "fr": "ou",
        "de": "oder",
        "pt-BR": "ou",
    },
    "login.sso_redirecting": {
        "en": "Redirecting to your identity provider…",
        "ja": "ID プロバイダにリダイレクト中…",
        "zh-CN": "正在跳转到身份提供商…",
        "ko": "ID 프로바이더로 이동 중…",
        "es": "Redirigiendo al proveedor de identidad…",
        "fr": "Redirection vers le fournisseur d'identité…",
        "de": "Weiterleitung zum Identity Provider…",
        "pt-BR": "Redirecionando para o provedor de identidade…",
    },
    "login.sso_failed": {
        "en": "❌ SSO failed: {error}",
        "ja": "❌ SSO 失敗: {error}",
        "zh-CN": "❌ SSO 失败: {error}",
        "ko": "❌ SSO 실패: {error}",
        "es": "❌ SSO falló: {error}",
        "fr": "❌ Échec SSO : {error}",
        "de": "❌ SSO fehlgeschlagen: {error}",
        "pt-BR": "❌ SSO falhou: {error}",
    },
    "login.sso_invalid_state": {
        "en": "❌ SSO state token invalid or expired. Please click the SSO button again.",
        "ja": "❌ SSO の state トークンが無効または期限切れです。もう一度 SSO ボタンを押してください。",
        "zh-CN": "❌ SSO state 令牌无效或已过期。请再次点击 SSO 按钮。",
        "ko": "❌ SSO state 토큰이 유효하지 않거나 만료되었습니다. SSO 버튼을 다시 눌러주세요.",
        "es": "❌ Token de estado SSO inválido o expirado. Vuelve a hacer clic en el botón SSO.",
        "fr": "❌ Token d'état SSO invalide ou expiré. Cliquez à nouveau sur le bouton SSO.",
        "de": "❌ SSO-State-Token ungültig oder abgelaufen. Bitte den SSO-Button erneut drücken.",
        "pt-BR": "❌ Token de estado SSO inválido ou expirado. Clique no botão SSO novamente.",
    },
    "login.sso_no_email": {
        "en": "❌ The identity provider didn't return an email address. Praxia uses email to identify SSO users.",
        "ja": "❌ ID プロバイダから email が返されませんでした。Praxia は SSO ユーザの識別に email を使います。",
        "zh-CN": "❌ 身份提供商未返回 email。Praxia 通过 email 识别 SSO 用户。",
        "ko": "❌ ID 프로바이더가 email 을 반환하지 않았습니다. Praxia 는 SSO 사용자 식별에 email 을 사용합니다.",
        "es": "❌ El proveedor de identidad no devolvió email. Praxia usa email para identificar usuarios SSO.",
        "fr": "❌ Le fournisseur d'identité n'a pas renvoyé d'email. Praxia utilise l'email pour identifier les utilisateurs SSO.",
        "de": "❌ Der Identity Provider hat keine E-Mail zurückgegeben. Praxia identifiziert SSO-Nutzer per E-Mail.",
        "pt-BR": "❌ O provedor de identidade não retornou email. Praxia usa email para identificar usuários SSO.",
    },
    "login.sso_callback_failed": {
        "en": "❌ SSO callback failed: {error}",
        "ja": "❌ SSO コールバック失敗: {error}",
        "zh-CN": "❌ SSO 回调失败: {error}",
        "ko": "❌ SSO 콜백 실패: {error}",
        "es": "❌ Callback SSO falló: {error}",
        "fr": "❌ Callback SSO échoué : {error}",
        "de": "❌ SSO-Callback fehlgeschlagen: {error}",
        "pt-BR": "❌ Callback SSO falhou: {error}",
    },
    "login.submit": {
        "en": "Sign in",
        "ja": "サインイン",
        "zh-CN": "登录",
        "ko": "로그인",
        "es": "Entrar",
        "fr": "Connexion",
        "de": "Anmelden",
        "pt-BR": "Entrar",
    },
    "login.user_id_required": {
        "en": "User ID is required.",
        "ja": "ユーザ ID は必須です。",
        "zh-CN": "需要用户 ID。",
        "ko": "사용자 ID 가 필요합니다.",
        "es": "Se requiere ID de usuario.",
        "fr": "ID utilisateur requis.",
        "de": "Benutzer-ID erforderlich.",
        "pt-BR": "ID de usuário obrigatório.",
    },
    "login.invalid_key": {
        "en": "❌ Invalid API key.",
        "ja": "❌ API キーが無効です。",
        "zh-CN": "❌ API 密钥无效。",
        "ko": "❌ 잘못된 API 키.",
        "es": "❌ Clave API inválida.",
        "fr": "❌ Clé API invalide.",
        "de": "❌ Ungültiger API-Key.",
        "pt-BR": "❌ Chave API inválida.",
    },
    "login.dev_hint": {
        "en": "Tip: in single-user dev mode, the User ID is just a namespace label. Create proper users via `praxia user create <name> --role admin` to enable role-based gating.",
        "ja": "ヒント: 単一ユーザの開発モードでは User ID は名前空間ラベルです。`praxia user create <名前> --role admin` でユーザを作成するとロールベース制御が有効化されます。",
        "zh-CN": "提示: 单用户开发模式下,User ID 仅是命名空间标签。运行 `praxia user create <名字> --role admin` 创建用户以启用角色控制。",
        "ko": "힌트: 단일 사용자 개발 모드에서 User ID 는 네임스페이스 라벨입니다. `praxia user create <이름> --role admin` 으로 사용자를 만들면 역할 기반 제어가 활성화됩니다.",
        "es": "Tip: en modo dev/usuario-único, User ID es una etiqueta de namespace. Crea usuarios con `praxia user create <nombre> --role admin` para activar control por rol.",
        "fr": "Astuce : en mode dev/mono-utilisateur, l'User ID est juste une étiquette de namespace. Créez des utilisateurs via `praxia user create <nom> --role admin` pour activer le contrôle par rôle.",
        "de": "Tipp: Im Einzelnutzer-Dev-Modus ist die User ID nur ein Namespace-Label. Lege Nutzer mit `praxia user create <name> --role admin` an, um rollenbasierte Kontrolle zu aktivieren.",
        "pt-BR": "Dica: em modo dev/usuário-único, User ID é apenas um label de namespace. Crie usuários com `praxia user create <nome> --role admin` para ativar controle por papel.",
    },
    "login.sign_out": {
        "en": "Sign out",
        "ja": "サインアウト",
        "zh-CN": "登出",
        "ko": "로그아웃",
        "es": "Salir",
        "fr": "Déconnexion",
        "de": "Abmelden",
        "pt-BR": "Sair",
    },
    # ===== Run view (Workflow / Skill / Agent sub-tabs) =====================
    "run.h": {
        "en": "🎬 Run",
        "ja": "🎬 実行",
        "zh-CN": "🎬 运行",
        "ko": "🎬 실행",
        "es": "🎬 Ejecutar",
        "fr": "🎬 Exécuter",
        "de": "🎬 Ausführen",
        "pt-BR": "🎬 Executar",
    },
    "run.ephemeral": {
        "en": "Ephemeral run (don't accumulate to memory or skill registry)",
        "ja": "一時実行 (メモリ・Skill レジストリに残さない)",
        "zh-CN": "临时执行(不累积到记忆 / 技能注册表)",
        "ko": "임시 실행 (메모리·스킬 레지스트리에 누적하지 않음)",
        "es": "Ejecución efímera (no acumular en memoria ni registro de skills)",
        "fr": "Exécution éphémère (ne rien accumuler en mémoire / registre de skills)",
        "de": "Flüchtiger Lauf (kein Eintrag in Memory / Skill-Registry)",
        "pt-BR": "Execução efêmera (não acumular em memória / registro de skills)",
    },
    "run.ephemeral_help": {
        "en": "When ON, this run reads memory and connectors as usual, but writes nothing back: personal memory is set to read_only and the skill_registry usage log is skipped. Use for sensitive content, one-off tests, or when you don't want the run to influence the next consolidation pass.",
        "ja": "ON にすると、メモリやコネクタの読込は通常通り行うが、書込みは一切しない: 個人メモリを read_only に切替、skill_registry の usage ログ記録もスキップ。機密内容を扱う時 / 単発テスト / 次回 consolidation に影響を残したくない時に。",
        "zh-CN": "开启后,本次执行像往常一样读取记忆与连接器,但不写回:个人记忆切换为 read_only,skill_registry 的 usage 日志也跳过。适用于敏感内容、一次性测试,或不想影响下一次 consolidation 的场景。",
        "ko": "ON 으로 설정 시, 메모리·커넥터 읽기는 평소대로 하지만 쓰기는 하지 않음: 개인 메모리를 read_only 로 전환, skill_registry 사용 로그 기록도 건너뜀. 민감한 내용 / 일회성 테스트 / 다음 consolidation 에 영향 주고 싶지 않을 때.",
        "es": "Cuando está activo, esta ejecución lee memoria/conectores como siempre, pero no escribe: memoria personal en read_only y se omite el registro de uso de skill_registry. Útil para contenido sensible, pruebas puntuales o evitar influencia en la próxima consolidación.",
        "fr": "Quand activé, cette exécution lit mémoire/connecteurs normalement mais n'écrit rien : mémoire personnelle en read_only et le journal d'usage du skill_registry est sauté. Utile pour contenu sensible, tests ponctuels ou pour ne pas influencer la prochaine consolidation.",
        "de": "Wenn aktiviert, liest dieser Lauf Memory/Konnektoren wie üblich, schreibt aber nichts zurück: persönlicher Speicher auf read_only, Skill-Registry-Usage-Log übersprungen. Für sensible Inhalte, Einzeltests oder wenn die nächste Konsolidierung nicht beeinflusst werden soll.",
        "pt-BR": "Quando ligado, esta execução lê memória/conectores normalmente mas não grava: memória pessoal em read_only e o log de uso do skill_registry é pulado. Útil para conteúdo sensível, testes pontuais ou para não afetar a próxima consolidation.",
    },
    "run.intro": {
        "en": "**Skill** = one-shot domain question. **Agent** = goal-driven, decides what to do.",
        "ja": "**スキル** = ドメイン単発質問。**エージェント** = ゴールから自動判断。",
        "zh-CN": "**技能** = 单领域问答。**代理** = 目标驱动,自主决定。",
        "ko": "**스킬** = 단발 질문. **에이전트** = 목표 주도, 자율 결정.",
        "es": "**Skill** = pregunta única de dominio. **Agent** = guiado por objetivo.",
        "fr": "**Skill** = question ponctuelle. **Agent** = guidé par objectif.",
        "de": "**Skill** = Einzelfrage. **Agent** = zielgetrieben.",
        "pt-BR": "**Skill** = pergunta única. **Agent** = guiado por objetivo.",
    },
    "run.tab.workflow": {
        "en": "📋 Pre-built workflow",
        "ja": "📋 定型ワークフロー",
        "zh-CN": "📋 预建工作流",
        "ko": "📋 사전 정의 워크플로",
        "es": "📋 Workflow pre-construido",
        "fr": "📋 Workflow pré-construit",
        "de": "📋 Vordefinierter Workflow",
        "pt-BR": "📋 Workflow pré-construído",
    },
    "run.tab.skill": {
        "en": "🛠 Single skill",
        "ja": "🛠 単発スキル",
        "zh-CN": "🛠 单一技能",
        "ko": "🛠 단일 스킬",
        "es": "🛠 Habilidad única",
        "fr": "🛠 Compétence unique",
        "de": "🛠 Einzel-Skill",
        "pt-BR": "🛠 Habilidade única",
    },
    "run.tab.agent": {
        "en": "🤖 Autonomous agent",
        "ja": "🤖 自律エージェント",
        "zh-CN": "🤖 自主代理",
        "ko": "🤖 자율 에이전트",
        "es": "🤖 Agente autónomo",
        "fr": "🤖 Agent autonome",
        "de": "🤖 Autonomer Agent",
        "pt-BR": "🤖 Agente autônomo",
    },
    "run.workflow.what": {
        "en": (
            "**What this is**: a *fixed sequence* of multiple agents that runs end-to-end. "
            "The 3 built-in workflows:\n\n"
            "- **sales-agent** — customer research → pain hypotheses → FAQ → proposal draft\n"
            "- **logic-checker** — structure check → contradiction check → readability review\n"
            "- **rag-optimizer** — query rewrite → retrieval → relevance eval → hallucination check loop\n\n"
            "**Pick this when** you have a *recurring procedure* that should always run the same way."
        ),
        "ja": (
            "**これは何**: 複数エージェントが **決まった手順** で連続実行される定型パイプライン。"
            "標準で 3 種類:\n\n"
            "- **sales-agent** — 顧客調査 → 課題仮説 → FAQ → 提案書ドラフト\n"
            "- **logic-checker** — 構造チェック → 矛盾チェック → 読みやすさレビュー\n"
            "- **rag-optimizer** — クエリ書換え → 検索 → 関連度評価 → ハルシネーション検証ループ\n\n"
            "**使う場面**: 毎回同じ手順を踏みたい **定型業務** がある時。"
        ),
        "zh-CN": (
            "**是什么**: 多个代理按 *固定顺序* 端到端运行。内置 3 种:\n\n"
            "- **sales-agent** — 客户调研 → 痛点假设 → FAQ → 提案草稿\n"
            "- **logic-checker** — 结构检查 → 矛盾检查 → 可读性审查\n"
            "- **rag-optimizer** — 查询改写 → 检索 → 相关度评估 → 幻觉检查循环\n\n"
            "**何时使用**: 有 *重复性流程* 且每次都应以相同方式运行时。"
        ),
        "ko": (
            "**무엇**: 여러 에이전트가 *고정된 순서* 로 끝까지 실행되는 파이프라인. 기본 3 종:\n\n"
            "- **sales-agent** — 고객 조사 → 페인포인트 가설 → FAQ → 제안서 초안\n"
            "- **logic-checker** — 구조 검토 → 모순 검토 → 가독성 리뷰\n"
            "- **rag-optimizer** — 쿼리 재작성 → 검색 → 관련도 평가 → 환각 검사 루프\n\n"
            "**언제**: 매번 같은 절차로 진행해야 하는 *반복 업무* 가 있을 때."
        ),
        "es": (
            "**Qué es**: una *secuencia fija* de varios agentes que se ejecuta de extremo a extremo. "
            "3 workflows integrados:\n\n"
            "- **sales-agent** — investigación → hipótesis → FAQ → borrador\n"
            "- **logic-checker** — estructura → contradicción → legibilidad\n"
            "- **rag-optimizer** — reescritura → recuperación → relevancia → bucle anti-alucinación\n\n"
            "**Cuándo**: tienes un procedimiento *recurrente* que siempre debe ejecutarse igual."
        ),
        "fr": (
            "**Qu'est-ce**: une *séquence fixe* de plusieurs agents qui s'exécute de bout en bout. "
            "3 workflows intégrés :\n\n"
            "- **sales-agent** — recherche → hypothèses → FAQ → brouillon\n"
            "- **logic-checker** — structure → contradiction → lisibilité\n"
            "- **rag-optimizer** — réécriture → récupération → pertinence → boucle anti-hallucination\n\n"
            "**Quand** : vous avez une procédure *récurrente* qui doit toujours s'exécuter de la même façon."
        ),
        "de": (
            "**Was ist es**: eine *feste Sequenz* mehrerer Agenten, die end-to-end läuft. "
            "3 eingebaute Workflows:\n\n"
            "- **sales-agent** — Recherche → Hypothesen → FAQ → Entwurf\n"
            "- **logic-checker** — Struktur → Widerspruch → Lesbarkeit\n"
            "- **rag-optimizer** — Query-Rewrite → Retrieval → Relevanz → Halluzinations-Loop\n\n"
            "**Wann**: für *wiederkehrende* Abläufe, die immer gleich laufen sollen."
        ),
        "pt-BR": (
            "**O que é**: uma *sequência fixa* de vários agentes que roda end-to-end. "
            "3 workflows integrados:\n\n"
            "- **sales-agent** — pesquisa → hipóteses → FAQ → rascunho\n"
            "- **logic-checker** — estrutura → contradição → legibilidade\n"
            "- **rag-optimizer** — reescrita → recuperação → relevância → loop anti-alucinação\n\n"
            "**Quando**: você tem um procedimento *recorrente* que sempre deve rodar do mesmo jeito."
        ),
    },
    "run.skill.what": {
        "en": "Single-call domain skill (investment / sales / design / purchasing / patent / legal).",
        "ja": "ドメイン単発スキル (投資 / 営業 / 設計 / 購買 / 特許 / 法務)。",
        "zh-CN": "单次领域技能(投资/销售/设计/采购/专利/法务)。",
        "ko": "단발 도메인 스킬 (투자/영업/설계/구매/특허/법무).",
        "es": "Habilidad de dominio de una sola llamada.",
        "fr": "Compétence de domaine en un seul appel.",
        "de": "Einzelaufruf-Domain-Skill.",
        "pt-BR": "Habilidade de domínio em chamada única.",
    },
    "run.agent.what": {
        "en": "Goal in, agent picks tools (memory / connectors / skills) and iterates until done.",
        "ja": "ゴールを伝えると、ツール (メモリ / コネクタ / スキル) を自動選択して反復実行。",
        "zh-CN": "给目标,代理自主选择工具(记忆/连接器/技能)反复执行。",
        "ko": "목표만 주면 도구 (메모리/커넥터/스킬) 를 자동 선택해 반복.",
        "es": "Das un objetivo, el agente elige herramientas e itera.",
        "fr": "Un objectif, l'agent choisit les outils et itère.",
        "de": "Ziel rein, Agent wählt Tools und iteriert.",
        "pt-BR": "Dê um objetivo, o agente escolhe ferramentas e itera.",
    },
    "run.agent.placeholder": {
        "en": "Ask the agent anything — attach images via 📎, pick scopes in the sidebar for context.",
        "ja": "エージェントに何でも聞いてください — 📎で画像添付、サイドバーで参照データ範囲を指定。",
        "zh-CN": "向代理提问 — 通过 📎 附加图片，侧边栏选择数据范围。",
        "ko": "에이전트에게 자유롭게 질문하세요 — 📎로 이미지 첨부, 사이드바에서 데이터 범위 선택.",
        "es": "Pregunta lo que quieras — adjunta imágenes con 📎 y elige scopes en la sidebar.",
        "fr": "Posez n'importe quelle question — joignez des images via 📎, scopes dans la sidebar.",
        "de": "Frag den Agenten alles — Bilder via 📎 anhängen, Scopes in der Sidebar.",
        "pt-BR": "Pergunte qualquer coisa — anexe imagens via 📎 e escolha escopos na sidebar.",
    },
    "run.agent.empty_hint": {
        "en": "Type below to start the conversation. Past turns will appear here and scroll independently from the input box.",
        "ja": "下の入力欄から会話を始めてください。過去のやりとりはこの領域に表示され、入力欄から独立してスクロールします。",
        "zh-CN": "请在下方输入开始对话。历史会显示在此区域并独立滚动。",
        "ko": "아래 입력창에서 대화를 시작하세요. 이전 대화는 이 영역에 표시되며 입력창과 독립적으로 스크롤됩니다.",
        "es": "Escribe abajo para empezar. Los turnos anteriores aparecen aquí y se desplazan independientemente del campo de entrada.",
        "fr": "Tapez ci-dessous pour commencer. Les tours précédents apparaissent ici et défilent indépendamment du champ de saisie.",
        "de": "Unten tippen, um die Konversation zu starten. Frühere Runden erscheinen hier und scrollen unabhängig vom Eingabefeld.",
        "pt-BR": "Digite abaixo para começar. Os turnos anteriores aparecem aqui e rolam independentemente da caixa de entrada.",
    },
    "run.agent.thinking": {
        "en": "Agent thinking…",
        "ja": "エージェント思考中…",
        "zh-CN": "代理正在思考…",
        "ko": "에이전트 사고 중…",
        "es": "El agente está pensando…",
        "fr": "L'agent réfléchit…",
        "de": "Agent denkt nach…",
        "pt-BR": "Agente pensando…",
    },
    "run.agent.trace": {
        "en": "🔧 Tool-use trace",
        "ja": "🔧 ツール使用トレース",
        "zh-CN": "🔧 工具使用追踪",
        "ko": "🔧 도구 사용 트레이스",
        "es": "🔧 Traza de uso de herramientas",
        "fr": "🔧 Trace d'utilisation d'outils",
        "de": "🔧 Tool-Use-Trace",
        "pt-BR": "🔧 Traço de uso de ferramentas",
    },
    "run.agent.clear": {
        "en": "🗑 Clear conversation",
        "ja": "🗑 会話をクリア",
        "zh-CN": "🗑 清空对话",
        "ko": "🗑 대화 지우기",
        "es": "🗑 Limpiar conversación",
        "fr": "🗑 Effacer la conversation",
        "de": "🗑 Konversation löschen",
        "pt-BR": "🗑 Limpar conversa",
    },
    "run.threads.h": {
        "en": "💬 Conversations",
        "ja": "💬 会話履歴",
        "zh-CN": "💬 会话",
        "ko": "💬 대화",
        "es": "💬 Conversaciones",
        "fr": "💬 Conversations",
        "de": "💬 Konversationen",
        "pt-BR": "💬 Conversas",
    },
    "run.threads.new": {
        "en": "+ New conversation",
        "ja": "+ 新しい会話",
        "zh-CN": "+ 新建会话",
        "ko": "+ 새 대화",
        "es": "+ Nueva conversación",
        "fr": "+ Nouvelle conversation",
        "de": "+ Neue Konversation",
        "pt-BR": "+ Nova conversa",
    },
    "run.threads.empty": {
        "en": "No past conversations yet.",
        "ja": "過去の会話はまだありません。",
        "zh-CN": "暂无历史会话。",
        "ko": "아직 대화 기록이 없습니다.",
        "es": "Aún no hay conversaciones.",
        "fr": "Pas encore de conversations.",
        "de": "Noch keine Konversationen.",
        "pt-BR": "Nenhuma conversa ainda.",
    },
    "run.threads.picker": {
        "en": "Resume",
        "ja": "再開",
        "zh-CN": "继续",
        "ko": "이어가기",
        "es": "Reanudar",
        "fr": "Reprendre",
        "de": "Fortsetzen",
        "pt-BR": "Retomar",
    },
    "run.threads.rename_label": {
        "en": "Rename conversation",
        "ja": "会話名を変更",
        "zh-CN": "重命名会话",
        "ko": "대화 이름 변경",
        "es": "Renombrar conversación",
        "fr": "Renommer la conversation",
        "de": "Konversation umbenennen",
        "pt-BR": "Renomear conversa",
    },
    "run.threads.rename_btn": {
        "en": "Rename",
        "ja": "変更",
        "zh-CN": "重命名",
        "ko": "변경",
        "es": "Renombrar",
        "fr": "Renommer",
        "de": "Umbenennen",
        "pt-BR": "Renomear",
    },
    "run.threads.delete_btn": {
        "en": "🗑 Delete this conversation",
        "ja": "🗑 この会話を削除",
        "zh-CN": "🗑 删除此会话",
        "ko": "🗑 이 대화 삭제",
        "es": "🗑 Eliminar esta conversación",
        "fr": "🗑 Supprimer cette conversation",
        "de": "🗑 Diese Konversation löschen",
        "pt-BR": "🗑 Excluir esta conversa",
    },
    "run.threads.delete_confirm": {
        "en": "Delete permanently? Click again to confirm.",
        "ja": "完全に削除しますか？ もう一度クリックで確定。",
        "zh-CN": "确认永久删除？再次点击确认。",
        "ko": "영구 삭제할까요? 다시 클릭하여 확인.",
        "es": "¿Eliminar permanentemente? Haz clic otra vez para confirmar.",
        "fr": "Supprimer définitivement ? Cliquez à nouveau pour confirmer.",
        "de": "Endgültig löschen? Erneut klicken zum Bestätigen.",
        "pt-BR": "Excluir permanentemente? Clique novamente para confirmar.",
    },
    "run.threads.ephemeral_note": {
        "en": "Ephemeral mode is on — this conversation will not be saved.",
        "ja": "エフェメラルモードが有効です — この会話は保存されません。",
        "zh-CN": "临时模式已启用 — 此会话不会被保存。",
        "ko": "에페메럴 모드 활성화 — 이 대화는 저장되지 않습니다。",
        "es": "Modo efímero activo — esta conversación no se guardará.",
        "fr": "Mode éphémère activé — cette conversation ne sera pas sauvegardée.",
        "de": "Ephemerer Modus aktiv — diese Konversation wird nicht gespeichert.",
        "pt-BR": "Modo efêmero ativo — esta conversa não será salva.",
    },
    "run.threads.active": {
        "en": "Active conversation",
        "ja": "アクティブな会話",
        "zh-CN": "当前会话",
        "ko": "현재 대화",
        "es": "Conversación activa",
        "fr": "Conversation active",
        "de": "Aktive Konversation",
        "pt-BR": "Conversa ativa",
    },
    "admin.consolidate.subtab": {
        "en": "🌙 Consolidate",
        "ja": "🌙 統合",
        "zh-CN": "🌙 整合",
        "ko": "🌙 통합",
        "es": "🌙 Consolidar",
        "fr": "🌙 Consolider",
        "de": "🌙 Konsolidieren",
        "pt-BR": "🌙 Consolidar",
    },
    "run.agent.coming_soon": {
        "en": "🚧 Autonomous-agent UI is coming. For now, run from the CLI:",
        "ja": "🚧 自律エージェントの UI は準備中。現状は CLI から実行してください:",
        "zh-CN": "🚧 自主代理 UI 准备中。目前请通过 CLI 运行:",
        "ko": "🚧 자율 에이전트 UI 는 준비 중. 현재는 CLI 에서 실행하세요:",
        "es": "🚧 La UI del agente autónomo está en camino. Por ahora, ejecuta desde la CLI:",
        "fr": "🚧 L'UI agent autonome arrive bientôt. Pour l'instant, lancez depuis la CLI :",
        "de": "🚧 Autonomous-Agent-UI ist im Aufbau. Derzeit über CLI starten:",
        "pt-BR": "🚧 A UI do agente autônomo está a caminho. Por enquanto, execute via CLI:",
    },
    # ===== Data scope picker (in-workspace) =================================
    "scope.section_h": {
        "en": "Context",
        "ja": "参照データ",
        "zh-CN": "参考数据",
        "ko": "참조 데이터",
        "es": "Contexto",
        "fr": "Contexte",
        "de": "Kontext",
        "pt-BR": "Contexto",
    },
    "scope.section_intro": {
        "en": "Pick which folders / memory layers to feed into this run as additional context. Manage folders under 📁 Data.",
        "ja": "今回の実行に渡す追加コンテキストを選択。フォルダの管理は 📁 データ から。",
        "zh-CN": "选择本次运行作为附加上下文的文件夹/记忆层。文件夹管理在 📁 数据。",
        "ko": "이번 실행에 추가 컨텍스트로 사용할 폴더 / 메모리 레이어를 선택. 폴더 관리는 📁 데이터.",
        "es": "Elige qué carpetas / capas de memoria alimentar como contexto extra. Gestiona carpetas en 📁 Datos.",
        "fr": "Choisissez les dossiers / couches mémoire à injecter comme contexte additionnel. Gestion sous 📁 Données.",
        "de": "Wähle Ordner / Speicherschichten als zusätzlichen Kontext. Ordner verwaltest du unter 📁 Daten.",
        "pt-BR": "Escolha quais pastas / camadas de memória usar como contexto extra. Gerencie pastas em 📁 Dados.",
    },
    "scope.builtin_h": {
        "en": "Built-in",
        "ja": "標準",
        "zh-CN": "内置",
        "ko": "기본",
        "es": "Integrado",
        "fr": "Intégré",
        "de": "Integriert",
        "pt-BR": "Integrado",
    },
    "scope.custom_h": {
        "en": "Custom folders",
        "ja": "カスタムフォルダ",
        "zh-CN": "自定义文件夹",
        "ko": "커스텀 폴더",
        "es": "Carpetas personalizadas",
        "fr": "Dossiers personnalisés",
        "de": "Eigene Ordner",
        "pt-BR": "Pastas personalizadas",
    },
    "scope.empty_hint": {
        "en": "(none yet — create one in 📁 Data)",
        "ja": "(未作成 — 📁 データ で作成)",
        "zh-CN": "(尚无 — 在 📁 数据 中创建)",
        "ko": "(없음 — 📁 데이터 에서 생성)",
        "es": "(aún ninguna — crea en 📁 Datos)",
        "fr": "(aucun — créez dans 📁 Données)",
        "de": "(noch keine — in 📁 Daten anlegen)",
        "pt-BR": "(nenhuma — crie em 📁 Dados)",
    },
    # ===== Admin: language picker (moved from sidebar) ======================
    "admin.settings.language_h": {
        "en": "Language",
        "ja": "言語",
        "zh-CN": "语言",
        "ko": "언어",
        "es": "Idioma",
        "fr": "Langue",
        "de": "Sprache",
        "pt-BR": "Idioma",
    },
    "admin.settings.language_intro": {
        "en": "Default is auto-detected from your browser/OS. Override here if you prefer a different language.",
        "ja": "既定はブラウザ/OS から自動検出。別言語を使いたい場合のみ切替えてください。",
        "zh-CN": "默认从浏览器/OS 自动检测。如需其他语言可在此切换。",
        "ko": "기본값은 브라우저/OS 에서 자동 감지. 다른 언어를 원하면 여기서 전환.",
        "es": "Por defecto se detecta del navegador/OS. Cambia aquí si prefieres otro idioma.",
        "fr": "Par défaut détecté depuis le navigateur/OS. Changez ici si vous préférez une autre langue.",
        "de": "Standard wird vom Browser/OS automatisch erkannt. Hier umstellen, wenn nötig.",
        "pt-BR": "Padrão detectado do navegador/OS. Troque aqui se preferir outro idioma.",
    },
    "admin.settings.language_label": {
        "en": "Display language",
        "ja": "表示言語",
        "zh-CN": "显示语言",
        "ko": "표시 언어",
        "es": "Idioma de la interfaz",
        "fr": "Langue d'affichage",
        "de": "Anzeigesprache",
        "pt-BR": "Idioma de exibição",
    },
    "mode.data": {
        "en": "📁 Data folders",
        "ja": "📁 データフォルダ",
        "zh-CN": "📁 数据文件夹",
        "ko": "📁 데이터 폴더",
        "es": "📁 Carpetas de datos",
        "fr": "📁 Dossiers de données",
        "de": "📁 Datenordner",
        "pt-BR": "📁 Pastas de dados",
    },
    # ===== Data scope sidebar selector ======================================
    "sidebar.scope.h": {
        "en": "Context",
        "ja": "参照データ",
        "zh-CN": "参考数据",
        "ko": "참조 데이터",
        "es": "Contexto",
        "fr": "Contexte",
        "de": "Kontext",
        "pt-BR": "Contexto",
    },
    "scope.personal_memory": {
        "en": "Personal memory",
        "ja": "個人メモリ",
        "zh-CN": "个人记忆",
        "ko": "개인 메모리",
        "es": "Memoria personal",
        "fr": "Mémoire personnelle",
        "de": "Persönlicher Speicher",
        "pt-BR": "Memória pessoal",
    },
    "scope.org_memory": {
        "en": "Org memory",
        "ja": "組織メモリ",
        "zh-CN": "组织记忆",
        "ko": "조직 메모리",
        "es": "Memoria org",
        "fr": "Mémoire org",
        "de": "Org-Speicher",
        "pt-BR": "Memória org",
    },
    "scope.frozen": {
        "en": "Frozen layer",
        "ja": "凍結層",
        "zh-CN": "冻结层",
        "ko": "동결 레이어",
        "es": "Capa congelada",
        "fr": "Couche figée",
        "de": "Frozen-Layer",
        "pt-BR": "Camada congelada",
    },
    "sidebar.scope.local_h": {
        "en": "Local folders",
        "ja": "ローカルフォルダ",
        "zh-CN": "本地文件夹",
        "ko": "로컬 폴더",
        "es": "Carpetas locales",
        "fr": "Dossiers locaux",
        "de": "Lokale Ordner",
        "pt-BR": "Pastas locais",
    },
    "sidebar.scope.connector_h": {
        "en": "Connector folders",
        "ja": "コネクタフォルダ",
        "zh-CN": "连接器文件夹",
        "ko": "커넥터 폴더",
        "es": "Carpetas de conector",
        "fr": "Dossiers de connecteur",
        "de": "Konnektor-Ordner",
        "pt-BR": "Pastas de conector",
    },
    "sidebar.scope.empty_hint": {
        "en": "No custom folders yet — create one in 📁 Data folders mode.",
        "ja": "カスタムフォルダ未作成 — 📁 データフォルダ モードで作成してください。",
        "zh-CN": "尚无自定义文件夹 — 在 📁 数据文件夹 模式中创建。",
        "ko": "커스텀 폴더 없음 — 📁 데이터 폴더 모드에서 만드세요.",
        "es": "Sin carpetas personalizadas — créalas en el modo 📁 Carpetas de datos.",
        "fr": "Aucun dossier personnalisé — créez-en dans le mode 📁 Dossiers de données.",
        "de": "Noch keine eigenen Ordner — im Modus 📁 Datenordner anlegen.",
        "pt-BR": "Sem pastas personalizadas — crie no modo 📁 Pastas de dados.",
    },
    # ===== Data folder management mode ======================================
    "data.intro": {
        "en": "Local folders (your uploads) and Connector folders (Box / SharePoint / Notion paths). Pick scopes in the sidebar to feed them into runs.",
        "ja": "ローカル (アップロード) と コネクタ (Box / SharePoint / Notion 等のパス) の 2 種類。サイドバーで選択して実行に反映。",
        "zh-CN": "本地(上传)与连接器(Box / SharePoint / Notion 路径)两类。在侧边栏选择以注入到运行中。",
        "ko": "로컬 (업로드) 과 커넥터 (Box / SharePoint / Notion 경로) 두 종류. 사이드바에서 선택해 실행에 반영.",
        "es": "Carpetas locales (subidas) y de conector (rutas Box / SharePoint / Notion). Selecciona en la barra lateral.",
        "fr": "Dossiers locaux (téléversements) et de connecteur (chemins Box / SharePoint / Notion). Sélectionnez dans la sidebar.",
        "de": "Lokale Ordner (Uploads) und Konnektor-Ordner (Box / SharePoint / Notion). In der Sidebar auswählen.",
        "pt-BR": "Pastas locais (uploads) e de conector (Box / SharePoint / Notion). Selecione na sidebar.",
    },
    "data.tab.local": {
        "en": "📁 Local folders",
        "ja": "📁 ローカルフォルダ",
        "zh-CN": "📁 本地文件夹",
        "ko": "📁 로컬 폴더",
        "es": "📁 Carpetas locales",
        "fr": "📁 Dossiers locaux",
        "de": "📁 Lokale Ordner",
        "pt-BR": "📁 Pastas locais",
    },
    "data.tab.connector": {
        "en": "🔌 Connector folders",
        "ja": "🔌 コネクタフォルダ",
        "zh-CN": "🔌 连接器文件夹",
        "ko": "🔌 커넥터 폴더",
        "es": "🔌 Carpetas de conector",
        "fr": "🔌 Dossiers de connecteur",
        "de": "🔌 Konnektor-Ordner",
        "pt-BR": "🔌 Pastas de conector",
    },
    "data.tab.browse": {
        "en": "🔍 Browse",
        "ja": "🔍 ブラウズ",
        "zh-CN": "🔍 浏览",
        "ko": "🔍 탐색",
        "es": "🔍 Explorar",
        "fr": "🔍 Parcourir",
        "de": "🔍 Durchsuchen",
        "pt-BR": "🔍 Explorar",
    },
    "data.local.intro": {
        "en": "Upload files into a named folder. Folders persist across sessions.",
        "ja": "名前付きフォルダにファイルをアップロードします。セッション越えに保存されます。",
        "zh-CN": "将文件上传到命名文件夹中,跨会话保留。",
        "ko": "이름이 있는 폴더에 파일을 업로드합니다. 세션 간 유지됩니다.",
        "es": "Sube archivos a una carpeta con nombre. Persisten entre sesiones.",
        "fr": "Téléversez des fichiers dans un dossier nommé. Conservés entre sessions.",
        "de": "Lade Dateien in einen benannten Ordner. Bleiben über Sitzungen hinweg erhalten.",
        "pt-BR": "Envie arquivos para uma pasta nomeada. Persistem entre sessões.",
    },
    "data.local.empty": {
        "en": "No local folders yet. Create one below.",
        "ja": "ローカルフォルダ未作成。下から作成してください。",
        "zh-CN": "尚无本地文件夹。在下方创建。",
        "ko": "로컬 폴더 없음. 아래에서 만드세요.",
        "es": "Sin carpetas locales. Crea una abajo.",
        "fr": "Aucun dossier local. Créez-en un ci-dessous.",
        "de": "Noch keine lokalen Ordner. Unten anlegen.",
        "pt-BR": "Sem pastas locais. Crie uma abaixo.",
    },
    "data.local.add_files": {
        "en": "Add more files (drop or browse)",
        "ja": "ファイルを追加 (ドロップまたは選択)",
        "zh-CN": "追加文件 (拖放或浏览)",
        "ko": "파일 추가 (드롭 또는 선택)",
        "es": "Agregar más archivos (soltar o examinar)",
        "fr": "Ajouter d'autres fichiers (déposer ou parcourir)",
        "de": "Weitere Dateien hinzufügen (Drop oder Auswahl)",
        "pt-BR": "Adicionar mais arquivos (soltar ou navegar)",
    },
    "data.local.save_uploads": {
        "en": "💾 Save uploads",
        "ja": "💾 アップロード保存",
        "zh-CN": "💾 保存上传",
        "ko": "💾 업로드 저장",
        "es": "💾 Guardar subidas",
        "fr": "💾 Enregistrer",
        "de": "💾 Uploads speichern",
        "pt-BR": "💾 Salvar uploads",
    },
    "data.local.no_files_to_save": {
        "en": "No files selected.",
        "ja": "ファイルが選択されていません。",
        "zh-CN": "未选择文件。",
        "ko": "선택된 파일이 없습니다.",
        "es": "No hay archivos seleccionados.",
        "fr": "Aucun fichier sélectionné.",
        "de": "Keine Dateien ausgewählt.",
        "pt-BR": "Nenhum arquivo selecionado.",
    },
    "data.local.saved": {
        "en": "✅ Saved {n} file(s)",
        "ja": "✅ {n} 件のファイルを保存しました",
        "zh-CN": "✅ 已保存 {n} 个文件",
        "ko": "✅ {n} 개 파일 저장됨",
        "es": "✅ Se guardaron {n} archivo(s)",
        "fr": "✅ {n} fichier(s) enregistré(s)",
        "de": "✅ {n} Datei(en) gespeichert",
        "pt-BR": "✅ {n} arquivo(s) salvo(s)",
    },
    "data.local.delete_folder": {
        "en": "🗑 Delete folder",
        "ja": "🗑 フォルダ削除",
        "zh-CN": "🗑 删除文件夹",
        "ko": "🗑 폴더 삭제",
        "es": "🗑 Eliminar carpeta",
        "fr": "🗑 Supprimer le dossier",
        "de": "🗑 Ordner löschen",
        "pt-BR": "🗑 Excluir pasta",
    },
    "data.local.share_h": {
        "en": "🤝 Share with users",
        "ja": "🤝 ユーザと共有",
        "zh-CN": "🤝 与用户共享",
        "ko": "🤝 사용자와 공유",
        "es": "🤝 Compartir con usuarios",
        "fr": "🤝 Partager avec des utilisateurs",
        "de": "🤝 Mit Nutzern teilen",
        "pt-BR": "🤝 Compartilhar com usuários",
    },
    "data.local.share_intro": {
        "en": "Selected users get **read-only** access — they can pick this folder as context but not upload, delete, or re-share. Sub-folders are NOT auto-shared; share each one explicitly if needed.",
        "ja": "選択したユーザに **読み取り専用** アクセスを付与 — Context として選択可、アップロード/削除/再共有は不可。サブフォルダは自動共有されないので、必要なら個別に共有してください。",
        "zh-CN": "所选用户获得 **只读** 访问 — 可作为 Context 选择，但不能上传/删除/再共享。子文件夹不会自动共享，需逐个设置。",
        "ko": "선택한 사용자에게 **읽기 전용** 권한 부여 — Context 로 선택 가능하지만 업로드/삭제/재공유 불가. 하위 폴더는 자동 공유되지 않으므로 필요 시 개별 공유.",
        "es": "Los usuarios seleccionados obtienen acceso de **solo lectura** — pueden elegir esta carpeta como contexto pero no subir, borrar ni re-compartir. Las subcarpetas NO se comparten automáticamente; compártelas por separado.",
        "fr": "Les utilisateurs sélectionnés ont un accès **lecture seule** — ils peuvent choisir ce dossier comme contexte mais pas téléverser, supprimer, ni re-partager. Les sous-dossiers ne sont pas partagés automatiquement.",
        "de": "Ausgewählte Nutzer erhalten **schreibgeschützten** Zugriff — sie können den Ordner als Kontext auswählen, aber nicht hochladen/löschen/weiterteilen. Unterordner werden NICHT automatisch geteilt.",
        "pt-BR": "Os usuários selecionados obtêm acesso **somente leitura** — podem escolher esta pasta como contexto mas não fazer upload, excluir ou re-compartilhar. Subpastas NÃO são compartilhadas automaticamente.",
    },
    "data.local.share_select_label": {
        "en": "Users to share with",
        "ja": "共有相手のユーザ",
        "zh-CN": "共享对象用户",
        "ko": "공유 대상 사용자",
        "es": "Usuarios con los que compartir",
        "fr": "Utilisateurs avec qui partager",
        "de": "Nutzer zum Teilen",
        "pt-BR": "Usuários para compartilhar",
    },
    "data.local.share_select_help": {
        "en": "Pick from registered users. The list comes from Admin → Users.",
        "ja": "登録済ユーザから選択。リストは Admin → Users から取得。",
        "zh-CN": "从已注册用户中选择。列表来自 Admin → Users。",
        "ko": "등록된 사용자 중 선택. 목록은 Admin → Users 에서 가져옴.",
        "es": "Elige entre usuarios registrados. La lista viene de Admin → Users.",
        "fr": "Choisissez parmi les utilisateurs enregistrés. La liste vient d'Admin → Users.",
        "de": "Wähle aus registrierten Nutzern. Die Liste stammt aus Admin → Users.",
        "pt-BR": "Escolha entre usuários registrados. A lista vem de Admin → Users.",
    },
    "data.local.share_addhoc_label": {
        "en": "+ Add user_id manually",
        "ja": "+ 任意のユーザ ID を直接追加",
        "zh-CN": "+ 手动添加 user_id",
        "ko": "+ user_id 직접 추가",
        "es": "+ Añadir user_id manualmente",
        "fr": "+ Ajouter un user_id manuellement",
        "de": "+ user_id manuell hinzufügen",
        "pt-BR": "+ Adicionar user_id manualmente",
    },
    "data.local.share_addhoc_placeholder": {
        "en": "alice@corp.com",
        "ja": "alice@corp.com",
        "zh-CN": "alice@corp.com",
        "ko": "alice@corp.com",
        "es": "alice@corp.com",
        "fr": "alice@corp.com",
        "de": "alice@corp.com",
        "pt-BR": "alice@corp.com",
    },
    "data.local.share_apply": {
        "en": "Save share list",
        "ja": "共有設定を保存",
        "zh-CN": "保存共享设置",
        "ko": "공유 설정 저장",
        "es": "Guardar lista de compartir",
        "fr": "Enregistrer le partage",
        "de": "Freigabeliste speichern",
        "pt-BR": "Salvar lista de compartilhamento",
    },
    "data.local.share_clear": {
        "en": "🚫 Stop sharing with everyone",
        "ja": "🚫 全員との共有を解除",
        "zh-CN": "🚫 取消与所有人的共享",
        "ko": "🚫 모든 사용자와의 공유 해제",
        "es": "🚫 Dejar de compartir con todos",
        "fr": "🚫 Arrêter le partage avec tous",
        "de": "🚫 Freigabe für alle aufheben",
        "pt-BR": "🚫 Parar de compartilhar com todos",
    },
    "data.local.share_saved": {
        "en": "✅ Share list updated.",
        "ja": "✅ 共有設定を更新しました。",
        "zh-CN": "✅ 共享设置已更新。",
        "ko": "✅ 공유 설정을 업데이트했습니다.",
        "es": "✅ Lista de compartir actualizada.",
        "fr": "✅ Liste de partage mise à jour.",
        "de": "✅ Freigabeliste aktualisiert.",
        "pt-BR": "✅ Lista de compartilhamento atualizada.",
    },
    "data.local.share_cleared": {
        "en": "🚫 Share list cleared. Folder is now private.",
        "ja": "🚫 共有設定を解除。フォルダは非公開になりました。",
        "zh-CN": "🚫 共享设置已清空。文件夹现在仅私有。",
        "ko": "🚫 공유 설정을 해제했습니다. 폴더는 비공개입니다.",
        "es": "🚫 Lista limpia. Carpeta ahora privada.",
        "fr": "🚫 Liste vidée. Dossier désormais privé.",
        "de": "🚫 Freigabeliste geleert. Ordner ist jetzt privat.",
        "pt-BR": "🚫 Lista limpa. Pasta agora privada.",
    },
    "data.local.share_no_changes": {
        "en": "No changes — share list is already that way.",
        "ja": "変更なし — 共有設定は既にこの状態です。",
        "zh-CN": "未变更 — 共享设置已是该状态。",
        "ko": "변경 없음 — 공유 설정이 이미 동일합니다.",
        "es": "Sin cambios — la lista ya está así.",
        "fr": "Aucun changement — la liste est déjà ainsi.",
        "de": "Keine Änderungen — die Liste ist bereits so.",
        "pt-BR": "Sem mudanças — a lista já está assim.",
    },
    "data.local.shared_by": {
        "en": "shared by {owner}",
        "ja": "{owner} から共有",
        "zh-CN": "由 {owner} 共享",
        "ko": "{owner} 가 공유",
        "es": "compartido por {owner}",
        "fr": "partagé par {owner}",
        "de": "geteilt von {owner}",
        "pt-BR": "compartilhado por {owner}",
    },
    "data.local.shared_in_notice": {
        "en": "ℹ️ This folder is shared with you by **{owner}** — read-only. You can pick it as context for runs, but only the owner can upload, delete, or change sharing.",
        "ja": "ℹ️ このフォルダは **{owner}** から共有されています — 読み取り専用。Run の Context として選択できますが、アップロード/削除/共有変更はオーナーのみ可能。",
        "zh-CN": "ℹ️ 此文件夹由 **{owner}** 共享给你 — 只读。可作为 Run 的 Context 选择，但上传/删除/修改共享仅限拥有者。",
        "ko": "ℹ️ 이 폴더는 **{owner}** 가 공유한 것입니다 — 읽기 전용. Run 의 Context 로 선택 가능하지만 업로드/삭제/공유 변경은 소유자만.",
        "es": "ℹ️ Esta carpeta te la comparte **{owner}** — solo lectura. Puedes usarla como contexto, pero solo el propietario puede subir, borrar o cambiar el uso compartido.",
        "fr": "ℹ️ Ce dossier vous est partagé par **{owner}** — lecture seule. Vous pouvez l'utiliser comme contexte, mais seul le propriétaire peut téléverser, supprimer ou modifier le partage.",
        "de": "ℹ️ Dieser Ordner wird von **{owner}** mit dir geteilt — schreibgeschützt. Du kannst ihn als Kontext nutzen; Hochladen/Löschen/Freigabeänderungen nur durch den Eigentümer.",
        "pt-BR": "ℹ️ Esta pasta é compartilhada com você por **{owner}** — somente leitura. Você pode usá-la como contexto; upload/exclusão/mudança de compartilhamento só pelo proprietário.",
    },
    "data.local.folder_deleted": {
        "en": "🗑 Folder '{name}' deleted",
        "ja": "🗑 フォルダ '{name}' を削除しました",
        "zh-CN": "🗑 已删除文件夹「{name}」",
        "ko": "🗑 '{name}' 폴더를 삭제했습니다",
        "es": "🗑 Carpeta '{name}' eliminada",
        "fr": "🗑 Dossier « {name} » supprimé",
        "de": "🗑 Ordner '{name}' gelöscht",
        "pt-BR": "🗑 Pasta '{name}' excluída",
    },
    "data.local.create_h": {
        "en": "Create a new local folder",
        "ja": "新規ローカルフォルダ作成",
        "zh-CN": "创建新的本地文件夹",
        "ko": "새 로컬 폴더 만들기",
        "es": "Crear nueva carpeta local",
        "fr": "Créer un nouveau dossier local",
        "de": "Neuen lokalen Ordner anlegen",
        "pt-BR": "Criar nova pasta local",
    },
    "data.local.create_name": {
        "en": "Folder name",
        "ja": "フォルダ名",
        "zh-CN": "文件夹名称",
        "ko": "폴더 이름",
        "es": "Nombre de la carpeta",
        "fr": "Nom du dossier",
        "de": "Ordnername",
        "pt-BR": "Nome da pasta",
    },
    "data.local.create_desc": {
        "en": "Description",
        "ja": "説明",
        "zh-CN": "描述",
        "ko": "설명",
        "es": "Descripción",
        "fr": "Description",
        "de": "Beschreibung",
        "pt-BR": "Descrição",
    },
    "data.local.create_files": {
        "en": "Initial files",
        "ja": "初期ファイル",
        "zh-CN": "初始文件",
        "ko": "초기 파일",
        "es": "Archivos iniciales",
        "fr": "Fichiers initiaux",
        "de": "Anfangsdateien",
        "pt-BR": "Arquivos iniciais",
    },
    "data.local.parent_label": {
        "en": "Parent folder",
        "ja": "親フォルダ",
        "zh-CN": "父文件夹",
        "ko": "상위 폴더",
        "es": "Carpeta padre",
        "fr": "Dossier parent",
        "de": "Übergeordneter Ordner",
        "pt-BR": "Pasta pai",
    },
    "data.local.parent_root": {
        "en": "(root — top-level folder)",
        "ja": "(ルート — 最上位)",
        "zh-CN": "(根 — 顶层)",
        "ko": "(루트 — 최상위)",
        "es": "(raíz — nivel superior)",
        "fr": "(racine — niveau supérieur)",
        "de": "(Wurzel — oberste Ebene)",
        "pt-BR": "(raiz — nível superior)",
    },
    "data.local.create_btn": {
        "en": "Create folder",
        "ja": "フォルダを作成",
        "zh-CN": "创建文件夹",
        "ko": "폴더 만들기",
        "es": "Crear carpeta",
        "fr": "Créer le dossier",
        "de": "Ordner anlegen",
        "pt-BR": "Criar pasta",
    },
    "data.local.create_name_required": {
        "en": "Folder name is required.",
        "ja": "フォルダ名は必須です。",
        "zh-CN": "需要文件夹名称。",
        "ko": "폴더 이름이 필요합니다.",
        "es": "Se requiere nombre de carpeta.",
        "fr": "Le nom du dossier est requis.",
        "de": "Ordnername ist erforderlich.",
        "pt-BR": "Nome da pasta é obrigatório.",
    },
    "data.local.created": {
        "en": "✅ Created '{name}'",
        "ja": "✅ '{name}' を作成しました",
        "zh-CN": "✅ 已创建「{name}」",
        "ko": "✅ '{name}' 을(를) 만들었습니다",
        "es": "✅ Se creó '{name}'",
        "fr": "✅ « {name} » créé",
        "de": "✅ '{name}' angelegt",
        "pt-BR": "✅ '{name}' criada",
    },
    "data.connector.intro": {
        "en": "Register an external path (admin must enable the connector first via env vars). Per-user OAuth = native ACL applied per user.",
        "ja": "外部パスを登録 (管理者が事前に env で連携先を有効化)。Per-user OAuth は各ユーザの権限が適用されます。",
        "zh-CN": "注册外部路径(需管理员先通过 env 启用连接器)。Per-user OAuth 各用户按自身权限。",
        "ko": "외부 경로 등록 (관리자가 env 로 커넥터 사전 활성화). Per-user OAuth 는 사용자별 권한 적용.",
        "es": "Registra una ruta externa (el admin habilita el conector vía env). Per-user OAuth = ACL nativa por usuario.",
        "fr": "Enregistrer un chemin externe (l'admin active le connecteur via env). Per-user OAuth = ACL native par utilisateur.",
        "de": "Externen Pfad registrieren (Admin aktiviert den Konnektor via env). Per-user OAuth = ACL je Nutzer.",
        "pt-BR": "Registre um caminho externo (admin habilita o conector via env). Per-user OAuth = ACL por usuário.",
    },
    "data.connector.empty": {
        "en": "No connector folders registered yet. Add one below.",
        "ja": "コネクタフォルダ未登録。下から追加してください。",
        "zh-CN": "尚未注册连接器文件夹。在下方添加。",
        "ko": "등록된 커넥터 폴더 없음. 아래에서 추가하세요.",
        "es": "Sin carpetas de conector registradas. Agrega una abajo.",
        "fr": "Aucun dossier de connecteur enregistré. Ajoutez-en un ci-dessous.",
        "de": "Noch keine Konnektor-Ordner. Unten hinzufügen.",
        "pt-BR": "Sem pastas de conector. Adicione uma abaixo.",
    },
    "data.connector.delete": {
        "en": "🗑 Delete registration",
        "ja": "🗑 登録を削除",
        "zh-CN": "🗑 删除注册",
        "ko": "🗑 등록 삭제",
        "es": "🗑 Eliminar registro",
        "fr": "🗑 Supprimer l'enregistrement",
        "de": "🗑 Registrierung löschen",
        "pt-BR": "🗑 Excluir registro",
    },
    "data.connector.create_h": {
        "en": "Register a new connector folder",
        "ja": "新規コネクタフォルダ登録",
        "zh-CN": "注册新的连接器文件夹",
        "ko": "새 커넥터 폴더 등록",
        "es": "Registrar nueva carpeta de conector",
        "fr": "Enregistrer un nouveau dossier de connecteur",
        "de": "Neuen Konnektor-Ordner registrieren",
        "pt-BR": "Registrar nova pasta de conector",
    },
    "data.connector.create_name": {
        "en": "Display name",
        "ja": "表示名",
        "zh-CN": "显示名称",
        "ko": "표시 이름",
        "es": "Nombre visible",
        "fr": "Nom affiché",
        "de": "Anzeigename",
        "pt-BR": "Nome de exibição",
    },
    "data.connector.create_desc": {
        "en": "Description",
        "ja": "説明",
        "zh-CN": "描述",
        "ko": "설명",
        "es": "Descripción",
        "fr": "Description",
        "de": "Beschreibung",
        "pt-BR": "Descrição",
    },
    "data.connector.create_connector": {
        "en": "Connector",
        "ja": "コネクタ",
        "zh-CN": "连接器",
        "ko": "커넥터",
        "es": "Conector",
        "fr": "Connecteur",
        "de": "Konnektor",
        "pt-BR": "Conector",
    },
    "data.connector.create_path": {
        "en": "Path / folder ID / SOQL / app id",
        "ja": "パス / フォルダ ID / SOQL / アプリ ID",
        "zh-CN": "路径 / 文件夹 ID / SOQL / app id",
        "ko": "경로 / 폴더 ID / SOQL / 앱 ID",
        "es": "Ruta / ID de carpeta / SOQL / ID de app",
        "fr": "Chemin / ID dossier / SOQL / ID app",
        "de": "Pfad / Ordner-ID / SOQL / App-ID",
        "pt-BR": "Caminho / ID pasta / SOQL / ID app",
    },
    "data.connector.create_btn": {
        "en": "Register folder",
        "ja": "フォルダを登録",
        "zh-CN": "注册文件夹",
        "ko": "폴더 등록",
        "es": "Registrar carpeta",
        "fr": "Enregistrer le dossier",
        "de": "Ordner registrieren",
        "pt-BR": "Registrar pasta",
    },
    "data.connector.create_required": {
        "en": "Display name and path are required.",
        "ja": "表示名とパスは必須です。",
        "zh-CN": "需要显示名称与路径。",
        "ko": "표시 이름과 경로가 필요합니다.",
        "es": "Se requieren nombre y ruta.",
        "fr": "Nom affiché et chemin requis.",
        "de": "Anzeigename und Pfad sind erforderlich.",
        "pt-BR": "Nome e caminho são obrigatórios.",
    },
    "data.browse.empty": {
        "en": "No folders to browse yet.",
        "ja": "ブラウズできるフォルダがありません。",
        "zh-CN": "尚无可浏览的文件夹。",
        "ko": "탐색할 폴더가 없습니다.",
        "es": "Aún no hay carpetas para explorar.",
        "fr": "Aucun dossier à parcourir.",
        "de": "Noch keine Ordner zum Durchsuchen.",
        "pt-BR": "Sem pastas para explorar.",
    },
    "data.browse.pick": {
        "en": "Pick a folder",
        "ja": "フォルダを選択",
        "zh-CN": "选择文件夹",
        "ko": "폴더 선택",
        "es": "Elige una carpeta",
        "fr": "Choisir un dossier",
        "de": "Ordner wählen",
        "pt-BR": "Escolha uma pasta",
    },
    "data.browse.not_found": {
        "en": "Folder not found.",
        "ja": "フォルダが見つかりません。",
        "zh-CN": "未找到文件夹。",
        "ko": "폴더를 찾을 수 없습니다.",
        "es": "Carpeta no encontrada.",
        "fr": "Dossier introuvable.",
        "de": "Ordner nicht gefunden.",
        "pt-BR": "Pasta não encontrada.",
    },
    "data.browse.connector_pull": {
        "en": "🔄 Preview pull (10 items max)",
        "ja": "🔄 プレビュー pull (最大 10 件)",
        "zh-CN": "🔄 预览 pull (最多 10 项)",
        "ko": "🔄 프리뷰 pull (최대 10 건)",
        "es": "🔄 Vista previa (máx 10)",
        "fr": "🔄 Aperçu pull (max 10)",
        "de": "🔄 Vorschau-Pull (max 10)",
        "pt-BR": "🔄 Pré-visualizar pull (máx 10)",
    },
    "data.injected": {
        "en": "📁 {n} Data scope(s) injected as additional context",
        "ja": "📁 {n} 件のデータ範囲を追加コンテキストとして注入",
        "zh-CN": "📁 已将 {n} 个数据范围作为附加上下文注入",
        "ko": "📁 {n} 개 데이터 범위를 추가 컨텍스트로 주입",
        "es": "📁 Se inyectaron {n} alcance(s) de datos como contexto extra",
        "fr": "📁 {n} portée(s) de données injectée(s) en contexte additionnel",
        "de": "📁 {n} Datenbereich(e) als Zusatzkontext eingespeist",
        "pt-BR": "📁 {n} escopo(s) de dados injetado(s) como contexto extra",
    },
    # ===== Common UI atoms ==================================================
    "common.done": {
        "en": "Done!",
        "ja": "完了!",
        "zh-CN": "完成!",
        "ko": "완료!",
        "es": "¡Listo!",
        "fr": "Terminé !",
        "de": "Fertig!",
        "pt-BR": "Concluído!",
    },
    "common.transcribing": {
        "en": "Transcribing audio…",
        "ja": "音声を文字起こし中…",
        "zh-CN": "正在转写音频…",
        "ko": "오디오 변환 중…",
        "es": "Transcribiendo audio…",
        "fr": "Transcription audio…",
        "de": "Audio wird transkribiert…",
        "pt-BR": "Transcrevendo áudio…",
    },
    "common.transcribed": {
        "en": "🎙 Transcribed: {n:,} chars",
        "ja": "🎙 文字起こし完了: {n:,} 文字",
        "zh-CN": "🎙 转写完成: {n:,} 字符",
        "ko": "🎙 변환 완료: {n:,} 문자",
        "es": "🎙 Transcrito: {n:,} caracteres",
        "fr": "🎙 Transcrit : {n:,} caractères",
        "de": "🎙 Transkribiert: {n:,} Zeichen",
        "pt-BR": "🎙 Transcrito: {n:,} caracteres",
    },
    # ===== Flow mode ========================================================
    "flow.h": {
        "en": "🎬 Run a multi-agent flow",
        "ja": "🎬 マルチエージェントフローを実行",
        "zh-CN": "🎬 运行多智能体流程",
        "ko": "🎬 멀티에이전트 플로우 실행",
        "es": "🎬 Ejecutar flujo multi-agente",
        "fr": "🎬 Lancer un flux multi-agents",
        "de": "🎬 Multi-Agenten-Flow ausführen",
        "pt-BR": "🎬 Executar fluxo multi-agente",
    },
    "flow.pick": {
        "en": "Choose a flow",
        "ja": "Flow を選択",
        "zh-CN": "选择流程",
        "ko": "플로우 선택",
        "es": "Elegir flujo",
        "fr": "Choisir un flux",
        "de": "Flow wählen",
        "pt-BR": "Escolher fluxo",
    },
    "flow.run_btn": {
        "en": "▶ Run",
        "ja": "▶ 実行",
        "zh-CN": "▶ 运行",
        "ko": "▶ 실행",
        "es": "▶ Ejecutar",
        "fr": "▶ Exécuter",
        "de": "▶ Ausführen",
        "pt-BR": "▶ Executar",
    },
    "flow.steps_h": {
        "en": "🔍 Per-step output",
        "ja": "🔍 各ステップの出力",
        "zh-CN": "🔍 每步输出",
        "ko": "🔍 단계별 출력",
        "es": "🔍 Salida por paso",
        "fr": "🔍 Sortie par étape",
        "de": "🔍 Ausgabe pro Schritt",
        "pt-BR": "🔍 Saída por etapa",
    },
    "flow.input_method": {
        "en": "Input method",
        "ja": "入力方法",
        "zh-CN": "输入方式",
        "ko": "입력 방식",
        "es": "Método de entrada",
        "fr": "Méthode d'entrée",
        "de": "Eingabemethode",
        "pt-BR": "Método de entrada",
    },
    "flow.input_method.text": {
        "en": "📋 Paste text",
        "ja": "📋 テキスト貼り付け",
        "zh-CN": "📋 粘贴文本",
        "ko": "📋 텍스트 붙여넣기",
        "es": "📋 Pegar texto",
        "fr": "📋 Coller texte",
        "de": "📋 Text einfügen",
        "pt-BR": "📋 Colar texto",
    },
    "flow.input_method.file": {
        "en": "📎 Upload file",
        "ja": "📎 ファイルアップロード",
        "zh-CN": "📎 上传文件",
        "ko": "📎 파일 업로드",
        "es": "📎 Subir archivo",
        "fr": "📎 Téléverser un fichier",
        "de": "📎 Datei hochladen",
        "pt-BR": "📎 Enviar arquivo",
    },
    "flow.input_method.voice": {
        "en": "🎙 Voice input",
        "ja": "🎙 音声入力",
        "zh-CN": "🎙 语音输入",
        "ko": "🎙 음성 입력",
        "es": "🎙 Entrada por voz",
        "fr": "🎙 Entrée vocale",
        "de": "🎙 Spracheingabe",
        "pt-BR": "🎙 Entrada por voz",
    },
    "flow.sales.customer_name": {
        "en": "Customer name",
        "ja": "顧客名",
        "zh-CN": "客户名称",
        "ko": "고객명",
        "es": "Nombre del cliente",
        "fr": "Nom du client",
        "de": "Kundenname",
        "pt-BR": "Nome do cliente",
    },
    "flow.sales.product": {
        "en": "Our product",
        "ja": "自社製品",
        "zh-CN": "我方产品",
        "ko": "자사 제품",
        "es": "Nuestro producto",
        "fr": "Notre produit",
        "de": "Unser Produkt",
        "pt-BR": "Nosso produto",
    },
    "flow.sales.context": {
        "en": "Additional context",
        "ja": "追加コンテキスト",
        "zh-CN": "附加上下文",
        "ko": "추가 컨텍스트",
        "es": "Contexto adicional",
        "fr": "Contexte additionnel",
        "de": "Zusätzlicher Kontext",
        "pt-BR": "Contexto adicional",
    },
    "flow.sales.files": {
        "en": "📎 Supporting files (optional): IR / press / minutes — formats: {exts}",
        "ja": "📎 補助資料 (任意): IR / プレス / 議事録 などをアップロード · 対応形式: {exts}",
        "zh-CN": "📎 辅助文件(可选): IR / 新闻 / 纪要 — 支持: {exts}",
        "ko": "📎 보조 자료 (선택): IR / 보도 / 회의록 — 지원: {exts}",
        "es": "📎 Archivos de apoyo (opcional): IR / prensa / actas — formatos: {exts}",
        "fr": "📎 Fichiers complémentaires (optionnel) : IR / presse / comptes-rendus — formats : {exts}",
        "de": "📎 Hilfsdateien (optional): IR / Presse / Protokolle — Formate: {exts}",
        "pt-BR": "📎 Arquivos de apoio (opcional): IR / press / atas — formatos: {exts}",
    },
    "flow.sales.attached": {
        "en": "📎 Attached and parsed {n} file(s)",
        "ja": "📎 {n} 件のファイルを添付・解析しました",
        "zh-CN": "📎 已附加并解析 {n} 个文件",
        "ko": "📎 {n} 개 파일 첨부·파싱 완료",
        "es": "📎 Adjuntados y parseados {n} archivo(s)",
        "fr": "📎 {n} fichier(s) joint(s) et analysé(s)",
        "de": "📎 {n} Datei(en) angehängt und geparst",
        "pt-BR": "📎 {n} arquivo(s) anexado(s) e parseado(s)",
    },
    "flow.logic.file": {
        "en": "📎 Document to review — formats: {exts}",
        "ja": "📎 レビュー対象ファイル · 対応形式: {exts}",
        "zh-CN": "📎 待审查文件 — 支持: {exts}",
        "ko": "📎 검토 대상 파일 — 지원: {exts}",
        "es": "📎 Documento a revisar — formatos: {exts}",
        "fr": "📎 Document à relire — formats : {exts}",
        "de": "📎 Zu prüfendes Dokument — Formate: {exts}",
        "pt-BR": "📎 Documento a revisar — formatos: {exts}",
    },
    "flow.logic.audio_record": {
        "en": "Record from microphone (browser permission required)",
        "ja": "マイクから録音 (ブラウザ許可必須)",
        "zh-CN": "用麦克风录音(需浏览器权限)",
        "ko": "마이크로 녹음 (브라우저 권한 필요)",
        "es": "Grabar desde micrófono (permiso del navegador)",
        "fr": "Enregistrer depuis le micro (permission du navigateur)",
        "de": "Mikrofon-Aufnahme (Browser-Erlaubnis nötig)",
        "pt-BR": "Gravar do microfone (permissão do navegador)",
    },
    "flow.logic.text_input": {
        "en": "Document to review",
        "ja": "レビュー対象の文書",
        "zh-CN": "待审查文档",
        "ko": "검토 대상 문서",
        "es": "Documento a revisar",
        "fr": "Document à relire",
        "de": "Zu prüfendes Dokument",
        "pt-BR": "Documento a revisar",
    },
    "flow.rag.question": {
        "en": "Question",
        "ja": "質問",
        "zh-CN": "问题",
        "ko": "질문",
        "es": "Pregunta",
        "fr": "Question",
        "de": "Frage",
        "pt-BR": "Pergunta",
    },
    "flow.rag.retriever_note": {
        "en": "Retriever uses your personal memory (`PersonalMemory.search`). To use a different retriever, swap via the SDK with `flow.run(retriever=...)`.",
        "ja": "リトリーバは個人メモリ (`PersonalMemory.search`) を使用します。他のリトリーバを使う場合は SDK の `flow.run(retriever=...)` で差し替えてください。",
        "zh-CN": "检索器使用你的个人记忆 (`PersonalMemory.search`)。如需其他检索器,通过 SDK 的 `flow.run(retriever=...)` 替换。",
        "ko": "리트리버는 개인 메모리 (`PersonalMemory.search`) 를 사용합니다. 다른 리트리버를 사용하려면 SDK 의 `flow.run(retriever=...)` 로 교체하세요.",
        "es": "El retriever usa tu memoria personal (`PersonalMemory.search`). Para otro retriever, cambia vía SDK con `flow.run(retriever=...)`.",
        "fr": "Le retriever utilise votre mémoire personnelle (`PersonalMemory.search`). Pour un autre retriever, utilisez `flow.run(retriever=...)` via le SDK.",
        "de": "Retriever nutzt deinen persönlichen Speicher (`PersonalMemory.search`). Für einen anderen Retriever via SDK mit `flow.run(retriever=...)` tauschen.",
        "pt-BR": "O retriever usa sua memória pessoal (`PersonalMemory.search`). Para outro retriever, troque via SDK com `flow.run(retriever=...)`.",
    },
    # ===== Skill mode =======================================================
    "skill.h": {
        "en": "🛠 Run a business skill",
        "ja": "🛠 ビジネススキルを実行",
        "zh-CN": "🛠 运行业务技能",
        "ko": "🛠 비즈니스 스킬 실행",
        "es": "🛠 Ejecutar habilidad de negocio",
        "fr": "🛠 Lancer une compétence métier",
        "de": "🛠 Business-Skill ausführen",
        "pt-BR": "🛠 Executar habilidade de negócio",
    },
    "skill.pick": {
        "en": "Choose a skill",
        "ja": "スキルを選択",
        "zh-CN": "选择技能",
        "ko": "스킬 선택",
        "es": "Elegir habilidad",
        "fr": "Choisir une compétence",
        "de": "Skill wählen",
        "pt-BR": "Escolher habilidade",
    },
    "skill.input_method.text": {
        "en": "Text",
        "ja": "テキスト",
        "zh-CN": "文本",
        "ko": "텍스트",
        "es": "Texto",
        "fr": "Texte",
        "de": "Text",
        "pt-BR": "Texto",
    },
    "skill.input_method.file": {
        "en": "📎 Attach file (combinable)",
        "ja": "📎 ファイル添付 (組合せ可)",
        "zh-CN": "📎 附加文件(可组合)",
        "ko": "📎 파일 첨부 (조합 가능)",
        "es": "📎 Adjuntar archivo (combinable)",
        "fr": "📎 Joindre un fichier (combinable)",
        "de": "📎 Datei anhängen (kombinierbar)",
        "pt-BR": "📎 Anexar arquivo (combinável)",
    },
    "skill.input": {
        "en": "Input",
        "ja": "入力",
        "zh-CN": "输入",
        "ko": "입력",
        "es": "Entrada",
        "fr": "Entrée",
        "de": "Eingabe",
        "pt-BR": "Entrada",
    },
    "skill.input_placeholder": {
        "en": "Describe what you want the agent to do",
        "ja": "エージェントへの依頼内容を記入",
        "zh-CN": "描述你希望代理做什么",
        "ko": "에이전트에게 시킬 내용을 입력",
        "es": "Describe qué quieres que haga el agente",
        "fr": "Décrivez ce que l'agent doit faire",
        "de": "Beschreibe, was der Agent tun soll",
        "pt-BR": "Descreva o que o agente deve fazer",
    },
    "skill.attach_label": {
        "en": "📎 Attach files: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — supported: {exts}",
        "ja": "📎 ファイル添付: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML 等 · 対応: {exts}",
        "zh-CN": "📎 附加文件: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML 等 — 支持: {exts}",
        "ko": "📎 파일 첨부: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — 지원: {exts}",
        "es": "📎 Adjuntar archivos: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — soportados: {exts}",
        "fr": "📎 Joindre fichiers : PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — supportés : {exts}",
        "de": "📎 Dateien anhängen: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — unterstützt: {exts}",
        "pt-BR": "📎 Anexar arquivos: PDF / Word / PowerPoint / Excel / CSV / TXT / MD / HTML — suportados: {exts}",
    },
    "skill.audio_record": {
        "en": "Record from microphone",
        "ja": "マイクから録音",
        "zh-CN": "用麦克风录音",
        "ko": "마이크로 녹음",
        "es": "Grabar desde micrófono",
        "fr": "Enregistrer depuis le micro",
        "de": "Mikrofon-Aufnahme",
        "pt-BR": "Gravar do microfone",
    },
    "skill.audio_edit": {
        "en": "Transcribed text (editable)",
        "ja": "文字起こし結果 (編集可)",
        "zh-CN": "转写结果(可编辑)",
        "ko": "변환 결과 (편집 가능)",
        "es": "Texto transcrito (editable)",
        "fr": "Texte transcrit (modifiable)",
        "de": "Transkription (editierbar)",
        "pt-BR": "Texto transcrito (editável)",
    },
    "skill.tts_toggle": {
        "en": "🔊 Read output aloud (optional)",
        "ja": "🔊 出力を音声で読み上げ (任意)",
        "zh-CN": "🔊 朗读输出(可选)",
        "ko": "🔊 출력을 음성으로 읽기 (선택)",
        "es": "🔊 Leer salida en voz alta (opcional)",
        "fr": "🔊 Lire la sortie à voix haute (optionnel)",
        "de": "🔊 Ausgabe vorlesen (optional)",
        "pt-BR": "🔊 Ler saída em voz alta (opcional)",
    },
    "skill.tts_synthesizing": {
        "en": "Synthesizing speech…",
        "ja": "音声合成中…",
        "zh-CN": "正在合成语音…",
        "ko": "음성 합성 중…",
        "es": "Sintetizando voz…",
        "fr": "Synthèse vocale…",
        "de": "Sprache wird synthetisiert…",
        "pt-BR": "Sintetizando voz…",
    },
    "skill.download_h": {
        "en": "📥 Download as…",
        "ja": "📥 ファイル出力",
        "zh-CN": "📥 下载为…",
        "ko": "📥 다운로드…",
        "es": "📥 Descargar como…",
        "fr": "📥 Télécharger…",
        "de": "📥 Herunterladen als…",
        "pt-BR": "📥 Baixar como…",
    },
    "skill.download_office_missing": {
        "en": "Office extras not installed (`pip install praxia[office]`)",
        "ja": "Office 拡張未導入 (`pip install praxia[office]`)",
        "zh-CN": "未安装 Office 扩展 (`pip install praxia[office]`)",
        "ko": "Office 확장 미설치 (`pip install praxia[office]`)",
        "es": "Extras de Office no instalados (`pip install praxia[office]`)",
        "fr": "Extras Office non installés (`pip install praxia[office]`)",
        "de": "Office-Extras nicht installiert (`pip install praxia[office]`)",
        "pt-BR": "Extras do Office não instalados (`pip install praxia[office]`)",
    },
    "skill.clear_output": {
        "en": "Clear output",
        "ja": "出力をクリア",
        "zh-CN": "清除输出",
        "ko": "출력 지우기",
        "es": "Borrar salida",
        "fr": "Effacer la sortie",
        "de": "Ausgabe löschen",
        "pt-BR": "Limpar saída",
    },
    "skill.use_saved_prompt": {
        "en": "📜 Load from saved prompts (optional)",
        "ja": "📜 保存済プロンプトをロード (任意)",
        "zh-CN": "📜 从已保存提示词加载(可选)",
        "ko": "📜 저장된 프롬프트에서 로드 (선택)",
        "es": "📜 Cargar desde prompts guardados (opcional)",
        "fr": "📜 Charger un prompt enregistré (optionnel)",
        "de": "📜 Aus gespeicherten Prompts laden (optional)",
        "pt-BR": "📜 Carregar de prompts salvos (opcional)",
    },
    "skill.pick_saved_prompt": {
        "en": "Pick a saved prompt",
        "ja": "保存済プロンプトを選択",
        "zh-CN": "选择已保存的提示词",
        "ko": "저장된 프롬프트 선택",
        "es": "Elige un prompt guardado",
        "fr": "Choisir un prompt enregistré",
        "de": "Gespeicherten Prompt wählen",
        "pt-BR": "Escolha um prompt salvo",
    },
    "skill.no_template": {
        "en": "(none — write input from scratch)",
        "ja": "(無し — ゼロから入力)",
        "zh-CN": "(无 — 从头输入)",
        "ko": "(없음 — 처음부터 입력)",
        "es": "(ninguno — escribe desde cero)",
        "fr": "(aucun — écrire de zéro)",
        "de": "(keiner — von Grund auf schreiben)",
        "pt-BR": "(nenhum — escrever do zero)",
    },
    "skill.load_btn": {
        "en": "📥 Load into input",
        "ja": "📥 入力欄にロード",
        "zh-CN": "📥 加载到输入框",
        "ko": "📥 입력란에 로드",
        "es": "📥 Cargar en la entrada",
        "fr": "📥 Charger dans l'entrée",
        "de": "📥 In Eingabe laden",
        "pt-BR": "📥 Carregar na entrada",
    },
    # ===== Memory mode ======================================================
    "memory.h": {
        "en": "🧠 Knowledge",
        "ja": "🧠 ナレッジ",
        "zh-CN": "🧠 知识",
        "ko": "🧠 지식",
        "es": "🧠 Conocimiento",
        "fr": "🧠 Connaissances",
        "de": "🧠 Wissen",
        "pt-BR": "🧠 Conhecimento",
    },
    "memory.personal_h": {
        "en": "Personal memory",
        "ja": "個人メモリ",
        "zh-CN": "个人记忆",
        "ko": "개인 메모리",
        "es": "Memoria personal",
        "fr": "Mémoire personnelle",
        "de": "Persönlicher Speicher",
        "pt-BR": "Memória pessoal",
    },
    "memory.entries_total": {
        "en": "Total entries",
        "ja": "総エントリ数",
        "zh-CN": "总条目数",
        "ko": "총 엔트리 수",
        "es": "Total de entradas",
        "fr": "Total des entrées",
        "de": "Einträge gesamt",
        "pt-BR": "Total de entradas",
    },
    "memory.search": {
        "en": "Search",
        "ja": "検索",
        "zh-CN": "搜索",
        "ko": "검색",
        "es": "Buscar",
        "fr": "Rechercher",
        "de": "Suchen",
        "pt-BR": "Buscar",
    },
    "memory.shared_h": {
        "en": "Shared memory",
        "ja": "共有メモリ",
        "zh-CN": "共享记忆",
        "ko": "공유 메모리",
        "es": "Memoria compartida",
        "fr": "Mémoire partagée",
        "de": "Geteilter Speicher",
        "pt-BR": "Memória compartilhada",
    },
    "memory.blocks_total": {
        "en": "Block count",
        "ja": "ブロック数",
        "zh-CN": "块数",
        "ko": "블록 수",
        "es": "Cantidad de bloques",
        "fr": "Nombre de blocs",
        "de": "Block-Anzahl",
        "pt-BR": "Total de blocos",
    },
    "memory.skills_h": {
        "en": "🎯 Skill registry",
        "ja": "🎯 スキルレジストリ",
        "zh-CN": "🎯 技能注册表",
        "ko": "🎯 스킬 레지스트리",
        "es": "🎯 Registro de habilidades",
        "fr": "🎯 Registre des compétences",
        "de": "🎯 Skill-Registry",
        "pt-BR": "🎯 Registro de habilidades",
    },
    "memory.skills_intro": {
        "en": "Skills accumulate as you and your team use Praxia. Personal skills get auto-promoted to the org catalog when they prove themselves (frequency / outcome / LLM-eval signals). Skills live in their own registry, separate from memory entries.",
        "ja": "スキルは個人/組織が Praxia を使うに従って蓄積されます。個人スキルが頻度・成果・LLM 評価で実績を満たすと自動的に組織カタログへ昇格。スキルはメモリエントリとは別の独立レジストリで管理されます。",
        "zh-CN": "随团队使用 Praxia,技能会累积。个人技能在频次/成果/LLM 评分达标时自动晋升至组织目录。技能与记忆条目在独立的注册表中管理。",
        "ko": "Praxia 를 사용함에 따라 스킬이 누적됩니다. 개인 스킬은 빈도/성과/LLM 평가 기준 충족 시 조직 카탈로그로 자동 승격. 메모리와는 별도 레지스트리.",
        "es": "Las habilidades se acumulan con el uso. Las personales se promueven automáticamente al catálogo org cuando cumplen criterios (frecuencia / outcome / LLM-eval). Registro separado de las entradas de memoria.",
        "fr": "Les compétences s'accumulent avec l'usage. Les compétences personnelles sont auto-promues au catalogue org selon fréquence / résultat / éval LLM. Registre séparé des entrées de mémoire.",
        "de": "Skills sammeln sich mit der Nutzung an. Persönliche Skills werden automatisch ins Org-Katalog befördert (Frequenz / Ergebnis / LLM-Eval). Eigenes Registry, getrennt von Memory.",
        "pt-BR": "As habilidades se acumulam com o uso. Habilidades pessoais são promovidas automaticamente ao catálogo org (frequência / outcome / LLM-eval). Registro separado das entradas de memória.",
    },
    "memory.skills_personal": {
        "en": "👤 Your personal skills",
        "ja": "👤 あなたの個人スキル",
        "zh-CN": "👤 你的个人技能",
        "ko": "👤 내 개인 스킬",
        "es": "👤 Tus habilidades personales",
        "fr": "👤 Vos compétences personnelles",
        "de": "👤 Deine persönlichen Skills",
        "pt-BR": "👤 Suas habilidades pessoais",
    },
    "memory.skills_org": {
        "en": "⭐ Org-promoted skills",
        "ja": "⭐ 組織昇格済スキル",
        "zh-CN": "⭐ 已晋升组织技能",
        "ko": "⭐ 조직 승격 스킬",
        "es": "⭐ Habilidades promovidas a org",
        "fr": "⭐ Compétences promues à l'org",
        "de": "⭐ In Org-Katalog beförderte Skills",
        "pt-BR": "⭐ Habilidades promovidas à org",
    },
    "memory.skills_count": {
        "en": "Count",
        "ja": "件数",
        "zh-CN": "数量",
        "ko": "개수",
        "es": "Cantidad",
        "fr": "Nombre",
        "de": "Anzahl",
        "pt-BR": "Quantidade",
    },
    "memory.skills_empty": {
        "en": "None yet — skills register as you save / promote them.",
        "ja": "未登録 — 保存・昇格時にここに表示されます。",
        "zh-CN": "尚无 — 保存或晋升时会出现在此。",
        "ko": "없음 — 저장/승격 시 여기에 표시됩니다.",
        "es": "Aún ninguna — aparecerán al guardar / promover.",
        "fr": "Aucune — apparaîtront en sauvegardant / promouvant.",
        "de": "Noch keine — beim Speichern / Befördern erscheinen sie hier.",
        "pt-BR": "Nenhuma ainda — aparecerão ao salvar / promover.",
    },
    "memory.skills_empty_org": {
        "en": "None yet — promotions happen via Consolidate (admin) when criteria are met.",
        "ja": "未昇格 — 基準を満たすと Consolidate (admin) で自動昇格します。",
        "zh-CN": "尚未晋升 — 满足条件时通过 Consolidate (admin) 自动晋升。",
        "ko": "승격 없음 — 기준 충족 시 Consolidate (admin) 으로 자동 승격됩니다.",
        "es": "Sin promociones — ocurren vía Consolidate (admin) al cumplir criterios.",
        "fr": "Aucune — les promotions se font via Consolidate (admin) selon critères.",
        "de": "Keine — Promotions erfolgen via Consolidate (admin) bei erfüllten Kriterien.",
        "pt-BR": "Nenhuma — promoções via Consolidate (admin) quando critérios cumpridos.",
    },
    # ===== Consolidate mode =================================================
    "consolidate.h": {
        "en": "🌙 Sleep-time consolidation",
        "ja": "🌙 Sleep-time Consolidation",
        "zh-CN": "🌙 夜间整合",
        "ko": "🌙 수면 시 통합",
        "es": "🌙 Consolidación nocturna",
        "fr": "🌙 Consolidation nocturne",
        "de": "🌙 Nacht-Konsolidierung",
        "pt-BR": "🌙 Consolidação noturna",
    },
    "consolidate.intro": {
        "en": "Promote high-value personal-memory entries into shared org memory. Usually a nightly cron — this button is for manual / dry-run.",
        "ja": "個人メモリの高価値項目を組織共有メモリへ昇格。通常は夜間バッチ — このボタンは手動 / dry-run 用。",
        "zh-CN": "将高价值的个人记忆条目晋升至组织共享记忆。通常是夜间定时任务 — 此按钮用于手动 / dry-run。",
        "ko": "개인 메모리의 가치 있는 항목을 조직 공유 메모리로 승격. 보통 야간 배치 — 이 버튼은 수동 / dry-run 용.",
        "es": "Promueve entradas valiosas de memoria personal a la memoria compartida. Normalmente cron nocturno — este botón es manual / dry-run.",
        "fr": "Promeut les entrées de valeur de la mémoire personnelle vers la mémoire partagée. Généralement cron nocturne — bouton manuel / dry-run.",
        "de": "Befördert wertvolle persönliche Memory-Einträge in den geteilten Org-Speicher. Üblicherweise nächtlicher Cron — Button für manuell / Dry-Run.",
        "pt-BR": "Promove entradas valiosas da memória pessoal para a memória compartilhada. Normalmente cron noturno — botão para manual / dry-run.",
    },
    "consolidate.threshold": {
        "en": "Auto-promote threshold",
        "ja": "自動昇格の閾値",
        "zh-CN": "自动晋升阈值",
        "ko": "자동 승격 임계값",
        "es": "Umbral de auto-promoción",
        "fr": "Seuil d'auto-promotion",
        "de": "Auto-Promote-Schwelle",
        "pt-BR": "Limite de auto-promoção",
    },
    "consolidate.dry_run": {
        "en": "Dry run (preview only — no writes)",
        "ja": "予行実行 (プレビューのみ・書き込み無し)",
        "zh-CN": "预演 (仅预览,不写入)",
        "ko": "예행 실행 (미리보기만, 쓰기 없음)",
        "es": "Ejecución de prueba (solo vista previa — sin escribir)",
        "fr": "Exécution à blanc (aperçu uniquement — pas d'écriture)",
        "de": "Probelauf (nur Vorschau — keine Schreibzugriffe)",
        "pt-BR": "Execução de teste (apenas pré-visualização — sem escritas)",
    },
    "consolidate.run": {
        "en": "🌙 Consolidate",
        "ja": "🌙 統合実行",
        "zh-CN": "🌙 整合",
        "ko": "🌙 통합 실행",
        "es": "🌙 Consolidar",
        "fr": "🌙 Consolider",
        "de": "🌙 Konsolidieren",
        "pt-BR": "🌙 Consolidar",
    },
    "consolidate.running": {
        "en": "Consolidating…",
        "ja": "統合実行中…",
        "zh-CN": "正在整合…",
        "ko": "통합 중…",
        "es": "Consolidando…",
        "fr": "Consolidation…",
        "de": "Konsolidieren…",
        "pt-BR": "Consolidando…",
    },
    # ===== Dashboard mode ===================================================
    "dashboard.h": {
        "en": "📊 Dashboard",
        "ja": "📊 ダッシュボード",
        "zh-CN": "📊 仪表板",
        "ko": "📊 대시보드",
        "es": "📊 Panel",
        "fr": "📊 Tableau de bord",
        "de": "📊 Dashboard",
        "pt-BR": "📊 Painel",
    },
    "dashboard.scope_label": {
        "en": "Scope",
        "ja": "範囲",
        "zh-CN": "范围",
        "ko": "범위",
        "es": "Alcance",
        "fr": "Portée",
        "de": "Bereich",
        "pt-BR": "Escopo",
    },
    "dashboard.scope.personal": {
        "en": "Personal",
        "ja": "個人",
        "zh-CN": "个人",
        "ko": "개인",
        "es": "Personal",
        "fr": "Personnel",
        "de": "Persönlich",
        "pt-BR": "Pessoal",
    },
    "dashboard.scope.org": {
        "en": "Organization",
        "ja": "組織",
        "zh-CN": "组织",
        "ko": "조직",
        "es": "Organización",
        "fr": "Organisation",
        "de": "Organisation",
        "pt-BR": "Organização",
    },
    "dashboard.runs_total": {
        "en": "Total runs",
        "ja": "総実行回数",
        "zh-CN": "总运行次数",
        "ko": "총 실행 횟수",
        "es": "Ejecuciones totales",
        "fr": "Exécutions totales",
        "de": "Gesamtläufe",
        "pt-BR": "Total de execuções",
    },
    "dashboard.org_runs_total": {
        "en": "Org runs",
        "ja": "組織実行回数",
        "zh-CN": "组织运行次数",
        "ko": "조직 실행 횟수",
        "es": "Ejecuciones org",
        "fr": "Exécutions org",
        "de": "Org-Läufe",
        "pt-BR": "Execuções org",
    },
    "dashboard.success_rate": {
        "en": "Success rate",
        "ja": "成功率",
        "zh-CN": "成功率",
        "ko": "성공률",
        "es": "Tasa de éxito",
        "fr": "Taux de réussite",
        "de": "Erfolgsrate",
        "pt-BR": "Taxa de sucesso",
    },
    "dashboard.memory_entries": {
        "en": "Memory entries",
        "ja": "メモリエントリ数",
        "zh-CN": "记忆条目数",
        "ko": "메모리 항목 수",
        "es": "Entradas de memoria",
        "fr": "Entrées mémoire",
        "de": "Speicher-Einträge",
        "pt-BR": "Entradas de memória",
    },
    "dashboard.active_users": {
        "en": "Active users",
        "ja": "アクティブユーザ",
        "zh-CN": "活跃用户",
        "ko": "활성 사용자",
        "es": "Usuarios activos",
        "fr": "Utilisateurs actifs",
        "de": "Aktive Nutzer",
        "pt-BR": "Usuários ativos",
    },
    "dashboard.top_skills": {
        "en": "Top skills",
        "ja": "よく使うスキル",
        "zh-CN": "热门技能",
        "ko": "주요 스킬",
        "es": "Habilidades principales",
        "fr": "Compétences principales",
        "de": "Top-Skills",
        "pt-BR": "Habilidades principais",
    },
    "dashboard.top_users": {
        "en": "Top users",
        "ja": "アクティブユーザ TOP",
        "zh-CN": "活跃用户 TOP",
        "ko": "주요 사용자",
        "es": "Usuarios principales",
        "fr": "Principaux utilisateurs",
        "de": "Top-Nutzer",
        "pt-BR": "Principais usuários",
    },
    "dashboard.empty": {
        "en": "Not enough data yet — usage history will appear here once you start running flows or skills.",
        "ja": "データがまだ少ないため表示できません — フロー / スキルを実行するとここに利用履歴が出ます。",
        "zh-CN": "数据还不足 — 运行流程或技能后,使用历史会显示在此处。",
        "ko": "데이터가 아직 부족합니다 — 플로우 / 스킬을 실행하면 사용 이력이 여기에 표시됩니다.",
        "es": "Aún no hay suficientes datos — el historial aparecerá tras ejecutar flujos o skills.",
        "fr": "Pas encore assez de données — l'historique apparaîtra après quelques exécutions.",
        "de": "Noch nicht genug Daten — der Verlauf erscheint nach einigen Läufen.",
        "pt-BR": "Ainda não há dados suficientes — o histórico aparecerá após algumas execuções.",
    },
    # ===== Prompts mode =====================================================
    "prompts.h": {
        "en": "📝 Custom prompts",
        "ja": "📝 カスタムプロンプト",
        "zh-CN": "📝 自定义提示词",
        "ko": "📝 커스텀 프롬프트",
        "es": "📝 Prompts personalizados",
        "fr": "📝 Prompts personnalisés",
        "de": "📝 Benutzerdefinierte Prompts",
        "pt-BR": "📝 Prompts personalizados",
    },
    "prompts.intro": {
        "en": "Generate a polished prompt template from a 1-line task, browse / edit / delete your saved prompts, or distribute curated prompts to your team.",
        "ja": "1 行の指示からプロンプトテンプレートを自動生成、保存済プロンプトの閲覧・編集・削除、またはチームへの配布。",
        "zh-CN": "从一行任务生成精炼的提示模板,浏览/编辑/删除保存的提示词,或向团队分发已审核的提示。",
        "ko": "1 줄 작업으로 프롬프트 템플릿 생성, 저장된 프롬프트 열람·편집·삭제, 또는 팀에 배포.",
        "es": "Genera una plantilla de prompt a partir de una tarea de 1 línea, navega/edita/elimina tus prompts guardados o distribúyelos al equipo.",
        "fr": "Générez un template de prompt à partir d'une tâche d'une ligne, parcourez/modifiez/supprimez vos prompts ou distribuez-les à l'équipe.",
        "de": "Erzeuge eine Prompt-Vorlage aus einer einzeiligen Aufgabe, durchstöbere/bearbeite/lösche gespeicherte Prompts oder verteile kuratierte Prompts ans Team.",
        "pt-BR": "Gere um template de prompt a partir de uma tarefa de 1 linha, navegue/edite/exclua prompts salvos ou distribua ao time.",
    },
    "prompts.tab.generate": {
        "en": "✨ Generate (PromptDesigner)",
        "ja": "✨ 生成 (PromptDesigner)",
        "zh-CN": "✨ 生成 (PromptDesigner)",
        "ko": "✨ 생성 (PromptDesigner)",
        "es": "✨ Generar (PromptDesigner)",
        "fr": "✨ Générer (PromptDesigner)",
        "de": "✨ Generieren (PromptDesigner)",
        "pt-BR": "✨ Gerar (PromptDesigner)",
    },
    "prompts.tab.browse": {
        "en": "📚 Browse & edit",
        "ja": "📚 一覧・編集",
        "zh-CN": "📚 浏览与编辑",
        "ko": "📚 목록·편집",
        "es": "📚 Explorar y editar",
        "fr": "📚 Parcourir et éditer",
        "de": "📚 Durchsuchen & Bearbeiten",
        "pt-BR": "📚 Explorar e editar",
    },
    "prompts.tab.distribute": {
        "en": "🤝 Share (admin)",
        "ja": "🤝 共有 (管理者)",
        "zh-CN": "🤝 共享 (管理员)",
        "ko": "🤝 공유 (관리자)",
        "es": "🤝 Compartir (admin)",
        "fr": "🤝 Partager (admin)",
        "de": "🤝 Teilen (Admin)",
        "pt-BR": "🤝 Compartilhar (admin)",
    },
    # ----- Generate (PromptDesigner) -----
    "prompts.generate.intro": {
        "en": "Describe your task in 1 line — get a production-grade prompt template back: tuned system message, `${variable}` user template, 2-3 few-shot examples, 5-criterion eval rubric. Per-LLM idioms applied automatically.",
        "ja": "やりたいことを 1 行で書くだけで、本番品質のプロンプト設計が返ってきます — チューニング済 system メッセージ、`${variable}` 入り user テンプレート、Few-Shot 例 2〜3 件、5 観点の評価ルーブリック付き。LLM ごとの作法を自動適用。",
        "zh-CN": "用一行描述任务,即可获得生产级提示模板: 调优 system 消息、含 `${variable}` 的 user 模板、2-3 个 few-shot 示例、5 项评估标准。自动适用 LLM 特定写法。",
        "ko": "한 줄로 작업을 설명하면 프로덕션 품질의 프롬프트 템플릿을 받습니다: 튜닝된 system 메시지, `${variable}` 포함 user 템플릿, Few-Shot 예시 2-3 개, 5 기준 루브릭. LLM 별 관용구 자동 적용.",
        "es": "Describe tu tarea en 1 línea: recibirás un template de prompt de producción — system ajustado, plantilla user con `${variable}`, 2-3 few-shot, rúbrica de 5 criterios. Idiomas por LLM aplicados automáticamente.",
        "fr": "Décrivez votre tâche en 1 ligne — recevez un template de prompt prêt prod : system affûté, template user avec `${variable}`, 2-3 few-shot, rubrique à 5 critères. Idiomes par LLM appliqués auto.",
        "de": "Beschreibe deine Aufgabe in 1 Zeile — erhalte ein produktionsreifes Prompt-Template: getuneter System-Prompt, User-Template mit `${variable}`, 2-3 Few-Shot, 5-Kriterien-Rubrik. LLM-Idiome automatisch angewendet.",
        "pt-BR": "Descreva sua tarefa em 1 linha — receba um template de prompt pronto: system ajustado, template user com `${variable}`, 2-3 few-shot, rubrica de 5 critérios. Idiomas por LLM aplicados automaticamente.",
    },
    "prompts.generate.task_label": {
        "en": "Task description",
        "ja": "タスク内容",
        "zh-CN": "任务描述",
        "ko": "작업 설명",
        "es": "Descripción de la tarea",
        "fr": "Description de la tâche",
        "de": "Aufgabenbeschreibung",
        "pt-BR": "Descrição da tarefa",
    },
    "prompts.generate.task_placeholder": {
        "en": "e.g. score contract risk 1-5 in JSON",
        "ja": "例: 契約書のリスクを 1〜5 段階で JSON 評価",
        "zh-CN": "例: 以 JSON 评 1-5 级合同风险",
        "ko": "예: 계약서 리스크를 1-5 로 JSON 평가",
        "es": "p. ej. valorar riesgo de contrato 1-5 en JSON",
        "fr": "ex. noter le risque du contrat 1-5 en JSON",
        "de": "z. B. Vertragsrisiko 1-5 als JSON bewerten",
        "pt-BR": "ex. avaliar risco do contrato 1-5 em JSON",
    },
    "prompts.generate.target_llm": {
        "en": "Target LLM family",
        "ja": "対象 LLM ファミリ",
        "zh-CN": "目标 LLM 家族",
        "ko": "대상 LLM 패밀리",
        "es": "Familia LLM objetivo",
        "fr": "Famille LLM cible",
        "de": "Ziel-LLM-Familie",
        "pt-BR": "Família LLM alvo",
    },
    "prompts.generate.target_llm_auto": {
        "en": "(auto — use current LLM)",
        "ja": "(自動 — 現在の LLM を使用)",
        "zh-CN": "(自动 — 使用当前 LLM)",
        "ko": "(자동 — 현재 LLM 사용)",
        "es": "(auto — usar LLM actual)",
        "fr": "(auto — utiliser le LLM actuel)",
        "de": "(auto — aktuelles LLM)",
        "pt-BR": "(auto — usar LLM atual)",
    },
    "prompts.generate.output_format": {
        "en": "Expected output format",
        "ja": "出力形式",
        "zh-CN": "期望输出格式",
        "ko": "출력 형식",
        "es": "Formato de salida",
        "fr": "Format de sortie",
        "de": "Ausgabeformat",
        "pt-BR": "Formato de saída",
    },
    "prompts.generate.include_examples": {
        "en": "Include 2-3 few-shot examples",
        "ja": "Few-shot 例 2〜3 件を含める",
        "zh-CN": "包含 2-3 个 few-shot 示例",
        "ko": "Few-shot 예시 2-3 개 포함",
        "es": "Incluir 2-3 ejemplos few-shot",
        "fr": "Inclure 2-3 exemples few-shot",
        "de": "2-3 Few-Shot-Beispiele einschließen",
        "pt-BR": "Incluir 2-3 exemplos few-shot",
    },
    "prompts.generate.max_tokens": {
        "en": "Max output tokens",
        "ja": "最大出力トークン数",
        "zh-CN": "最大输出 token 数",
        "ko": "최대 출력 토큰",
        "es": "Tokens máximos de salida",
        "fr": "Tokens max en sortie",
        "de": "Max. Ausgabe-Token",
        "pt-BR": "Tokens máx. de saída",
    },
    "prompts.generate.max_tokens_help": {
        "en": "Cap on the meta-prompt's response length. Increase if generation is being cut off (especially for pptx / docx output formats which need detailed slide / section guidance).",
        "ja": "メタプロンプト応答の最大長。pptx / docx 形式など詳細な指示が必要な場合に途中で切れたら増やしてください。",
        "zh-CN": "Meta prompt 响应长度上限。如果生成被截断 (尤其是 pptx / docx 等需要详细指示的格式),请增加该值。",
        "ko": "메타 프롬프트 응답 길이 상한. pptx / docx 등 상세 지시가 필요한 형식에서 생성이 잘리면 늘려주세요.",
        "es": "Tope de longitud de respuesta del meta-prompt. Increméntalo si la generación se corta (especialmente para pptx / docx).",
        "fr": "Plafond de longueur de la réponse du meta-prompt. Augmentez si la génération est coupée (surtout pour pptx / docx).",
        "de": "Begrenzung der Meta-Prompt-Antwortlänge. Erhöhen, wenn Generierung abgeschnitten wird (besonders bei pptx / docx).",
        "pt-BR": "Limite do comprimento da resposta do meta-prompt. Aumente se a geração for cortada (especialmente para pptx / docx).",
    },
    "prompts.generate.constraint": {
        "en": "Constraint level",
        "ja": "制約レベル",
        "zh-CN": "约束级别",
        "ko": "제약 수준",
        "es": "Nivel de restricción",
        "fr": "Niveau de contrainte",
        "de": "Constraint-Level",
        "pt-BR": "Nível de restrição",
    },
    "prompts.generate.btn": {
        "en": "✨ Generate template",
        "ja": "✨ テンプレート生成",
        "zh-CN": "✨ 生成模板",
        "ko": "✨ 템플릿 생성",
        "es": "✨ Generar template",
        "fr": "✨ Générer le template",
        "de": "✨ Template erzeugen",
        "pt-BR": "✨ Gerar template",
    },
    "prompts.generate.task_required": {
        "en": "Task description is required.",
        "ja": "タスク内容は必須です。",
        "zh-CN": "需要任务描述。",
        "ko": "작업 설명이 필요합니다.",
        "es": "Se requiere descripción de tarea.",
        "fr": "Description de la tâche requise.",
        "de": "Aufgabenbeschreibung erforderlich.",
        "pt-BR": "Descrição da tarefa é obrigatória.",
    },
    "prompts.generate.designing": {
        "en": "Designing prompt template…",
        "ja": "プロンプト設計中…",
        "zh-CN": "设计提示模板中…",
        "ko": "프롬프트 템플릿 설계 중…",
        "es": "Diseñando plantilla…",
        "fr": "Création du template…",
        "de": "Erzeuge Template…",
        "pt-BR": "Projetando template…",
    },
    "prompts.generate.save_h": {
        "en": "💾 Save to your prompt library",
        "ja": "💾 プロンプトライブラリに保存",
        "zh-CN": "💾 保存到你的提示词库",
        "ko": "💾 프롬프트 라이브러리에 저장",
        "es": "💾 Guardar en tu biblioteca de prompts",
        "fr": "💾 Enregistrer dans la bibliothèque",
        "de": "💾 In Prompt-Bibliothek speichern",
        "pt-BR": "💾 Salvar na biblioteca de prompts",
    },
    "prompts.generate.save_name": {
        "en": "Name",
        "ja": "名前",
        "zh-CN": "名称",
        "ko": "이름",
        "es": "Nombre",
        "fr": "Nom",
        "de": "Name",
        "pt-BR": "Nome",
    },
    "prompts.generate.save_desc": {
        "en": "Description",
        "ja": "説明",
        "zh-CN": "描述",
        "ko": "설명",
        "es": "Descripción",
        "fr": "Description",
        "de": "Beschreibung",
        "pt-BR": "Descrição",
    },
    "prompts.generate.save_btn": {
        "en": "💾 Save to library",
        "ja": "💾 ライブラリに保存",
        "zh-CN": "💾 保存到库",
        "ko": "💾 라이브러리에 저장",
        "es": "💾 Guardar en biblioteca",
        "fr": "💾 Enregistrer",
        "de": "💾 Speichern",
        "pt-BR": "💾 Salvar",
    },
    "prompts.generate.discard_btn": {
        "en": "Discard",
        "ja": "破棄",
        "zh-CN": "丢弃",
        "ko": "버리기",
        "es": "Descartar",
        "fr": "Abandonner",
        "de": "Verwerfen",
        "pt-BR": "Descartar",
    },
    "prompts.generate.saved": {
        "en": "✅ Saved as '{name}'",
        "ja": "✅ '{name}' として保存しました",
        "zh-CN": "✅ 已保存为「{name}」",
        "ko": "✅ '{name}' 으로 저장됨",
        "es": "✅ Guardado como '{name}'",
        "fr": "✅ Enregistré sous « {name} »",
        "de": "✅ Als '{name}' gespeichert",
        "pt-BR": "✅ Salvo como '{name}'",
    },
    # ----- Browse & edit -----
    "prompts.browse.scope_hint": {
        "en": "Shows your **personal** prompts + **org-promoted** prompts + **distributed** prompts pushed to your user/role. Use any of them in **🎬 Run → 🛠 Skill** via the '📜 Load from saved prompts' expander.",
        "ja": "**個人** プロンプト + **組織昇格** プロンプト + あなた / あなたのロールに **配信されたプロンプト** がここに集約されます。利用は **🎬 Run → 🛠 Skill** の「📜 保存済プロンプトをロード」expander から。",
        "zh-CN": "显示**个人**提示词 + **组织晋升**提示词 + 推送给你/你角色的**已分发**提示词。在 **🎬 Run → 🛠 Skill** 的「📜 从已保存提示词加载」中使用。",
        "ko": "**개인** 프롬프트 + **조직 승격** 프롬프트 + 사용자/역할에 **배포된** 프롬프트가 여기 모입니다. **🎬 Run → 🛠 Skill** 의 「📜 저장된 프롬프트에서 로드」 에서 사용하세요.",
        "es": "Muestra prompts **personales** + **promovidos a org** + **distribuidos** a tu usuario/rol. Úsalos en **🎬 Run → 🛠 Skill** vía el expander 'Cargar desde prompts guardados'.",
        "fr": "Affiche les prompts **personnels** + **promus org** + **distribués** à votre utilisateur/rôle. Utilisation dans **🎬 Run → 🛠 Skill** via 'Charger un prompt enregistré'.",
        "de": "Zeigt **persönliche** + **org-beförderte** + an deinen Nutzer/Rolle **verteilte** Prompts. Nutzung unter **🎬 Run → 🛠 Skill** via 'Aus gespeicherten Prompts laden'.",
        "pt-BR": "Mostra prompts **pessoais** + **promovidos org** + **distribuídos** ao seu usuário/papel. Use em **🎬 Run → 🛠 Skill** via 'Carregar de prompts salvos'.",
    },
    "prompts.distribute.history_h": {
        "en": "📋 Currently shared",
        "ja": "📋 現在の共有状況",
        "zh-CN": "📋 当前分发情况",
        "ko": "📋 현재 배포 현황",
        "es": "📋 Distribuciones actuales",
        "fr": "📋 Distributions actuelles",
        "de": "📋 Aktuelle Verteilungen",
        "pt-BR": "📋 Distribuições atuais",
    },
    "prompts.distribute.history_intro": {
        "en": "Each row is one prompt copy under one target (a user_id or a role:name). Recipients see these in their Browse & edit tab tagged [distributed], and can load them in Run → Skill.",
        "ja": "1 行 = 1 プロンプトが 1 配信先 (user_id または role:name) に配置されたコピー。配信先のユーザは Browse & edit タブで [distributed] タグ付きで閲覧、Run → Skill で利用可能。",
        "zh-CN": "每行 = 一个提示词分发到一个目标(user_id 或 role:name)。接收者可在 Browse & edit 中看到 [distributed] 标签,在 Run → Skill 中加载使用。",
        "ko": "1 행 = 1 프롬프트가 1 대상 (user_id 또는 role:name) 에 배치된 사본. 수신자는 Browse & edit 에서 [distributed] 태그로 확인하고 Run → Skill 에서 로드 가능.",
        "es": "Cada fila = una copia del prompt bajo un objetivo (user_id o role:name). Los receptores los ven en Browse & edit con etiqueta [distributed] y pueden cargarlos en Run → Skill.",
        "fr": "Chaque ligne = une copie du prompt sous une cible (user_id ou role:name). Les destinataires les voient dans Browse & edit avec le tag [distributed] et peuvent les charger dans Run → Skill.",
        "de": "Jede Zeile = eine Prompt-Kopie unter einem Ziel (user_id oder role:name). Empfänger sehen sie in Browse & edit mit [distributed]-Tag und können sie in Run → Skill laden.",
        "pt-BR": "Cada linha = uma cópia do prompt sob um alvo (user_id ou role:name). Destinatários veem em Browse & edit com tag [distributed] e podem carregar em Run → Skill.",
    },
    "prompts.distribute.history_empty": {
        "en": "Nothing shared yet.",
        "ja": "まだ共有なし。",
        "zh-CN": "尚未分发任何内容。",
        "ko": "아직 배포 없음.",
        "es": "Aún no hay distribuciones.",
        "fr": "Aucune distribution pour l'instant.",
        "de": "Noch keine Verteilungen.",
        "pt-BR": "Nenhuma distribuição ainda.",
    },
    "prompts.browse.empty": {
        "en": "No prompts yet. Use the **Generate** tab to create one, or the **Create new prompt** form below to write one manually.",
        "ja": "プロンプト未登録。**生成** タブで作成、または下の **新規作成** フォームで手書き登録できます。",
        "zh-CN": "暂无提示词。使用 **生成** 标签创建,或下方 **新建** 表单手动编写。",
        "ko": "프롬프트 없음. **생성** 탭에서 만들거나 아래 **새 프롬프트** 폼에서 수동 작성하세요.",
        "es": "Sin prompts. Usa la pestaña **Generar** o el formulario **Nuevo prompt** de abajo.",
        "fr": "Aucun prompt. Utilisez l'onglet **Générer** ou le formulaire **Nouveau** ci-dessous.",
        "de": "Noch keine Prompts. Nutze den **Generieren**-Tab oder das **Neu**-Formular unten.",
        "pt-BR": "Sem prompts. Use a aba **Gerar** ou o formulário **Novo prompt** abaixo.",
    },
    "prompts.edit.body_label": {
        "en": "Prompt body",
        "ja": "プロンプト本文",
        "zh-CN": "提示词正文",
        "ko": "프롬프트 본문",
        "es": "Cuerpo del prompt",
        "fr": "Corps du prompt",
        "de": "Prompt-Inhalt",
        "pt-BR": "Corpo do prompt",
    },
    "prompts.edit.desc_label": {
        "en": "Description",
        "ja": "説明",
        "zh-CN": "描述",
        "ko": "설명",
        "es": "Descripción",
        "fr": "Description",
        "de": "Beschreibung",
        "pt-BR": "Descrição",
    },
    "prompts.edit.tags_label": {
        "en": "Tags (comma-separated)",
        "ja": "タグ (カンマ区切り)",
        "zh-CN": "标签(逗号分隔)",
        "ko": "태그 (쉼표 구분)",
        "es": "Etiquetas (separadas por coma)",
        "fr": "Tags (séparés par virgule)",
        "de": "Tags (kommagetrennt)",
        "pt-BR": "Tags (separadas por vírgula)",
    },
    "prompts.edit.save_btn": {
        "en": "💾 Save changes",
        "ja": "💾 変更を保存",
        "zh-CN": "💾 保存更改",
        "ko": "💾 변경 저장",
        "es": "💾 Guardar cambios",
        "fr": "💾 Enregistrer",
        "de": "💾 Änderungen speichern",
        "pt-BR": "💾 Salvar alterações",
    },
    "prompts.edit.delete_btn": {
        "en": "🗑 Delete prompt",
        "ja": "🗑 プロンプト削除",
        "zh-CN": "🗑 删除提示词",
        "ko": "🗑 프롬프트 삭제",
        "es": "🗑 Eliminar prompt",
        "fr": "🗑 Supprimer le prompt",
        "de": "🗑 Prompt löschen",
        "pt-BR": "🗑 Excluir prompt",
    },
    "prompts.edit.saved": {
        "en": "✅ Saved",
        "ja": "✅ 保存しました",
        "zh-CN": "✅ 已保存",
        "ko": "✅ 저장됨",
        "es": "✅ Guardado",
        "fr": "✅ Enregistré",
        "de": "✅ Gespeichert",
        "pt-BR": "✅ Salvo",
    },
    "prompts.edit.deleted": {
        "en": "🗑 Deleted",
        "ja": "🗑 削除しました",
        "zh-CN": "🗑 已删除",
        "ko": "🗑 삭제됨",
        "es": "🗑 Eliminado",
        "fr": "🗑 Supprimé",
        "de": "🗑 Gelöscht",
        "pt-BR": "🗑 Excluído",
    },
    "prompts.edit.readonly_hint": {
        "en": "Read-only — `{scope}` scope can't be edited from this view.",
        "ja": "読み取り専用 — `{scope}` スコープはこの画面から編集できません。",
        "zh-CN": "只读 — 此视图无法编辑 `{scope}` 范围。",
        "ko": "읽기 전용 — 이 뷰에서 `{scope}` 범위는 편집 불가.",
        "es": "Solo lectura — el ámbito `{scope}` no se edita aquí.",
        "fr": "Lecture seule — le scope `{scope}` n'est pas éditable ici.",
        "de": "Nur lesen — `{scope}`-Scope hier nicht editierbar.",
        "pt-BR": "Somente leitura — escopo `{scope}` não é editável aqui.",
    },
    # ----- Create new prompt -----
    "prompts.create.h": {
        "en": "✏️ Create a new prompt manually",
        "ja": "✏️ 新規プロンプト手動作成",
        "zh-CN": "✏️ 手动新建提示词",
        "ko": "✏️ 새 프롬프트 수동 생성",
        "es": "✏️ Crear nuevo prompt manualmente",
        "fr": "✏️ Créer un nouveau prompt manuellement",
        "de": "✏️ Neuen Prompt manuell erstellen",
        "pt-BR": "✏️ Criar novo prompt manualmente",
    },
    "prompts.create.name": {
        "en": "Name",
        "ja": "名前",
        "zh-CN": "名称",
        "ko": "이름",
        "es": "Nombre",
        "fr": "Nom",
        "de": "Name",
        "pt-BR": "Nome",
    },
    "prompts.create.desc": {
        "en": "Description",
        "ja": "説明",
        "zh-CN": "描述",
        "ko": "설명",
        "es": "Descripción",
        "fr": "Description",
        "de": "Beschreibung",
        "pt-BR": "Descrição",
    },
    "prompts.create.tags": {
        "en": "Tags (comma-separated)",
        "ja": "タグ (カンマ区切り)",
        "zh-CN": "标签(逗号分隔)",
        "ko": "태그 (쉼표 구분)",
        "es": "Etiquetas (separadas por coma)",
        "fr": "Tags (séparés par virgule)",
        "de": "Tags (kommagetrennt)",
        "pt-BR": "Tags (separadas por vírgula)",
    },
    "prompts.create.body": {
        "en": "Prompt body",
        "ja": "プロンプト本文",
        "zh-CN": "提示词正文",
        "ko": "프롬프트 본문",
        "es": "Cuerpo del prompt",
        "fr": "Corps du prompt",
        "de": "Prompt-Inhalt",
        "pt-BR": "Corpo do prompt",
    },
    "prompts.create.btn": {
        "en": "Create",
        "ja": "作成",
        "zh-CN": "创建",
        "ko": "생성",
        "es": "Crear",
        "fr": "Créer",
        "de": "Erstellen",
        "pt-BR": "Criar",
    },
    "prompts.create.required": {
        "en": "Name and body are required.",
        "ja": "名前と本文は必須です。",
        "zh-CN": "需要名称与正文。",
        "ko": "이름과 본문이 필요합니다.",
        "es": "Se requieren nombre y cuerpo.",
        "fr": "Nom et corps requis.",
        "de": "Name und Inhalt erforderlich.",
        "pt-BR": "Nome e corpo são obrigatórios.",
    },
    "prompts.create.saved": {
        "en": "✅ Created '{name}'",
        "ja": "✅ '{name}' を作成しました",
        "zh-CN": "✅ 已创建「{name}」",
        "ko": "✅ '{name}' 생성됨",
        "es": "✅ Creado '{name}'",
        "fr": "✅ « {name} » créé",
        "de": "✅ '{name}' erstellt",
        "pt-BR": "✅ '{name}' criado",
    },
    # ----- Distribute -----
    "prompts.distribute.intro": {
        "en": "**Admin only.** Share a curated prompt with specific users or roles.",
        "ja": "**管理者のみ。** 厳選プロンプトを特定ユーザまたはロールに共有。",
        "zh-CN": "**仅管理员。** 将精选提示推送给特定用户或角色。",
        "ko": "**관리자 전용.** 선별된 프롬프트를 특정 사용자/역할에 배포.",
        "es": "**Solo admin.** Empuja un prompt curado a usuarios o roles específicos.",
        "fr": "**Admin uniquement.** Pousse un prompt soigné vers des utilisateurs / rôles.",
        "de": "**Nur Admin.** Ausgewählten Prompt an Nutzer/Rollen verteilen.",
        "pt-BR": "**Apenas admin.** Envia um prompt curado para usuários/papéis.",
    },
    "prompts.distribute.role_required": {
        "en": "🚫 Sharing is admin-only. **{user}** has role `{role}` and can't share prompts with other users.",
        "ja": "🚫 共有は admin のみ。**{user}** のロールは `{role}` のため他ユーザへの共有不可。",
        "zh-CN": "🚫 分发仅 admin 可用。**{user}** 角色为 `{role}`,无法向其他用户分发。",
        "ko": "🚫 배포는 admin 만 가능. **{user}** 역할 `{role}` 이므로 다른 사용자에게 배포 불가.",
        "es": "🚫 La distribución es solo admin. **{user}** con rol `{role}` no puede distribuir.",
        "fr": "🚫 Distribution admin uniquement. **{user}** (rôle `{role}`) ne peut pas distribuer.",
        "de": "🚫 Verteilen nur für admin. **{user}** mit Rolle `{role}` darf nicht verteilen.",
        "pt-BR": "🚫 Distribuir apenas admin. **{user}** com papel `{role}` não pode distribuir.",
    },
    "prompts.distribute.target_users": {
        "en": "Target user IDs (comma-separated)",
        "ja": "対象ユーザ ID (カンマ区切り)",
        "zh-CN": "目标用户 ID(逗号分隔)",
        "ko": "대상 사용자 ID (쉼표 구분)",
        "es": "IDs de usuarios objetivo (coma)",
        "fr": "ID utilisateurs cibles (virgule)",
        "de": "Ziel-User-IDs (kommagetrennt)",
        "pt-BR": "IDs de usuários alvo (vírgula)",
    },
    "prompts.distribute.target_roles": {
        "en": "Target roles",
        "ja": "対象ロール",
        "zh-CN": "目标角色",
        "ko": "대상 역할",
        "es": "Roles objetivo",
        "fr": "Rôles cibles",
        "de": "Zielrollen",
        "pt-BR": "Papéis alvo",
    },
    "prompts.distribute.btn": {
        "en": "🤝 Share",
        "ja": "🤝 共有",
        "zh-CN": "🤝 共享",
        "ko": "🤝 공유",
        "es": "🤝 Compartir",
        "fr": "🤝 Partager",
        "de": "🤝 Teilen",
        "pt-BR": "🤝 Compartilhar",
    },
    "prompts.distribute.saved": {
        "en": "✅ Shared with {n} target(s)",
        "ja": "✅ {n} 件の対象に共有しました",
        "zh-CN": "✅ 已分发至 {n} 个目标",
        "ko": "✅ {n} 개 대상에 배포됨",
        "es": "✅ Distribuido a {n} objetivos",
        "fr": "✅ Distribué à {n} cibles",
        "de": "✅ An {n} Ziele verteilt",
        "pt-BR": "✅ Distribuído para {n} alvos",
    },
    # ===== About ============================================================
    "about.h": {
        "en": "ℹ About Praxia",
        "ja": "ℹ Praxia について",
        "zh-CN": "ℹ 关于 Praxia",
        "ko": "ℹ Praxia 정보",
        "es": "ℹ Acerca de Praxia",
        "fr": "ℹ À propos de Praxia",
        "de": "ℹ Über Praxia",
        "pt-BR": "ℹ Sobre Praxia",
    },
    "about.body": {
        "en": (
            "**Praxia** is a workflow-specialized multi-agent orchestrator "
            "that **automatically promotes** individual tacit knowledge "
            "into shared organizational know-how, via a **5-layer cyclic "
            "memory stack**.\n\n"
            "#### Supported LLMs (15+ first-class · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / o-series)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq fast / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 100+ more via LiteLLM\n\n"
            "Switch with one-line aliases (`claude` / `gpt-5` / `gemini` / ...) or "
            "`PRAXIA_LOCAL_MODEL=gemma` for air-gapped operation.\n\n"
            "#### Bundled business skills\n"
            "- Investment · Sales · Design · Purchasing · Patent · Legal\n\n"
            "#### LTM backends\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- Parallel fusion (RRF) or per-query routing for ensembles\n\n"
            "#### License\n"
            "Praxia ships under **Apache License 2.0** "
            "([LICENSE](https://github.com/praxia-dev/praxia/blob/main/LICENSE)). "
            "Third-party dependency licenses are inventoried in "
            "[NOTICE.md](https://github.com/praxia-dev/praxia/blob/main/NOTICE.md) — "
            "every direct + transitive dep, with its license and source URL.\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia)"
        ),
        "ja": (
            "**Praxia** は、業務特化型のマルチエージェント・オーケストレーターです。"
            "個人で利用するだけで暗黙知が自動蓄積され、有効なものだけが組織知へ昇格する"
            "**5層メモリ循環機構**を備えています。\n\n"
            "#### サポート LLM (15+ 標準 · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / o-series)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq fast / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 他、LiteLLM 経由で 100+\n\n"
            "1 行エイリアスで切替 (`claude` / `gpt-5` / `gemini` 等)、もしくは "
            "`PRAXIA_LOCAL_MODEL=gemma` でエアギャップ運用。\n\n"
            "#### 同梱業務スキル\n"
            "- 投資 / 営業 / 設計 / 購買 / 特許 / 法務\n\n"
            "#### LTM バックエンド\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- 並列融合 (RRF) または query-routing で複数併用可\n\n"
            "#### ライセンス\n"
            "Praxia は **Apache License 2.0** "
            "([LICENSE](https://github.com/praxia-dev/praxia/blob/main/LICENSE)) で配布。"
            "依存パッケージのライセンス一覧は "
            "[NOTICE.md](https://github.com/praxia-dev/praxia/blob/main/NOTICE.md) "
            "にすべて記載 (直接/間接依存、ライセンス、ソース URL)。\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia)"
        ),
        "zh-CN": (
            "**Praxia** 是面向特定工作流的多智能体编排器,通过 **5 层循环记忆栈** "
            "**自动提升** 个人隐性知识为组织共享 know-how。\n\n"
            "#### 支持的 LLM(15+ 一类 · 100+ via LiteLLM)\n"
            "- **Anthropic Claude**(Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT**(GPT-5 / o-series)\n"
            "- **Google Gemini** + **Gemma**(cloud + Ollama)\n"
            "- **Alibaba Qwen**(API + Ollama)\n"
            "- **DeepSeek**(V3 / R1 推理)· **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama**(Groq fast / Ollama)· **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- LiteLLM 还有 100+\n\n"
            "用一行别名切换(`claude` / `gpt-5` / `gemini` / ...),"
            "或 `PRAXIA_LOCAL_MODEL=gemma` 用于气隙环境。\n\n"
            "#### 内置业务技能\n"
            "- 投资 · 销售 · 设计 · 采购 · 专利 · 法务\n\n"
            "#### LTM 后端\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- 并行融合(RRF)或按查询路由,支持组合使用\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | License: Apache 2.0"
        ),
        "ko": (
            "**Praxia** 는 업무 특화 멀티 에이전트 오케스트레이터로, **5 층 순환 "
            "메모리 스택** 을 통해 개인의 암묵지를 조직 공유 노하우로 **자동 승격** 합니다.\n\n"
            "#### 지원 LLM (15+ 기본 · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / o-series)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq fast / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- LiteLLM 으로 100+ 추가\n\n"
            "한 줄 에이리어스로 전환 (`claude` / `gpt-5` / `gemini` / ...) 하거나, "
            "`PRAXIA_LOCAL_MODEL=gemma` 로 에어갭 운영.\n\n"
            "#### 동봉 비즈니스 스킬\n"
            "- 투자 · 영업 · 설계 · 구매 · 특허 · 법무\n\n"
            "#### LTM 백엔드\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- 병렬 융합 (RRF) 또는 쿼리별 라우팅으로 앙상블 가능\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | License: Apache 2.0"
        ),
        "es": (
            "**Praxia** es un orquestador multi-agente especializado en workflows que "
            "**promueve automáticamente** el conocimiento tácito individual al saber "
            "organizacional, mediante una **pila de memoria cíclica de 5 capas**.\n\n"
            "#### LLMs soportados (15+ primarios · 100+ vía LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / o-series)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq rápido / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 100+ más vía LiteLLM\n\n"
            "Cambia con alias de una línea (`claude` / `gpt-5` / `gemini` / ...) o "
            "`PRAXIA_LOCAL_MODEL=gemma` para operación air-gapped.\n\n"
            "#### Habilidades de negocio incluidas\n"
            "- Inversión · Ventas · Diseño · Compras · Patentes · Legal\n\n"
            "#### Backends LTM\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- Fusión paralela (RRF) o enrutamiento por consulta para ensambles\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | Licencia: Apache 2.0"
        ),
        "fr": (
            "**Praxia** est un orchestrateur multi-agents spécialisé par workflow qui "
            "**promeut automatiquement** la connaissance tacite individuelle en "
            "savoir-faire partagé de l'organisation, via une **pile mémoire cyclique "
            "à 5 couches**.\n\n"
            "#### LLMs supportés (15+ natifs · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / série o)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq fast / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 100+ via LiteLLM\n\n"
            "Basculez avec des alias d'une ligne (`claude` / `gpt-5` / `gemini` / ...) "
            "ou `PRAXIA_LOCAL_MODEL=gemma` pour un fonctionnement air-gapped.\n\n"
            "#### Compétences métiers incluses\n"
            "- Investissement · Ventes · Design · Achats · Brevets · Juridique\n\n"
            "#### Backends LTM\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- Fusion parallèle (RRF) ou routage par requête pour les ensembles\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | Licence : Apache 2.0"
        ),
        "de": (
            "**Praxia** ist ein workflow-spezialisierter Multi-Agenten-Orchestrator, "
            "der individuelles implizites Wissen über einen **5-schichtigen "
            "zyklischen Memory-Stack** **automatisch in geteiltes Org-Know-how "
            "befördert**.\n\n"
            "#### Unterstützte LLMs (15+ direkt · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / o-Serie)\n"
            "- **Google Gemini** + **Gemma** (Cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 Reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq fast / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 100+ weitere via LiteLLM\n\n"
            "Wechsle mit Einzeilen-Aliasen (`claude` / `gpt-5` / `gemini` / ...) oder "
            "`PRAXIA_LOCAL_MODEL=gemma` für Air-gapped-Betrieb.\n\n"
            "#### Mitgelieferte Business-Skills\n"
            "- Invest · Sales · Design · Einkauf · Patent · Legal\n\n"
            "#### LTM-Backends\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- Parallele Fusion (RRF) oder Routing pro Anfrage für Ensembles\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | Lizenz: Apache 2.0"
        ),
        "pt-BR": (
            "**Praxia** é um orquestrador multi-agente especializado em workflows que "
            "**promove automaticamente** o conhecimento tácito individual em know-how "
            "organizacional compartilhado, via uma **pilha cíclica de memória de 5 "
            "camadas**.\n\n"
            "#### LLMs suportados (15+ primários · 100+ via LiteLLM)\n"
            "- **Anthropic Claude** (Opus / Sonnet / Haiku)\n"
            "- **OpenAI ChatGPT** (GPT-5 / série o)\n"
            "- **Google Gemini** + **Gemma** (cloud + Ollama)\n"
            "- **Alibaba Qwen** (API + Ollama)\n"
            "- **DeepSeek** (V3 / R1 reasoning) · **Mistral** + **Codestral**\n"
            "- **xAI Grok** · **Meta Llama** (Groq rápido / Ollama) · **Microsoft Phi**\n"
            "- **Cohere Command R+** · **Perplexity Sonar**\n"
            "- 100+ via LiteLLM\n\n"
            "Troque com aliases de uma linha (`claude` / `gpt-5` / `gemini` / ...) ou "
            "`PRAXIA_LOCAL_MODEL=gemma` para operação air-gapped.\n\n"
            "#### Habilidades de negócio incluídas\n"
            "- Investimento · Vendas · Design · Compras · Patentes · Jurídico\n\n"
            "#### Backends LTM\n"
            "- Mem0 / LangMem / Letta / Zep / HindSight / JSON\n"
            "- Fusão paralela (RRF) ou roteamento por consulta para ensembles\n\n"
            "[GitHub](https://github.com/praxia-dev/praxia) | Licença: Apache 2.0"
        ),
    },
    "tab.run_flow": {
        "en": "🎬 Run Flow",
        "ja": "🎬 フロー実行",
        "zh-CN": "🎬 运行流程",
        "ko": "🎬 플로우 실행",
        "es": "🎬 Ejecutar Flujo",
        "fr": "🎬 Lancer Flux",
        "de": "🎬 Flow Ausführen",
        "pt-BR": "🎬 Executar Fluxo",
    },
    "tab.skill": {
        "en": "🛠 Skill",
        "ja": "🛠 スキル",
        "zh-CN": "🛠 技能",
        "ko": "🛠 스킬",
        "es": "🛠 Habilidad",
        "fr": "🛠 Compétence",
        "de": "🛠 Skill",
        "pt-BR": "🛠 Habilidade",
    },
    "tab.memory": {
        "en": "🧠 Memory",
        "ja": "🧠 メモリ",
        "zh-CN": "🧠 记忆",
        "ko": "🧠 메모리",
        "es": "🧠 Memoria",
        "fr": "🧠 Mémoire",
        "de": "🧠 Speicher",
        "pt-BR": "🧠 Memória",
    },
    "tab.consolidate": {
        "en": "🌙 Consolidate",
        "ja": "🌙 統合",
        "zh-CN": "🌙 整合",
        "ko": "🌙 통합",
        "es": "🌙 Consolidar",
        "fr": "🌙 Consolider",
        "de": "🌙 Konsolidieren",
        "pt-BR": "🌙 Consolidar",
    },
    "tab.dashboard": {
        "en": "📊 Dashboard",
        "ja": "📊 ダッシュボード",
        "zh-CN": "📊 仪表板",
        "ko": "📊 대시보드",
        "es": "📊 Panel",
        "fr": "📊 Tableau de bord",
        "de": "📊 Dashboard",
        "pt-BR": "📊 Painel",
    },
    "tab.prompts": {
        "en": "📝 Prompts",
        "ja": "📝 プロンプト",
        "zh-CN": "📝 提示",
        "ko": "📝 프롬프트",
        "es": "📝 Prompts",
        "fr": "📝 Prompts",
        "de": "📝 Prompts",
        "pt-BR": "📝 Prompts",
    },
    "tab.users": {
        "en": "👥 Users",
        "ja": "👥 ユーザ",
        "zh-CN": "👥 用户",
        "ko": "👥 사용자",
        "es": "👥 Usuarios",
        "fr": "👥 Utilisateurs",
        "de": "👥 Benutzer",
        "pt-BR": "👥 Usuários",
    },
    "tab.connectors": {
        "en": "🔌 Connectors",
        "ja": "🔌 コネクタ",
        "zh-CN": "🔌 连接器",
        "ko": "🔌 커넥터",
        "es": "🔌 Conectores",
        "fr": "🔌 Connecteurs",
        "de": "🔌 Konnektoren",
        "pt-BR": "🔌 Conectores",
    },
    "tab.policies": {
        "en": "🛡 Policies",
        "ja": "🛡 ポリシー",
        "zh-CN": "🛡 策略",
        "ko": "🛡 정책",
        "es": "🛡 Políticas",
        "fr": "🛡 Politiques",
        "de": "🛡 Richtlinien",
        "pt-BR": "🛡 Políticas",
    },
    "tab.admin": {
        "en": "💾 Admin",
        "ja": "💾 管理",
        "zh-CN": "💾 管理",
        "ko": "💾 관리",
        "es": "💾 Admin",
        "fr": "💾 Admin",
        "de": "💾 Admin",
        "pt-BR": "💾 Admin",
    },
    "tab.about": {
        "en": "ℹ About",
        "ja": "ℹ 情報",
        "zh-CN": "ℹ 关于",
        "ko": "ℹ 정보",
        "es": "ℹ Acerca de",
        "fr": "ℹ À propos",
        "de": "ℹ Info",
        "pt-BR": "ℹ Sobre",
    },
    # ===== Admin tab (settings + downloads) =================================
    "admin.header": {
        "en": "💾 Admin",
        "ja": "💾 管理",
        "zh-CN": "💾 管理",
        "ko": "💾 관리",
        "es": "💾 Admin",
        "fr": "💾 Admin",
        "de": "💾 Admin",
        "pt-BR": "💾 Admin",
    },
    "admin.settings.subtab": {
        "en": "🔑 Settings",
        "ja": "🔑 設定",
        "zh-CN": "🔑 设置",
        "ko": "🔑 설정",
        "es": "🔑 Ajustes",
        "fr": "🔑 Paramètres",
        "de": "🔑 Einstellungen",
        "pt-BR": "🔑 Ajustes",
    },
    "admin.downloads.subtab": {
        "en": "💾 Exports",
        "ja": "💾 エクスポート",
        "zh-CN": "💾 导出",
        "ko": "💾 내보내기",
        "es": "💾 Exportar",
        "fr": "💾 Exports",
        "de": "💾 Exporte",
        "pt-BR": "💾 Exportar",
    },
    "admin.users.subtab": {
        "en": "👥 Users",
        "ja": "👥 ユーザ",
        "zh-CN": "👥 用户",
        "ko": "👥 사용자",
        "es": "👥 Usuarios",
        "fr": "👥 Utilisateurs",
        "de": "👥 Nutzer",
        "pt-BR": "👥 Usuários",
    },
    "admin.connectors.subtab": {
        "en": "🔌 Connectors",
        "ja": "🔌 コネクタ",
        "zh-CN": "🔌 连接器",
        "ko": "🔌 커넥터",
        "es": "🔌 Conectores",
        "fr": "🔌 Connecteurs",
        "de": "🔌 Konnektoren",
        "pt-BR": "🔌 Conectores",
    },
    "admin.policies.subtab": {
        "en": "🛡 Policies",
        "ja": "🛡 ポリシー",
        "zh-CN": "🛡 策略",
        "ko": "🛡 정책",
        "es": "🛡 Políticas",
        "fr": "🛡 Politiques",
        "de": "🛡 Richtlinien",
        "pt-BR": "🛡 Políticas",
    },
    "admin.policies.header": {
        "en": "🛡 Resource Access Policies",
        "ja": "🛡 リソースアクセスポリシー",
        "zh-CN": "🛡 资源访问策略",
        "ko": "🛡 리소스 액세스 정책",
        "es": "🛡 Políticas de Acceso a Recursos",
        "fr": "🛡 Politiques d'Accès aux Ressources",
        "de": "🛡 Ressourcen-Zugriffsrichtlinien",
        "pt-BR": "🛡 Políticas de Acesso a Recursos",
    },
    "admin.policies.intro": {
        "en": "Control which users / roles can access connector paths, memory namespaces, prompts, and skills. Designed for enterprise IS departments.",
        "ja": "コネクタパス・メモリ名前空間・プロンプト・スキルへのアクセスを、ユーザ / ロール単位で制御します。エンタープライズの情報システム部門向けの機能です。",
        "zh-CN": "按用户 / 角色控制对连接器路径、内存命名空间、提示词和技能的访问。面向企业 IT 部门。",
        "ko": "커넥터 경로, 메모리 네임스페이스, 프롬프트, 스킬에 대한 사용자/역할별 접근을 제어합니다. 엔터프라이즈 IT 부서를 위한 기능입니다.",
        "es": "Controla qué usuarios / roles pueden acceder a rutas de conectores, espacios de nombres de memoria, prompts y skills. Diseñado para departamentos de TI empresariales.",
        "fr": "Contrôle quels utilisateurs / rôles peuvent accéder aux chemins des connecteurs, aux espaces de noms mémoire, aux prompts et aux skills. Conçu pour les départements informatiques d'entreprise.",
        "de": "Steuert, welche Benutzer / Rollen auf Connector-Pfade, Memory-Namespaces, Prompts und Skills zugreifen können. Konzipiert für IT-Abteilungen von Unternehmen.",
        "pt-BR": "Controla quais usuários / papéis podem acessar caminhos de conectores, namespaces de memória, prompts e skills. Projetado para departamentos de TI corporativos.",
    },
    "admin.policies.sub_list": {
        "en": "List", "ja": "一覧", "zh-CN": "列表", "ko": "목록",
        "es": "Listar", "fr": "Liste", "de": "Liste", "pt-BR": "Listar",
    },
    "admin.policies.sub_add": {
        "en": "Add", "ja": "追加", "zh-CN": "添加", "ko": "추가",
        "es": "Añadir", "fr": "Ajouter", "de": "Hinzufügen", "pt-BR": "Adicionar",
    },
    "admin.policies.sub_test": {
        "en": "Test", "ja": "評価テスト", "zh-CN": "评估测试", "ko": "평가 테스트",
        "es": "Probar", "fr": "Tester", "de": "Testen", "pt-BR": "Testar",
    },
    "admin.policies.remove_select_h": {
        "en": "Remove policy by ID",
        "ja": "ID 指定でポリシーを削除",
        "zh-CN": "按 ID 删除策略",
        "ko": "ID로 정책 삭제",
        "es": "Eliminar política por ID",
        "fr": "Supprimer la politique par ID",
        "de": "Richtlinie nach ID entfernen",
        "pt-BR": "Remover política por ID",
    },
    "admin.policies.remove_placeholder": {
        "en": "(select)", "ja": "(選択)", "zh-CN": "(选择)", "ko": "(선택)",
        "es": "(seleccionar)", "fr": "(sélectionner)", "de": "(auswählen)", "pt-BR": "(selecionar)",
    },
    "admin.policies.remove_btn": {
        "en": "🗑 Remove selected",
        "ja": "🗑 選択したポリシーを削除",
        "zh-CN": "🗑 删除所选",
        "ko": "🗑 선택 항목 삭제",
        "es": "🗑 Eliminar seleccionado",
        "fr": "🗑 Supprimer la sélection",
        "de": "🗑 Auswahl entfernen",
        "pt-BR": "🗑 Remover selecionado",
    },
    "admin.policies.removed_ok": {
        "en": "Removed {id_short}",
        "ja": "削除しました: {id_short}",
        "zh-CN": "已删除 {id_short}",
        "ko": "삭제됨: {id_short}",
        "es": "Eliminado: {id_short}",
        "fr": "Supprimé : {id_short}",
        "de": "Entfernt: {id_short}",
        "pt-BR": "Removido: {id_short}",
    },
    "admin.policies.empty": {
        "en": "No policies yet. Defaults to 'allow' when no policy matches.",
        "ja": "ポリシー未登録。マッチするポリシーが無い場合は 'allow' がデフォルトです。",
        "zh-CN": "尚无策略。无匹配策略时默认为 'allow'。",
        "ko": "정책 없음. 일치하는 정책이 없을 때는 기본값 'allow' 입니다.",
        "es": "Aún no hay políticas. Por defecto 'allow' cuando ninguna política coincide.",
        "fr": "Aucune politique. 'allow' par défaut si aucune politique ne correspond.",
        "de": "Noch keine Richtlinien. Standard ist 'allow', wenn keine Richtlinie zutrifft.",
        "pt-BR": "Ainda sem políticas. Padrão 'allow' quando nenhuma política coincide.",
    },
    "admin.policies.add.effect": {
        "en": "Effect", "ja": "効果", "zh-CN": "效果", "ko": "효과",
        "es": "Efecto", "fr": "Effet", "de": "Effekt", "pt-BR": "Efeito",
    },
    "admin.policies.add.resource_type": {
        "en": "Resource type",
        "ja": "リソース種別",
        "zh-CN": "资源类型",
        "ko": "리소스 유형",
        "es": "Tipo de recurso",
        "fr": "Type de ressource",
        "de": "Ressourcentyp",
        "pt-BR": "Tipo de recurso",
    },
    "admin.policies.add.pattern": {
        "en": "Resource pattern (glob)",
        "ja": "リソースパターン (glob)",
        "zh-CN": "资源模式 (glob)",
        "ko": "리소스 패턴 (glob)",
        "es": "Patrón de recurso (glob)",
        "fr": "Motif de ressource (glob)",
        "de": "Ressourcenmuster (glob)",
        "pt-BR": "Padrão de recurso (glob)",
    },
    "admin.policies.add.actions": {
        "en": "Actions", "ja": "アクション", "zh-CN": "操作", "ko": "작업",
        "es": "Acciones", "fr": "Actions", "de": "Aktionen", "pt-BR": "Ações",
    },
    "admin.policies.add.principals": {
        "en": "Principals (comma-separated user_ids and role:<name>)",
        "ja": "プリンシパル (user_id とロールをカンマ区切り。例: alice, role:admin)",
        "zh-CN": "主体 (逗号分隔的 user_id 和 role:<name>)",
        "ko": "주체 (쉼표로 구분된 user_id 및 role:<이름>)",
        "es": "Principales (user_ids y role:<nombre> separados por comas)",
        "fr": "Principaux (user_ids et role:<nom> séparés par des virgules)",
        "de": "Principals (kommagetrennte user_ids und role:<name>)",
        "pt-BR": "Principais (user_ids e role:<nome> separados por vírgula)",
    },
    "admin.policies.add.description": {
        "en": "Description", "ja": "説明", "zh-CN": "说明", "ko": "설명",
        "es": "Descripción", "fr": "Description", "de": "Beschreibung", "pt-BR": "Descrição",
    },
    "admin.policies.add.submit": {
        "en": "Add policy",
        "ja": "ポリシーを追加",
        "zh-CN": "添加策略",
        "ko": "정책 추가",
        "es": "Añadir política",
        "fr": "Ajouter la politique",
        "de": "Richtlinie hinzufügen",
        "pt-BR": "Adicionar política",
    },
    "admin.policies.add.added": {
        "en": "Added policy {id_short}",
        "ja": "ポリシーを追加しました: {id_short}",
        "zh-CN": "已添加策略 {id_short}",
        "ko": "정책 추가됨: {id_short}",
        "es": "Política añadida: {id_short}",
        "fr": "Politique ajoutée : {id_short}",
        "de": "Richtlinie hinzugefügt: {id_short}",
        "pt-BR": "Política adicionada: {id_short}",
    },
    "admin.policies.test.user_id": {
        "en": "user_id", "ja": "ユーザ ID (user_id)",
        "zh-CN": "user_id", "ko": "user_id",
        "es": "user_id", "fr": "user_id", "de": "user_id", "pt-BR": "user_id",
    },
    "admin.policies.test.role": {
        "en": "role", "ja": "ロール", "zh-CN": "角色", "ko": "역할",
        "es": "rol", "fr": "rôle", "de": "Rolle", "pt-BR": "papel",
    },
    "admin.policies.test.resource_type": {
        "en": "resource_type",
        "ja": "リソース種別",
        "zh-CN": "资源类型",
        "ko": "리소스 유형",
        "es": "tipo de recurso",
        "fr": "type de ressource",
        "de": "Ressourcentyp",
        "pt-BR": "tipo de recurso",
    },
    "admin.policies.test.resource_id": {
        "en": "resource_id",
        "ja": "リソース ID",
        "zh-CN": "资源 ID",
        "ko": "리소스 ID",
        "es": "id de recurso",
        "fr": "id de ressource",
        "de": "Ressourcen-ID",
        "pt-BR": "id do recurso",
    },
    "admin.policies.test.action": {
        "en": "action", "ja": "アクション", "zh-CN": "操作", "ko": "작업",
        "es": "acción", "fr": "action", "de": "Aktion", "pt-BR": "ação",
    },
    "admin.policies.test.submit": {
        "en": "Evaluate", "ja": "評価実行", "zh-CN": "评估", "ko": "평가",
        "es": "Evaluar", "fr": "Évaluer", "de": "Auswerten", "pt-BR": "Avaliar",
    },
    "admin.policies.test.allowed": {
        "en": "✅ Allowed — {reason}",
        "ja": "✅ 許可 — {reason}",
        "zh-CN": "✅ 允许 — {reason}",
        "ko": "✅ 허용 — {reason}",
        "es": "✅ Permitido — {reason}",
        "fr": "✅ Autorisé — {reason}",
        "de": "✅ Erlaubt — {reason}",
        "pt-BR": "✅ Permitido — {reason}",
    },
    "admin.policies.test.denied": {
        "en": "🚫 Denied — {reason}",
        "ja": "🚫 拒否 — {reason}",
        "zh-CN": "🚫 拒绝 — {reason}",
        "ko": "🚫 거부 — {reason}",
        "es": "🚫 Denegado — {reason}",
        "fr": "🚫 Refusé — {reason}",
        "de": "🚫 Verweigert — {reason}",
        "pt-BR": "🚫 Negado — {reason}",
    },
    "admin.about.subtab": {
        "en": "ℹ About",
        "ja": "ℹ 情報",
        "zh-CN": "ℹ 关于",
        "ko": "ℹ 정보",
        "es": "ℹ Acerca de",
        "fr": "ℹ À propos",
        "de": "ℹ Info",
        "pt-BR": "ℹ Sobre",
    },
    "admin.credentials.subtab": {
        "en": "🔐 Credentials",
        "ja": "🔐 認証情報",
        "zh-CN": "🔐 凭据",
        "ko": "🔐 자격 증명",
        "es": "🔐 Credenciales",
        "fr": "🔐 Identifiants",
        "de": "🔐 Anmeldedaten",
        "pt-BR": "🔐 Credenciais",
    },
    "admin.credentials.intro": {
        "en": "Persistent API keys and service credentials. Saved to `.praxia/config.toml` and mirrored to `os.environ` for libraries (LiteLLM, OpenAI SDK, etc.) that read env vars directly. Sub-tabs group related credentials together.",
        "ja": "永続化される API キーとサービス認証情報です。`.praxia/config.toml` に保存され、LiteLLM / OpenAI SDK など環境変数を直接読むライブラリ向けに `os.environ` にもミラーされます。関連する認証情報はサブタブごとにまとまっています。",
        "zh-CN": "持久化的 API 密钥和服务凭据。保存到 `.praxia/config.toml` 并镜像到 `os.environ`,供直接读取环境变量的库 (LiteLLM、OpenAI SDK 等) 使用。相关凭据按子标签分组。",
        "ko": "영구 저장되는 API 키와 서비스 자격 증명입니다. `.praxia/config.toml`에 저장되며 LiteLLM / OpenAI SDK 등 환경 변수를 직접 읽는 라이브러리를 위해 `os.environ`에도 미러됩니다. 관련 자격 증명은 하위 탭으로 그룹화됩니다.",
        "es": "API keys y credenciales de servicio persistentes. Se guardan en `.praxia/config.toml` y se reflejan en `os.environ` para las librerías (LiteLLM, OpenAI SDK, etc.) que leen variables de entorno directamente. Las sub-pestañas agrupan credenciales relacionadas.",
        "fr": "Clés API et identifiants de service persistants. Enregistrés dans `.praxia/config.toml` et reflétés dans `os.environ` pour les bibliothèques (LiteLLM, OpenAI SDK, etc.) qui lisent directement les variables d'environnement. Les sous-onglets regroupent les identifiants associés.",
        "de": "Persistente API-Schlüssel und Service-Anmeldedaten. Werden in `.praxia/config.toml` gespeichert und in `os.environ` gespiegelt, damit Bibliotheken (LiteLLM, OpenAI SDK usw.), die Umgebungsvariablen direkt lesen, sie finden. Unter-Tabs gruppieren zusammengehörige Anmeldedaten.",
        "pt-BR": "API keys e credenciais de serviço persistentes. Salvas em `.praxia/config.toml` e espelhadas em `os.environ` para bibliotecas (LiteLLM, OpenAI SDK, etc.) que leem variáveis de ambiente diretamente. As sub-abas agrupam credenciais relacionadas.",
    },
    "admin.connections.subtab": {
        "en": "🔗 Service Connections",
        "ja": "🔗 外部サービス連携",
        "zh-CN": "🔗 外部服务集成",
        "ko": "🔗 외부 서비스 연동",
        "es": "🔗 Conexiones de Servicio",
        "fr": "🔗 Connexions de Service",
        "de": "🔗 Dienstverbindungen",
        "pt-BR": "🔗 Conexões de Serviço",
    },
    "admin.connections.intro": {
        "en": "Connect your own account to external systems (Box / Microsoft 365 / Google Drive / kintone / Slack / etc.) via OAuth. Each Praxia user authenticates with their own credentials, so each external system's native ACL is enforced **per-user** — you only see files/records the external system grants to your account.",
        "ja": "OAuth で外部システム (Box / Microsoft 365 / Google Drive / kintone / Slack など) へ自分のアカウントで接続します。各 Praxia ユーザは自分の資格情報で認証するため、外部システム側の ACL が**ユーザ単位**で適用されます — 接続先側で自分のアカウントに許可されたファイル/レコードのみアクセスできます。",
        "zh-CN": "通过 OAuth 用您自己的账户连接外部系统 (Box / Microsoft 365 / Google Drive / kintone / Slack 等)。每个 Praxia 用户使用自己的凭据进行认证,因此外部系统的原生 ACL 按**用户**强制执行 — 您只能看到外部系统授予您账户访问权限的文件/记录。",
        "ko": "OAuth로 외부 시스템 (Box / Microsoft 365 / Google Drive / kintone / Slack 등)에 자신의 계정으로 연결합니다. 각 Praxia 사용자는 자신의 자격 증명으로 인증하므로 외부 시스템의 ACL이 **사용자별로** 적용됩니다 — 외부 시스템이 본인 계정에 허용한 파일/레코드만 액세스할 수 있습니다.",
        "es": "Conecta tu propia cuenta a sistemas externos (Box / Microsoft 365 / Google Drive / kintone / Slack / etc.) mediante OAuth. Cada usuario de Praxia se autentica con sus propias credenciales, por lo que el ACL nativo de cada sistema externo se aplica **por usuario** — solo ves los archivos/registros que el sistema externo concede a tu cuenta.",
        "fr": "Connectez votre propre compte à des systèmes externes (Box / Microsoft 365 / Google Drive / kintone / Slack / etc.) via OAuth. Chaque utilisateur Praxia s'authentifie avec ses propres identifiants, donc l'ACL natif de chaque système externe est appliqué **par utilisateur** — vous ne voyez que les fichiers/enregistrements que le système externe accorde à votre compte.",
        "de": "Verbinden Sie Ihr eigenes Konto via OAuth mit externen Systemen (Box / Microsoft 365 / Google Drive / kintone / Slack / usw.). Jeder Praxia-Benutzer authentifiziert sich mit eigenen Anmeldedaten, sodass die native ACL jedes externen Systems **pro Benutzer** durchgesetzt wird — Sie sehen nur die Dateien/Datensätze, die das externe System Ihrem Konto gewährt.",
        "pt-BR": "Conecte sua própria conta a sistemas externos (Box / Microsoft 365 / Google Drive / kintone / Slack / etc.) via OAuth. Cada usuário do Praxia autentica com suas próprias credenciais, então a ACL nativa de cada sistema externo é aplicada **por usuário** — você só vê os arquivos/registros que o sistema externo concede à sua conta.",
    },
    "admin.connections.status_connected": {
        "en": "✅ Connected", "ja": "✅ 接続済み", "zh-CN": "✅ 已连接", "ko": "✅ 연결됨",
        "es": "✅ Conectado", "fr": "✅ Connecté", "de": "✅ Verbunden", "pt-BR": "✅ Conectado",
    },
    "admin.connections.status_disconnected": {
        "en": "⚪ Not connected", "ja": "⚪ 未接続", "zh-CN": "⚪ 未连接", "ko": "⚪ 연결 안 됨",
        "es": "⚪ No conectado", "fr": "⚪ Non connecté", "de": "⚪ Nicht verbunden", "pt-BR": "⚪ Não conectado",
    },
    "admin.connections.status_expired": {
        "en": "⚠️ Token expired", "ja": "⚠️ トークン期限切れ", "zh-CN": "⚠️ 令牌已过期", "ko": "⚠️ 토큰 만료",
        "es": "⚠️ Token caducado", "fr": "⚠️ Jeton expiré", "de": "⚠️ Token abgelaufen", "pt-BR": "⚠️ Token expirado",
    },
    "admin.connections.scope": {
        "en": "Scopes", "ja": "スコープ", "zh-CN": "授权范围", "ko": "범위",
        "es": "Alcances", "fr": "Portées", "de": "Geltungsbereiche", "pt-BR": "Escopos",
    },
    "admin.connections.connect_btn": {
        "en": "🔗 Connect", "ja": "🔗 接続する", "zh-CN": "🔗 连接", "ko": "🔗 연결",
        "es": "🔗 Conectar", "fr": "🔗 Connecter", "de": "🔗 Verbinden", "pt-BR": "🔗 Conectar",
    },
    "admin.connections.disconnect_btn": {
        "en": "🚪 Disconnect", "ja": "🚪 切断", "zh-CN": "🚪 断开连接", "ko": "🚪 연결 해제",
        "es": "🚪 Desconectar", "fr": "🚪 Déconnecter", "de": "🚪 Trennen", "pt-BR": "🚪 Desconectar",
    },
    "admin.connections.refresh_btn": {
        "en": "🔄 Refresh status", "ja": "🔄 状態を更新", "zh-CN": "🔄 刷新状态", "ko": "🔄 상태 새로 고침",
        "es": "🔄 Actualizar estado", "fr": "🔄 Rafraîchir l'état", "de": "🔄 Status aktualisieren", "pt-BR": "🔄 Atualizar status",
    },
    "admin.connections.client_missing": {
        "en": "OAuth app not configured. Ask your admin to set the client_id / client_secret under **Credentials → OAuth Apps**.",
        "ja": "OAuth アプリ未設定です。管理者に **認証情報 → OAuth アプリ** で client_id / client_secret を登録してもらってください。",
        "zh-CN": "未配置 OAuth 应用。请管理员在 **凭据 → OAuth 应用** 中设置 client_id / client_secret。",
        "ko": "OAuth 앱이 설정되지 않았습니다. 관리자에게 **자격 증명 → OAuth 앱**에서 client_id / client_secret을 설정하도록 요청하세요.",
        "es": "Aplicación OAuth no configurada. Pídele al administrador que defina client_id / client_secret en **Credenciales → Apps OAuth**.",
        "fr": "Application OAuth non configurée. Demandez à votre administrateur de définir client_id / client_secret dans **Identifiants → Apps OAuth**.",
        "de": "OAuth-App nicht konfiguriert. Bitten Sie Ihren Administrator, client_id / client_secret unter **Anmeldedaten → OAuth-Apps** zu setzen.",
        "pt-BR": "App OAuth não configurado. Peça ao administrador para definir client_id / client_secret em **Credenciais → Apps OAuth**.",
    },
    "admin.connections.serve_required": {
        "en": "ℹ Per-user OAuth requires the FastAPI server (`praxia serve`) to capture the IdP callback. Start it in another terminal with `praxia serve --port 8000` and set `PRAXIA_PUBLIC_URL=http://localhost:8000` in the env.",
        "ja": "ℹ ユーザ単位 OAuth は IdP コールバック受信のため FastAPI サーバ (`praxia serve`) が必要です。別ターミナルで `praxia serve --port 8000` を起動し、環境変数 `PRAXIA_PUBLIC_URL=http://localhost:8000` を設定してください。",
        "zh-CN": "ℹ 用户级 OAuth 需要 FastAPI 服务器 (`praxia serve`) 来捕获 IdP 回调。在另一个终端启动 `praxia serve --port 8000` 并在环境中设置 `PRAXIA_PUBLIC_URL=http://localhost:8000`。",
        "ko": "ℹ 사용자별 OAuth는 IdP 콜백 캡처를 위해 FastAPI 서버 (`praxia serve`)가 필요합니다. 다른 터미널에서 `praxia serve --port 8000`을 시작하고 환경 변수 `PRAXIA_PUBLIC_URL=http://localhost:8000`을 설정하세요.",
        "es": "ℹ El OAuth por usuario requiere el servidor FastAPI (`praxia serve`) para capturar el callback del IdP. Inícialo en otra terminal con `praxia serve --port 8000` y define `PRAXIA_PUBLIC_URL=http://localhost:8000` en el entorno.",
        "fr": "ℹ L'OAuth par utilisateur nécessite le serveur FastAPI (`praxia serve`) pour capturer le rappel de l'IdP. Lancez-le dans un autre terminal avec `praxia serve --port 8000` et définissez `PRAXIA_PUBLIC_URL=http://localhost:8000` dans l'environnement.",
        "de": "ℹ Pro-Benutzer-OAuth erfordert den FastAPI-Server (`praxia serve`), um den IdP-Callback zu erfassen. Starten Sie ihn in einem anderen Terminal mit `praxia serve --port 8000` und setzen Sie `PRAXIA_PUBLIC_URL=http://localhost:8000` in der Umgebung.",
        "pt-BR": "ℹ O OAuth por usuário requer o servidor FastAPI (`praxia serve`) para capturar o callback do IdP. Inicie-o em outro terminal com `praxia serve --port 8000` e defina `PRAXIA_PUBLIC_URL=http://localhost:8000` no ambiente.",
    },
    # --- Users tab ---
    "admin.users.header": {
        "en": "👥 User Management (admin)",
        "ja": "👥 ユーザ管理 (admin)",
        "zh-CN": "👥 用户管理 (admin)",
        "ko": "👥 사용자 관리 (admin)",
        "es": "👥 Gestión de Usuarios (admin)",
        "fr": "👥 Gestion des Utilisateurs (admin)",
        "de": "👥 Benutzerverwaltung (admin)",
        "pt-BR": "👥 Gerenciamento de Usuários (admin)",
    },
    "admin.users.sub_list": {
        "en": "List", "ja": "一覧", "zh-CN": "列表", "ko": "목록",
        "es": "Listar", "fr": "Liste", "de": "Liste", "pt-BR": "Listar",
    },
    "admin.users.sub_create": {
        "en": "Create", "ja": "新規作成", "zh-CN": "创建", "ko": "생성",
        "es": "Crear", "fr": "Créer", "de": "Erstellen", "pt-BR": "Criar",
    },
    "admin.users.sub_edit": {
        "en": "Edit / Delete", "ja": "編集 / 削除", "zh-CN": "编辑 / 删除", "ko": "편집 / 삭제",
        "es": "Editar / Eliminar", "fr": "Éditer / Supprimer", "de": "Bearbeiten / Löschen", "pt-BR": "Editar / Excluir",
    },
    "admin.users.col_username": {
        "en": "username", "ja": "ユーザ名", "zh-CN": "用户名", "ko": "사용자명",
        "es": "usuario", "fr": "utilisateur", "de": "Benutzername", "pt-BR": "usuário",
    },
    "admin.users.col_role": {
        "en": "role", "ja": "ロール", "zh-CN": "角色", "ko": "역할",
        "es": "rol", "fr": "rôle", "de": "Rolle", "pt-BR": "papel",
    },
    "admin.users.col_email": {
        "en": "email", "ja": "メール", "zh-CN": "邮箱", "ko": "이메일",
        "es": "correo", "fr": "courriel", "de": "E-Mail", "pt-BR": "e-mail",
    },
    "admin.users.col_active": {
        "en": "active", "ja": "有効", "zh-CN": "启用", "ko": "활성",
        "es": "activo", "fr": "actif", "de": "aktiv", "pt-BR": "ativo",
    },
    "admin.users.empty": {
        "en": "No users yet.",
        "ja": "ユーザがまだ登録されていません。",
        "zh-CN": "尚无用户。",
        "ko": "사용자가 없습니다.",
        "es": "Aún no hay usuarios.",
        "fr": "Aucun utilisateur pour l'instant.",
        "de": "Noch keine Benutzer.",
        "pt-BR": "Ainda sem usuários.",
    },
    "admin.users.username_label": {
        "en": "Username", "ja": "ユーザ名", "zh-CN": "用户名", "ko": "사용자명",
        "es": "Usuario", "fr": "Utilisateur", "de": "Benutzername", "pt-BR": "Usuário",
    },
    "admin.users.role_label": {
        "en": "Role", "ja": "ロール", "zh-CN": "角色", "ko": "역할",
        "es": "Rol", "fr": "Rôle", "de": "Rolle", "pt-BR": "Papel",
    },
    "admin.users.email_label": {
        "en": "Email", "ja": "メールアドレス", "zh-CN": "邮箱", "ko": "이메일",
        "es": "Correo", "fr": "Courriel", "de": "E-Mail", "pt-BR": "E-mail",
    },
    "admin.users.create_btn": {
        "en": "Create", "ja": "作成", "zh-CN": "创建", "ko": "생성",
        "es": "Crear", "fr": "Créer", "de": "Erstellen", "pt-BR": "Criar",
    },
    "admin.users.created_ok": {
        "en": "Created {username} (role={role})",
        "ja": "作成しました: {username} (ロール={role})",
        "zh-CN": "已创建 {username} (角色={role})",
        "ko": "생성됨: {username} (역할={role})",
        "es": "Creado {username} (rol={role})",
        "fr": "Créé {username} (rôle={role})",
        "de": "Erstellt {username} (Rolle={role})",
        "pt-BR": "Criado {username} (papel={role})",
    },
    "admin.users.save_key_warn": {
        "en": "Save this API key now — it will not be shown again.",
        "ja": "この API キーは今すぐ保存してください。二度と表示されません。",
        "zh-CN": "请立即保存此 API 密钥 — 不会再次显示。",
        "ko": "이 API 키를 지금 저장하세요 — 다시 표시되지 않습니다.",
        "es": "Guarda esta API key ahora — no se mostrará de nuevo.",
        "fr": "Enregistrez cette clé API maintenant — elle ne sera plus affichée.",
        "de": "Speichern Sie diesen API-Key jetzt — er wird nicht erneut angezeigt.",
        "pt-BR": "Salve esta API key agora — não será exibida novamente.",
    },
    "admin.users.select_user": {
        "en": "Select user", "ja": "ユーザを選択", "zh-CN": "选择用户", "ko": "사용자 선택",
        "es": "Seleccionar usuario", "fr": "Sélectionner l'utilisateur", "de": "Benutzer auswählen", "pt-BR": "Selecionar usuário",
    },
    "admin.users.new_role": {
        "en": "New role", "ja": "新しいロール", "zh-CN": "新角色", "ko": "새 역할",
        "es": "Nuevo rol", "fr": "Nouveau rôle", "de": "Neue Rolle", "pt-BR": "Novo papel",
    },
    "admin.users.new_email": {
        "en": "New email", "ja": "新しいメールアドレス", "zh-CN": "新邮箱", "ko": "새 이메일",
        "es": "Nuevo correo", "fr": "Nouveau courriel", "de": "Neue E-Mail", "pt-BR": "Novo e-mail",
    },
    "admin.users.update_btn": {
        "en": "Update", "ja": "更新", "zh-CN": "更新", "ko": "업데이트",
        "es": "Actualizar", "fr": "Mettre à jour", "de": "Aktualisieren", "pt-BR": "Atualizar",
    },
    "admin.users.rotate_btn": {
        "en": "Rotate API key",
        "ja": "API キーを再発行",
        "zh-CN": "轮换 API 密钥",
        "ko": "API 키 재발급",
        "es": "Rotar API key",
        "fr": "Renouveler la clé API",
        "de": "API-Key rotieren",
        "pt-BR": "Rotacionar API key",
    },
    "admin.users.deactivate_btn": {
        "en": "Deactivate", "ja": "無効化", "zh-CN": "停用", "ko": "비활성화",
        "es": "Desactivar", "fr": "Désactiver", "de": "Deaktivieren", "pt-BR": "Desativar",
    },
    "admin.users.activate_btn": {
        "en": "Activate", "ja": "有効化", "zh-CN": "启用", "ko": "활성화",
        "es": "Activar", "fr": "Activer", "de": "Aktivieren", "pt-BR": "Ativar",
    },
    "admin.users.delete_btn": {
        "en": "🗑 Delete (cannot undo)",
        "ja": "🗑 削除 (取り消し不可)",
        "zh-CN": "🗑 删除 (不可撤销)",
        "ko": "🗑 삭제 (취소 불가)",
        "es": "🗑 Eliminar (sin deshacer)",
        "fr": "🗑 Supprimer (irréversible)",
        "de": "🗑 Löschen (nicht widerrufbar)",
        "pt-BR": "🗑 Excluir (sem desfazer)",
    },
    "admin.users.updated_ok": {
        "en": "Updated", "ja": "更新しました", "zh-CN": "已更新", "ko": "업데이트됨",
        "es": "Actualizado", "fr": "Mis à jour", "de": "Aktualisiert", "pt-BR": "Atualizado",
    },
    "admin.users.toggled_ok": {
        "en": "Status changed",
        "ja": "状態を切り替えました",
        "zh-CN": "状态已切换",
        "ko": "상태가 변경됨",
        "es": "Estado cambiado",
        "fr": "État modifié",
        "de": "Status geändert",
        "pt-BR": "Status alterado",
    },
    "admin.users.deleted_ok": {
        "en": "Deleted", "ja": "削除しました", "zh-CN": "已删除", "ko": "삭제됨",
        "es": "Eliminado", "fr": "Supprimé", "de": "Gelöscht", "pt-BR": "Excluído",
    },
    "admin.users.auth_unavailable": {
        "en": "Auth not available: {error}",
        "ja": "認証システムが利用できません: {error}",
        "zh-CN": "认证不可用: {error}",
        "ko": "인증 사용 불가: {error}",
        "es": "Autenticación no disponible: {error}",
        "fr": "Authentification indisponible : {error}",
        "de": "Auth nicht verfügbar: {error}",
        "pt-BR": "Auth indisponível: {error}",
    },

    # --- Connectors tab ---
    "admin.connectors.header": {
        "en": "🔌 External Connectors",
        "ja": "🔌 外部コネクタ",
        "zh-CN": "🔌 外部连接器",
        "ko": "🔌 외부 커넥터",
        "es": "🔌 Conectores Externos",
        "fr": "🔌 Connecteurs Externes",
        "de": "🔌 Externe Connectors",
        "pt-BR": "🔌 Conectores Externos",
    },
    "admin.connectors.intro": {
        "en": "Pull data from external systems for use as context, or push Praxia outputs back to your team's systems of record.",
        "ja": "外部システムからコンテキスト用データを取得 (Pull) するか、Praxia の出力を業務システムへ書き戻し (Push) します。",
        "zh-CN": "从外部系统拉取数据作为上下文,或将 Praxia 输出推回团队的记录系统。",
        "ko": "외부 시스템에서 컨텍스트용 데이터를 가져오거나 (Pull) Praxia 출력을 팀의 시스템에 다시 푸시합니다 (Push).",
        "es": "Extrae datos de sistemas externos para usar como contexto, o envía las salidas de Praxia de vuelta a los sistemas de registro de tu equipo.",
        "fr": "Récupère des données depuis des systèmes externes pour les utiliser comme contexte, ou renvoie les sorties de Praxia vers les systèmes de votre équipe.",
        "de": "Daten aus externen Systemen als Kontext abrufen oder Praxia-Ausgaben in die Systeme Ihres Teams zurückschreiben.",
        "pt-BR": "Extraia dados de sistemas externos para uso como contexto, ou envie saídas do Praxia de volta para os sistemas da sua equipe.",
    },
    "admin.connectors.connector_label": {
        "en": "Connector", "ja": "コネクタ", "zh-CN": "连接器", "ko": "커넥터",
        "es": "Conector", "fr": "Connecteur", "de": "Connector", "pt-BR": "Conector",
    },
    "admin.connectors.op_label": {
        "en": "Operation", "ja": "操作", "zh-CN": "操作", "ko": "작업",
        "es": "Operación", "fr": "Opération", "de": "Vorgang", "pt-BR": "Operação",
    },
    "admin.connectors.op_pull": {
        "en": "Pull", "ja": "取得 (Pull)", "zh-CN": "拉取", "ko": "가져오기",
        "es": "Obtener", "fr": "Récupérer", "de": "Abrufen", "pt-BR": "Obter",
    },
    "admin.connectors.op_push": {
        "en": "Push", "ja": "書込 (Push)", "zh-CN": "推送", "ko": "내보내기",
        "es": "Enviar", "fr": "Envoyer", "de": "Senden", "pt-BR": "Enviar",
    },
    "admin.connectors.path_label": {
        "en": "Path / folder ID / SOQL / app ID",
        "ja": "パス / フォルダ ID / SOQL / アプリ ID",
        "zh-CN": "路径 / 文件夹 ID / SOQL / 应用 ID",
        "ko": "경로 / 폴더 ID / SOQL / 앱 ID",
        "es": "Ruta / ID de carpeta / SOQL / ID de app",
        "fr": "Chemin / ID de dossier / SOQL / ID d'app",
        "de": "Pfad / Ordner-ID / SOQL / App-ID",
        "pt-BR": "Caminho / ID de pasta / SOQL / ID de app",
    },
    "admin.connectors.creds_hint": {
        "en": "Credentials are read from environment variables prefixed with `{prefix}`.",
        "ja": "資格情報は `{prefix}` プレフィックスの環境変数から読み込みます。",
        "zh-CN": "凭据从前缀为 `{prefix}` 的环境变量读取。",
        "ko": "자격 증명은 `{prefix}` 접두사 환경 변수에서 읽습니다.",
        "es": "Las credenciales se leen de variables de entorno con prefijo `{prefix}`.",
        "fr": "Les identifiants sont lus depuis les variables d'environnement préfixées `{prefix}`.",
        "de": "Anmeldedaten werden aus Umgebungsvariablen mit Präfix `{prefix}` gelesen.",
        "pt-BR": "As credenciais são lidas de variáveis de ambiente com prefixo `{prefix}`.",
    },
    "admin.connectors.limit_label": {
        "en": "Limit", "ja": "件数上限", "zh-CN": "上限", "ko": "최대 수",
        "es": "Límite", "fr": "Limite", "de": "Limit", "pt-BR": "Limite",
    },
    "admin.connectors.body_label": {
        "en": "Body / payload (text or JSON)",
        "ja": "本文 / ペイロード (テキストまたは JSON)",
        "zh-CN": "正文 / payload (文本或 JSON)",
        "ko": "본문 / 페이로드 (텍스트 또는 JSON)",
        "es": "Cuerpo / payload (texto o JSON)",
        "fr": "Corps / charge utile (texte ou JSON)",
        "de": "Body / Payload (Text oder JSON)",
        "pt-BR": "Corpo / payload (texto ou JSON)",
    },
    "admin.connectors.pull_btn": {
        "en": "Pull", "ja": "取得", "zh-CN": "拉取", "ko": "가져오기",
        "es": "Obtener", "fr": "Récupérer", "de": "Abrufen", "pt-BR": "Obter",
    },
    "admin.connectors.push_btn": {
        "en": "Push", "ja": "書込", "zh-CN": "推送", "ko": "내보내기",
        "es": "Enviar", "fr": "Envoyer", "de": "Senden", "pt-BR": "Enviar",
    },
    "admin.connectors.pulled_ok": {
        "en": "Pulled {count} items",
        "ja": "{count} 件を取得しました",
        "zh-CN": "已拉取 {count} 项",
        "ko": "{count}개 항목을 가져왔습니다",
        "es": "Se obtuvieron {count} ítems",
        "fr": "{count} éléments récupérés",
        "de": "{count} Einträge abgerufen",
        "pt-BR": "Obtidos {count} itens",
    },
    "admin.connectors.pushed_ok": {
        "en": "Pushed: {receipt}",
        "ja": "書き込みました: {receipt}",
        "zh-CN": "已推送: {receipt}",
        "ko": "푸시됨: {receipt}",
        "es": "Enviado: {receipt}",
        "fr": "Envoyé : {receipt}",
        "de": "Gesendet: {receipt}",
        "pt-BR": "Enviado: {receipt}",
    },

    # --- Exports tab ---
    "admin.exports.intro": {
        "en": "Export audit logs, users, skill usage, memories, and policies for compliance, SIEM ingestion, or backups. Every export action is logged.",
        "ja": "監査ログ・ユーザ・スキル利用履歴・メモリ・ポリシーをコンプライアンス対応、SIEM 連携、バックアップ用にエクスポートします。すべてのエクスポート操作は監査ログに記録されます。",
        "zh-CN": "导出审计日志、用户、技能使用、内存、策略,用于合规、SIEM 接入或备份。每次导出操作都会被记录。",
        "ko": "규정 준수, SIEM 인제스트, 백업을 위해 감사 로그, 사용자, 스킬 사용, 메모리, 정책을 내보냅니다. 모든 내보내기 작업은 기록됩니다.",
        "es": "Exporta registros de auditoría, usuarios, uso de skills, memoria y políticas para cumplimiento, ingesta SIEM o copias de seguridad. Cada exportación se registra.",
        "fr": "Exporte les journaux d'audit, utilisateurs, utilisation des skills, mémoires et politiques pour conformité, ingestion SIEM ou sauvegardes. Chaque export est journalisé.",
        "de": "Exportiert Audit-Logs, Benutzer, Skill-Nutzung, Memories und Richtlinien für Compliance, SIEM-Ingestion oder Backups. Jeder Export wird protokolliert.",
        "pt-BR": "Exporta logs de auditoria, usuários, uso de skills, memórias e políticas para conformidade, ingestão SIEM ou backups. Cada exportação é registrada.",
    },
    "admin.exports.what": {
        "en": "What to export",
        "ja": "エクスポート対象",
        "zh-CN": "导出内容",
        "ko": "내보낼 항목",
        "es": "Qué exportar",
        "fr": "À exporter",
        "de": "Zu exportieren",
        "pt-BR": "O que exportar",
    },
    "admin.exports.format_label": {
        "en": "Format", "ja": "フォーマット", "zh-CN": "格式", "ko": "포맷",
        "es": "Formato", "fr": "Format", "de": "Format", "pt-BR": "Formato",
    },
    "admin.exports.kind.audit": {
        "en": "Audit log",
        "ja": "監査ログ",
        "zh-CN": "审计日志",
        "ko": "감사 로그",
        "es": "Registro de auditoría",
        "fr": "Journal d'audit",
        "de": "Audit-Log",
        "pt-BR": "Log de auditoria",
    },
    "admin.exports.kind.users": {
        "en": "Users", "ja": "ユーザ", "zh-CN": "用户", "ko": "사용자",
        "es": "Usuarios", "fr": "Utilisateurs", "de": "Benutzer", "pt-BR": "Usuários",
    },
    "admin.exports.kind.skill_usage": {
        "en": "Skill usage",
        "ja": "スキル利用履歴",
        "zh-CN": "技能使用",
        "ko": "스킬 사용 기록",
        "es": "Uso de skills",
        "fr": "Utilisation des skills",
        "de": "Skill-Nutzung",
        "pt-BR": "Uso de skills",
    },
    "admin.exports.kind.personal_memory": {
        "en": "Personal memory (one user)",
        "ja": "個人メモリ (1 ユーザ分)",
        "zh-CN": "个人内存 (单用户)",
        "ko": "개인 메모리 (한 사용자)",
        "es": "Memoria personal (un usuario)",
        "fr": "Mémoire personnelle (un utilisateur)",
        "de": "Personal Memory (ein Benutzer)",
        "pt-BR": "Memória pessoal (um usuário)",
    },
    "admin.exports.kind.all_personal": {
        "en": "All personal memories",
        "ja": "全ユーザの個人メモリ",
        "zh-CN": "全部个人内存",
        "ko": "모든 개인 메모리",
        "es": "Todas las memorias personales",
        "fr": "Toutes les mémoires personnelles",
        "de": "Alle Personal Memories",
        "pt-BR": "Todas as memórias pessoais",
    },
    "admin.exports.kind.shared_memory": {
        "en": "Shared memory blocks",
        "ja": "共有メモリブロック",
        "zh-CN": "共享内存块",
        "ko": "공유 메모리 블록",
        "es": "Bloques de memoria compartida",
        "fr": "Blocs de mémoire partagée",
        "de": "Shared-Memory-Blöcke",
        "pt-BR": "Blocos de memória compartilhada",
    },
    "admin.exports.kind.policies": {
        "en": "Access policies",
        "ja": "アクセスポリシー",
        "zh-CN": "访问策略",
        "ko": "접근 정책",
        "es": "Políticas de acceso",
        "fr": "Politiques d'accès",
        "de": "Zugriffsrichtlinien",
        "pt-BR": "Políticas de acesso",
    },
    "admin.exports.user_id_label": {
        "en": "user_id", "ja": "ユーザ ID", "zh-CN": "用户 ID", "ko": "사용자 ID",
        "es": "ID de usuario", "fr": "ID utilisateur", "de": "Benutzer-ID", "pt-BR": "ID do usuário",
    },
    "admin.exports.skill_filter": {
        "en": "Optional skill name filter",
        "ja": "スキル名でフィルタ (任意)",
        "zh-CN": "可选: 技能名过滤",
        "ko": "선택 사항: 스킬 이름 필터",
        "es": "Filtro opcional por nombre de skill",
        "fr": "Filtre optionnel par nom de skill",
        "de": "Optionaler Skill-Name-Filter",
        "pt-BR": "Filtro opcional por nome de skill",
    },
    "admin.exports.export_btn": {
        "en": "Export", "ja": "エクスポート実行", "zh-CN": "导出", "ko": "내보내기",
        "es": "Exportar", "fr": "Exporter", "de": "Exportieren", "pt-BR": "Exportar",
    },
    "admin.exports.exported_ok": {
        "en": "Exported → {path}",
        "ja": "エクスポート完了 → {path}",
        "zh-CN": "已导出 → {path}",
        "ko": "내보내기 완료 → {path}",
        "es": "Exportado → {path}",
        "fr": "Exporté → {path}",
        "de": "Exportiert → {path}",
        "pt-BR": "Exportado → {path}",
    },
    "admin.exports.download_btn": {
        "en": "⬇️ Download",
        "ja": "⬇️ ダウンロード",
        "zh-CN": "⬇️ 下载",
        "ko": "⬇️ 다운로드",
        "es": "⬇️ Descargar",
        "fr": "⬇️ Télécharger",
        "de": "⬇️ Herunterladen",
        "pt-BR": "⬇️ Baixar",
    },

    "admin.connections.unavailable_short": {
        "en": "Not available yet — ask your administrator to enable the OAuth callback endpoint.",
        "ja": "現在は利用できません。OAuth コールバック機能の有効化を管理者に依頼してください。",
        "zh-CN": "暂不可用 — 请联系管理员启用 OAuth 回调功能。",
        "ko": "사용할 수 없음 — OAuth 콜백 기능 활성화를 관리자에게 요청하세요.",
        "es": "No disponible — solicita al administrador que habilite el callback de OAuth.",
        "fr": "Non disponible — demandez à l'administrateur d'activer le callback OAuth.",
        "de": "Noch nicht verfügbar — bitten Sie den Administrator, den OAuth-Callback zu aktivieren.",
        "pt-BR": "Não disponível — peça ao administrador para habilitar o callback OAuth.",
    },
    "admin.connections.disconnected_ok": {
        "en": "Disconnected from {provider}.",
        "ja": "{provider} の接続を解除しました。",
        "zh-CN": "已断开与 {provider} 的连接。",
        "ko": "{provider} 연결을 해제했습니다.",
        "es": "Desconectado de {provider}.",
        "fr": "Déconnecté de {provider}.",
        "de": "Verbindung zu {provider} getrennt.",
        "pt-BR": "Desconectado de {provider}.",
    },
    "admin.themes.subtab": {
        "en": "🎨 Themes",
        "ja": "🎨 テーマ",
        "zh-CN": "🎨 主题",
        "ko": "🎨 테마",
        "es": "🎨 Temas",
        "fr": "🎨 Thèmes",
        "de": "🎨 Themes",
        "pt-BR": "🎨 Temas",
    },
    "admin.themes.intro": {
        "en": "Document themes for the designer skills (pptx_designer / docx_designer). Each theme is a JSON file plus optional logo / slide-master assets. Users pick a theme when running a designer skill; the LLM-authored code applies the theme's colors, fonts, logo, and footer to the generated deck or document.",
        "ja": "デザイナースキル (pptx_designer / docx_designer) 用のドキュメントテーマです。各テーマは JSON ファイル + ロゴ/マスタースライドの任意素材で構成されます。ユーザはデザイナースキル実行時にテーマを選択し、LLM が生成するコードはテーマの色・フォント・ロゴ・フッターを成果物に適用します。",
        "zh-CN": "Designer skill (pptx_designer / docx_designer) 使用的文档主题。每个主题是一个 JSON 文件加可选的 logo / 母版素材。用户运行 designer skill 时选择主题,LLM 生成的代码将主题的颜色、字体、logo 和页脚应用到生成的文档。",
        "ko": "디자이너 스킬 (pptx_designer / docx_designer) 용 문서 테마. 각 테마는 JSON 파일과 선택적 로고 / 마스터 슬라이드 자산으로 구성됩니다. 사용자는 디자이너 스킬 실행 시 테마를 선택하며, LLM이 작성한 코드가 테마의 색상, 폰트, 로고, 푸터를 생성된 문서에 적용합니다.",
        "es": "Temas de documento para los skills de diseñador (pptx_designer / docx_designer). Cada tema es un archivo JSON más recursos opcionales de logo / master de diapositivas. Los usuarios eligen un tema al ejecutar un skill de diseñador; el código generado por el LLM aplica los colores, fuentes, logo y pie de página del tema al documento.",
        "fr": "Thèmes de document pour les skills designer (pptx_designer / docx_designer). Chaque thème est un fichier JSON avec des ressources optionnelles (logo / master de diapositives). Les utilisateurs choisissent un thème lors de l'exécution d'un skill designer ; le code généré par le LLM applique les couleurs, polices, logo et pied de page du thème au document généré.",
        "de": "Dokumentthemes für die Designer-Skills (pptx_designer / docx_designer). Jedes Theme ist eine JSON-Datei plus optionale Logo-/Master-Slide-Assets. Benutzer wählen beim Ausführen eines Designer-Skills ein Theme aus; der vom LLM generierte Code wendet die Farben, Schriftarten, das Logo und den Footer des Themes auf das Dokument an.",
        "pt-BR": "Temas de documento para os skills designer (pptx_designer / docx_designer). Cada tema é um arquivo JSON mais recursos opcionais de logo / master de slides. Os usuários escolhem um tema ao executar um skill designer; o código gerado pelo LLM aplica as cores, fontes, logo e rodapé do tema ao documento.",
    },
    "admin.themes.existing_h": {
        "en": "Installed themes",
        "ja": "登録済みテーマ",
        "zh-CN": "已安装主题",
        "ko": "설치된 테마",
        "es": "Temas instalados",
        "fr": "Thèmes installés",
        "de": "Installierte Themes",
        "pt-BR": "Temas instalados",
    },
    "admin.themes.empty": {
        "en": "No themes yet — designer skills will use a neutral default theme.",
        "ja": "テーマ未登録です。デザイナースキルはニュートラルなデフォルトテーマで動作します。",
        "zh-CN": "尚无主题 — designer skill 将使用中性默认主题。",
        "ko": "테마 없음 — 디자이너 스킬은 중립적인 기본 테마로 동작합니다.",
        "es": "Aún no hay temas — los skills de diseñador usarán un tema neutral por defecto.",
        "fr": "Aucun thème pour l'instant — les skills designer utiliseront un thème neutre par défaut.",
        "de": "Noch keine Themes — Designer-Skills verwenden ein neutrales Standardtheme.",
        "pt-BR": "Ainda não há temas — os skills designer usarão um tema neutro padrão.",
    },
    "admin.themes.delete_btn": {
        "en": "🗑 Delete theme",
        "ja": "🗑 テーマを削除",
        "zh-CN": "🗑 删除主题",
        "ko": "🗑 테마 삭제",
        "es": "🗑 Eliminar tema",
        "fr": "🗑 Supprimer le thème",
        "de": "🗑 Theme löschen",
        "pt-BR": "🗑 Excluir tema",
    },
    "admin.themes.deleted": {
        "en": "Deleted theme {name}.",
        "ja": "テーマ {name} を削除しました。",
        "zh-CN": "已删除主题 {name}。",
        "ko": "테마 {name} 을(를) 삭제했습니다.",
        "es": "Tema {name} eliminado.",
        "fr": "Thème {name} supprimé.",
        "de": "Theme {name} gelöscht.",
        "pt-BR": "Tema {name} excluído.",
    },
    "admin.themes.new_h": {
        "en": "Add a new theme",
        "ja": "新しいテーマを追加",
        "zh-CN": "添加新主题",
        "ko": "새 테마 추가",
        "es": "Agregar un nuevo tema",
        "fr": "Ajouter un nouveau thème",
        "de": "Neues Theme hinzufügen",
        "pt-BR": "Adicionar novo tema",
    },
    "admin.themes.new.name": {
        "en": "Theme name (a-z, 0-9, _ , -)",
        "ja": "テーマ名 (英数字 / _ / -)",
        "zh-CN": "主题名 (字母数字 / _ / -)",
        "ko": "테마 이름 (영숫자 / _ / -)",
        "es": "Nombre del tema (a-z, 0-9, _, -)",
        "fr": "Nom du thème (a-z, 0-9, _, -)",
        "de": "Theme-Name (a-z, 0-9, _, -)",
        "pt-BR": "Nome do tema (a-z, 0-9, _, -)",
    },
    "admin.themes.new.primary": {
        "en": "Primary color",
        "ja": "プライマリカラー",
        "zh-CN": "主色",
        "ko": "기본 색상",
        "es": "Color primario",
        "fr": "Couleur primaire",
        "de": "Primärfarbe",
        "pt-BR": "Cor primária",
    },
    "admin.themes.new.accent": {
        "en": "Accent color",
        "ja": "アクセントカラー",
        "zh-CN": "强调色",
        "ko": "강조 색상",
        "es": "Color de acento",
        "fr": "Couleur d'accent",
        "de": "Akzentfarbe",
        "pt-BR": "Cor de destaque",
    },
    "admin.themes.new.bg": {
        "en": "Background color",
        "ja": "背景色",
        "zh-CN": "背景色",
        "ko": "배경 색상",
        "es": "Color de fondo",
        "fr": "Couleur de fond",
        "de": "Hintergrundfarbe",
        "pt-BR": "Cor de fundo",
    },
    "admin.themes.new.muted": {
        "en": "Muted color (captions / dividers)",
        "ja": "ミュートカラー (キャプション・罫線)",
        "zh-CN": "弱化色 (说明 / 分隔)",
        "ko": "약한 색상 (캡션 / 구분선)",
        "es": "Color atenuado (subtítulos / divisores)",
        "fr": "Couleur atténuée (légendes / séparateurs)",
        "de": "Gedämpfte Farbe (Bildunterschriften / Trenner)",
        "pt-BR": "Cor atenuada (legendas / divisores)",
    },
    "admin.themes.new.text": {
        "en": "Body text color",
        "ja": "本文テキスト色",
        "zh-CN": "正文颜色",
        "ko": "본문 텍스트 색상",
        "es": "Color del texto",
        "fr": "Couleur du texte",
        "de": "Textfarbe",
        "pt-BR": "Cor do texto",
    },
    "admin.themes.new.heading_font": {
        "en": "Heading font (any installed font name)",
        "ja": "見出しフォント (インストール済みフォント名)",
        "zh-CN": "标题字体 (任何已安装字体名)",
        "ko": "제목 폰트 (설치된 폰트 이름)",
        "es": "Fuente de encabezado",
        "fr": "Police de titre",
        "de": "Überschriften-Schrift",
        "pt-BR": "Fonte de título",
    },
    "admin.themes.new.body_font": {
        "en": "Body font",
        "ja": "本文フォント",
        "zh-CN": "正文字体",
        "ko": "본문 폰트",
        "es": "Fuente del cuerpo",
        "fr": "Police du corps",
        "de": "Body-Schrift",
        "pt-BR": "Fonte do corpo",
    },
    "admin.themes.new.heading_size": {
        "en": "Heading size (pt)",
        "ja": "見出しサイズ (pt)",
        "zh-CN": "标题字号 (pt)",
        "ko": "제목 크기 (pt)",
        "es": "Tamaño de encabezado (pt)",
        "fr": "Taille de titre (pt)",
        "de": "Überschriftgröße (pt)",
        "pt-BR": "Tamanho do título (pt)",
    },
    "admin.themes.new.body_size": {
        "en": "Body size (pt)",
        "ja": "本文サイズ (pt)",
        "zh-CN": "正文字号 (pt)",
        "ko": "본문 크기 (pt)",
        "es": "Tamaño del cuerpo (pt)",
        "fr": "Taille du corps (pt)",
        "de": "Body-Größe (pt)",
        "pt-BR": "Tamanho do corpo (pt)",
    },
    "admin.themes.new.footer_text": {
        "en": "Footer text (optional)",
        "ja": "フッターテキスト (任意)",
        "zh-CN": "页脚文本 (可选)",
        "ko": "푸터 텍스트 (선택)",
        "es": "Texto de pie de página (opcional)",
        "fr": "Texte du pied de page (optionnel)",
        "de": "Fußzeilentext (optional)",
        "pt-BR": "Texto do rodapé (opcional)",
    },
    "admin.themes.new.logo": {
        "en": "Logo (PNG / JPG, optional)",
        "ja": "ロゴ (PNG / JPG, 任意)",
        "zh-CN": "Logo (PNG / JPG, 可选)",
        "ko": "로고 (PNG / JPG, 선택)",
        "es": "Logo (PNG / JPG, opcional)",
        "fr": "Logo (PNG / JPG, optionnel)",
        "de": "Logo (PNG / JPG, optional)",
        "pt-BR": "Logo (PNG / JPG, opcional)",
    },
    "admin.themes.new.master": {
        "en": "Slide master .pptx (optional, advanced)",
        "ja": "スライドマスター .pptx (任意・上級)",
        "zh-CN": "母版 .pptx (可选,高级)",
        "ko": "슬라이드 마스터 .pptx (선택, 고급)",
        "es": "Master .pptx (opcional, avanzado)",
        "fr": "Master .pptx (optionnel, avancé)",
        "de": "Slide-Master .pptx (optional, erweitert)",
        "pt-BR": "Master .pptx (opcional, avançado)",
    },
    "admin.themes.new.save_btn": {
        "en": "💾 Save theme",
        "ja": "💾 テーマを保存",
        "zh-CN": "💾 保存主题",
        "ko": "💾 테마 저장",
        "es": "💾 Guardar tema",
        "fr": "💾 Enregistrer le thème",
        "de": "💾 Theme speichern",
        "pt-BR": "💾 Salvar tema",
    },
    "admin.themes.saved": {
        "en": "Saved theme {name}.",
        "ja": "テーマ {name} を保存しました。",
        "zh-CN": "已保存主题 {name}。",
        "ko": "테마 {name} 을(를) 저장했습니다.",
        "es": "Tema {name} guardado.",
        "fr": "Thème {name} enregistré.",
        "de": "Theme {name} gespeichert.",
        "pt-BR": "Tema {name} salvo.",
    },
    "skill.designer.theme": {
        "en": "🎨 Theme",
        "ja": "🎨 テーマ",
        "zh-CN": "🎨 主题",
        "ko": "🎨 테마",
        "es": "🎨 Tema",
        "fr": "🎨 Thème",
        "de": "🎨 Theme",
        "pt-BR": "🎨 Tema",
    },
    "skill.designer.theme_none": {
        "en": "(no theme — neutral defaults)",
        "ja": "(テーマなし — ニュートラル既定)",
        "zh-CN": "(无主题 — 中性默认)",
        "ko": "(테마 없음 — 중립 기본값)",
        "es": "(sin tema — predeterminados neutros)",
        "fr": "(sans thème — valeurs neutres par défaut)",
        "de": "(kein Theme — neutrale Standards)",
        "pt-BR": "(sem tema — padrões neutros)",
    },
    "skill.designer.theme_hint": {
        "en": "Themes provide colors, fonts, logo, and footer that the LLM-generated code applies to the document. Manage themes in Admin → Themes.",
        "ja": "テーマは LLM 生成コードが文書に適用する色・フォント・ロゴ・フッターを提供します。Admin → テーマで管理できます。",
        "zh-CN": "主题提供 LLM 生成代码应用到文档的颜色、字体、logo 和页脚。在 Admin → 主题中管理。",
        "ko": "테마는 LLM이 생성한 코드가 문서에 적용하는 색상, 폰트, 로고, 푸터를 제공합니다. Admin → 테마에서 관리하세요.",
        "es": "Los temas proporcionan colores, fuentes, logo y pie de página que el código generado por el LLM aplica al documento. Gestionar en Admin → Temas.",
        "fr": "Les thèmes fournissent les couleurs, polices, logo et pied de page que le code généré par le LLM applique au document. Gérer dans Admin → Thèmes.",
        "de": "Themes bestimmen Farben, Schriftarten, Logo und Footer, die vom LLM-generierten Code auf das Dokument angewendet werden. Verwaltung unter Admin → Themes.",
        "pt-BR": "Temas fornecem cores, fontes, logo e rodapé que o código gerado pelo LLM aplica ao documento. Gerencie em Admin → Temas.",
    },
    "skill.designer.no_tts": {
        "en": "TTS doesn't apply to designer skills — output is a binary document, not text.",
        "ja": "TTS はデザイナースキルには適用されません (出力はテキストではなくバイナリ文書)。",
        "zh-CN": "TTS 不适用于 designer skill — 输出为二进制文档,而非文本。",
        "ko": "TTS는 디자이너 스킬에 적용되지 않습니다 — 출력이 텍스트가 아닌 바이너리 문서입니다.",
        "es": "TTS no aplica a los skills de diseñador — la salida es un documento binario, no texto.",
        "fr": "TTS ne s'applique pas aux skills designer — la sortie est un document binaire, pas du texte.",
        "de": "TTS gilt nicht für Designer-Skills — die Ausgabe ist ein binäres Dokument, kein Text.",
        "pt-BR": "TTS não se aplica aos skills designer — a saída é um documento binário, não texto.",
    },
    "skill.designer.designing": {
        "en": "🎨 Designing… (LLM authoring code, sandbox running, may retry)",
        "ja": "🎨 デザイン中… (LLM がコード生成 → サンドボックス実行 → 失敗時はリトライ)",
        "zh-CN": "🎨 设计中… (LLM 编写代码 → 沙盒执行 → 失败则重试)",
        "ko": "🎨 디자인 중… (LLM이 코드 작성 → 샌드박스 실행 → 실패 시 재시도)",
        "es": "🎨 Diseñando… (el LLM escribe código → sandbox ejecuta → reintenta en caso de fallo)",
        "fr": "🎨 Conception… (le LLM rédige le code → sandbox exécute → réessai en cas d'échec)",
        "de": "🎨 Entwerfen… (LLM schreibt Code → Sandbox führt aus → bei Fehler erneuter Versuch)",
        "pt-BR": "🎨 Desenhando… (LLM escreve código → sandbox executa → tenta novamente em caso de falha)",
    },
    "skill.designer.success": {
        "en": "✅ Generated {n:,} bytes — ready to download as {ext}.",
        "ja": "✅ {n:,} バイト生成完了 — {ext} としてダウンロード可。",
        "zh-CN": "✅ 已生成 {n:,} 字节 — 可下载为 {ext}。",
        "ko": "✅ {n:,} 바이트 생성 완료 — {ext} 로 다운로드 가능.",
        "es": "✅ Generados {n:,} bytes — listo para descargar como {ext}.",
        "fr": "✅ {n:,} octets générés — prêt à télécharger en {ext}.",
        "de": "✅ {n:,} Bytes generiert — bereit zum Download als {ext}.",
        "pt-BR": "✅ {n:,} bytes gerados — pronto para baixar como {ext}.",
    },
    "admin.settings.runtime_h": {
        "en": "Default LLM model (persistent, applies to every user)",
        "ja": "既定の LLM モデル (永続、全ユーザに適用)",
        "zh-CN": "默认 LLM 模型 (持久化，所有用户共用)",
        "ko": "기본 LLM 모델 (영구, 모든 사용자에게 적용)",
        "es": "Modelo LLM por defecto (persistente, todos los usuarios)",
        "fr": "Modèle LLM par défaut (persistant, pour tous les utilisateurs)",
        "de": "Standard-LLM-Modell (persistent, für alle Nutzer)",
        "pt-BR": "Modelo LLM padrão (persistente, para todos os usuários)",
    },
    "admin.settings.runtime_intro": {
        "en": "Saved to `.praxia/admin/runtime.json` and used by every user's RUN until changed. Restart-proof. The memory backend is configured separately under **Memory policy** below.",
        "ja": "`.praxia/admin/runtime.json` に保存され、変更されるまで全ユーザの RUN で使われます。Streamlit を再起動しても残ります。メモリバックエンドは下の **メモリポリシー** で別途設定。",
        "zh-CN": "保存到 `.praxia/admin/runtime.json`，被所有用户的 RUN 使用，直到再次修改。重启后仍然有效。内存后端在下方 **内存策略** 中单独配置。",
        "ko": "`.praxia/admin/runtime.json` 에 저장되어 변경 전까지 모든 사용자의 RUN 에서 사용됩니다. 재시작 후에도 유지. 메모리 백엔드는 아래 **메모리 정책** 에서 별도 설정.",
        "es": "Guardado en `.praxia/admin/runtime.json` y usado por el RUN de cada usuario hasta que cambies. Persiste al reinicio. El backend de memoria se configura aparte en **Política de memoria** abajo.",
        "fr": "Stocké dans `.praxia/admin/runtime.json` et utilisé par le RUN de chaque utilisateur jusqu'à modification. Persiste au redémarrage. Le backend mémoire se configure séparément dans **Politique mémoire** ci-dessous.",
        "de": "Gespeichert in `.praxia/admin/runtime.json` und beim RUN jedes Nutzers verwendet, bis geändert. Bleibt nach Neustart. Memory-Backend wird separat unter **Memory-Richtlinie** unten konfiguriert.",
        "pt-BR": "Salvo em `.praxia/admin/runtime.json` e usado pelo RUN de todos os usuários até ser alterado. Persiste no reinício. O backend de memória é configurado separadamente em **Política de memória** abaixo.",
    },
    "admin.settings.provider_label": {
        "en": "Provider",
        "ja": "プロバイダ",
        "zh-CN": "提供商",
        "ko": "프로바이더",
        "es": "Proveedor",
        "fr": "Fournisseur",
        "de": "Anbieter",
        "pt-BR": "Provedor",
    },
    "admin.settings.model_label": {
        "en": "LLM model",
        "ja": "LLM モデル",
        "zh-CN": "LLM 模型",
        "ko": "LLM 모델",
        "es": "Modelo LLM",
        "fr": "Modèle LLM",
        "de": "LLM-Modell",
        "pt-BR": "Modelo LLM",
    },
    "admin.settings.model_custom": {
        "en": "Custom model string (e.g. anthropic/claude-opus-4-7)",
        "ja": "カスタムモデル文字列 (例: anthropic/claude-opus-4-7)",
        "zh-CN": "自定义模型字符串(如 anthropic/claude-opus-4-7)",
        "ko": "커스텀 모델 문자열 (예: anthropic/claude-opus-4-7)",
        "es": "Cadena de modelo personalizada (p. ej. anthropic/claude-opus-4-7)",
        "fr": "Chaîne de modèle personnalisée (ex. anthropic/claude-opus-4-7)",
        "de": "Benutzerdefinierter Modell-String (z. B. anthropic/claude-opus-4-7)",
        "pt-BR": "String de modelo personalizada (ex. anthropic/claude-opus-4-7)",
    },
    "admin.settings.model_custom_in_provider": {
        "en": "Custom deployment / model name…",
        "ja": "カスタム デプロイメント / モデル名…",
        "zh-CN": "自定义部署 / 模型名…",
        "ko": "커스텀 배포 / 모델 이름…",
        "es": "Deployment / modelo personalizado…",
        "fr": "Déploiement / modèle personnalisé…",
        "de": "Eigener Deployment / Modell-Name…",
        "pt-BR": "Deployment / modelo personalizado…",
    },
    "admin.settings.model_custom_in_provider_input": {
        "en": "Custom model id (must start with `{prefix}`)",
        "ja": "カスタムモデル ID (`{prefix}` で始める必要があります)",
        "zh-CN": "自定义模型 id (必须以 `{prefix}` 开头)",
        "ko": "커스텀 모델 id (`{prefix}` 로 시작해야 함)",
        "es": "ID de modelo personalizado (debe empezar por `{prefix}`)",
        "fr": "ID de modèle personnalisé (doit commencer par `{prefix}`)",
        "de": "Eigene Modell-ID (muss mit `{prefix}` beginnen)",
        "pt-BR": "ID de modelo personalizado (deve começar com `{prefix}`)",
    },
    "admin.settings.model_custom_in_provider_help": {
        "en": "For Azure: replace `your-deployment-name` with the exact Deployment name from Foundry Studio → Deployments. For Bedrock: use the inference profile id (e.g. `us.anthropic.claude-opus-4-7-v1:0`).",
        "ja": "Azure の場合: `your-deployment-name` を Foundry Studio → Deployments の Deployment name 列の値に置き換え。Bedrock の場合: inference profile id (例: `us.anthropic.claude-opus-4-7-v1:0`) を入力。",
        "zh-CN": "Azure: 将 `your-deployment-name` 换成 Foundry Studio → Deployments 中的 Deployment name。Bedrock: 使用 inference profile id (如 `us.anthropic.claude-opus-4-7-v1:0`)。",
        "ko": "Azure: `your-deployment-name` 을 Foundry Studio → Deployments 의 Deployment name 값으로 교체. Bedrock: inference profile id (예: `us.anthropic.claude-opus-4-7-v1:0`).",
        "es": "Azure: sustituye `your-deployment-name` por el Deployment name exacto de Foundry Studio → Deployments. Bedrock: usa el inference profile id (p.ej. `us.anthropic.claude-opus-4-7-v1:0`).",
        "fr": "Azure : remplacez `your-deployment-name` par le Deployment name exact dans Foundry Studio → Deployments. Bedrock : utilisez l'inference profile id (ex. `us.anthropic.claude-opus-4-7-v1:0`).",
        "de": "Azure: `your-deployment-name` durch den exakten Deployment name aus Foundry Studio → Deployments ersetzen. Bedrock: Inference-Profile-ID verwenden (z. B. `us.anthropic.claude-opus-4-7-v1:0`).",
        "pt-BR": "Azure: substitua `your-deployment-name` pelo Deployment name exato em Foundry Studio → Deployments. Bedrock: use o inference profile id (p.ex. `us.anthropic.claude-opus-4-7-v1:0`).",
    },
    "admin.settings.backend_label": {
        "en": "Memory backend",
        "ja": "メモリバックエンド",
        "zh-CN": "记忆后端",
        "ko": "메모리 백엔드",
        "es": "Backend de memoria",
        "fr": "Backend mémoire",
        "de": "Memory-Backend",
        "pt-BR": "Backend de memória",
    },
    "admin.settings.runtime_apply": {
        "en": "Apply runtime change",
        "ja": "ランタイム変更を適用",
        "zh-CN": "应用运行时更改",
        "ko": "런타임 변경 적용",
        "es": "Aplicar cambio runtime",
        "fr": "Appliquer le changement runtime",
        "de": "Laufzeitänderung anwenden",
        "pt-BR": "Aplicar mudança em runtime",
    },
    "admin.settings.runtime_saved": {
        "en": "✅ Runtime settings updated. Reloading…",
        "ja": "✅ ランタイム設定を更新。再読み込み中…",
        "zh-CN": "✅ 运行时设置已更新,正在重新加载…",
        "ko": "✅ 런타임 설정 갱신됨. 다시 로드 중…",
        "es": "✅ Ajustes runtime actualizados. Recargando…",
        "fr": "✅ Réglages runtime mis à jour. Rechargement…",
        "de": "✅ Laufzeit-Einstellungen aktualisiert. Lade neu…",
        "pt-BR": "✅ Ajustes runtime atualizados. Recarregando…",
    },
    "admin.settings.backend_probe_failed": {
        "en": "❌ Backend `{backend}` could not initialize: {error}\n\nCommon cause: `mem0` defaults its embedder to OpenAI and requires `OPENAI_API_KEY`. Set the env var or pick a different backend before applying.",
        "ja": "❌ バックエンド `{backend}` の初期化に失敗: {error}\n\n典型的な原因: `mem0` はデフォルトのエンベッダが OpenAI のため `OPENAI_API_KEY` が必須です。env var を設定するか別のバックエンドを選んでから適用してください。",
        "zh-CN": "❌ 后端 `{backend}` 初始化失败: {error}\n\n常见原因: `mem0` 的嵌入器默认使用 OpenAI，需要 `OPENAI_API_KEY`。请设置环境变量或改选其他后端后再应用。",
        "ko": "❌ 백엔드 `{backend}` 초기화 실패: {error}\n\n일반적 원인: `mem0` 는 임베더가 기본 OpenAI 라 `OPENAI_API_KEY` 가 필요합니다. 환경변수를 설정하거나 다른 백엔드를 선택하고 적용하세요.",
        "es": "❌ El backend `{backend}` no pudo inicializar: {error}\n\nCausa habitual: `mem0` usa OpenAI como embedder por defecto y requiere `OPENAI_API_KEY`. Define la env var o elige otro backend antes de aplicar.",
        "fr": "❌ Le backend `{backend}` n'a pas pu s'initialiser : {error}\n\nCause fréquente : `mem0` utilise OpenAI comme embedder par défaut et requiert `OPENAI_API_KEY`. Définissez la variable d'env ou choisissez un autre backend avant d'appliquer.",
        "de": "❌ Backend `{backend}` konnte nicht initialisieren: {error}\n\nHäufige Ursache: `mem0` nutzt OpenAI als Standard-Embedder und braucht `OPENAI_API_KEY`. Setze die Env-Variable oder wähle ein anderes Backend, bevor du anwendest.",
        "pt-BR": "❌ Backend `{backend}` não pôde inicializar: {error}\n\nCausa comum: `mem0` usa OpenAI como embedder padrão e requer `OPENAI_API_KEY`. Defina a env var ou escolha outro backend antes de aplicar.",
    },
    "loom.init_failed": {
        "en": "❌ Praxia could not start with backend `{backend}`: {error}",
        "ja": "❌ バックエンド `{backend}` で Praxia を起動できませんでした: {error}",
        "zh-CN": "❌ Praxia 无法以后端 `{backend}` 启动: {error}",
        "ko": "❌ 백엔드 `{backend}` 로 Praxia 를 시작할 수 없습니다: {error}",
        "es": "❌ Praxia no pudo arrancar con el backend `{backend}`: {error}",
        "fr": "❌ Praxia n'a pas pu démarrer avec le backend `{backend}` : {error}",
        "de": "❌ Praxia konnte mit Backend `{backend}` nicht starten: {error}",
        "pt-BR": "❌ Praxia não pôde iniciar com o backend `{backend}`: {error}",
    },
    "loom.init_failed_hint": {
        "en": "Most often this is a missing API key for an external memory provider (e.g. `mem0` defaults its embedder to OpenAI and needs `OPENAI_API_KEY`). Fix the env var, or fall back to the always-on `json` backend below.",
        "ja": "多くの場合、外部メモリプロバイダの API キーが不足しています (例: `mem0` はエンベッダのデフォルトが OpenAI なので `OPENAI_API_KEY` が必要)。env var を直すか、依存ゼロの `json` バックエンドに戻してください。",
        "zh-CN": "多数情况是外部内存提供方的 API key 缺失 (如 `mem0` 嵌入器默认 OpenAI，需要 `OPENAI_API_KEY`)。请修正环境变量，或回退到无依赖的 `json` 后端。",
        "ko": "대부분 외부 메모리 프로바이더의 API 키가 없는 것이 원인입니다 (예: `mem0` 은 임베더 기본이 OpenAI 이므로 `OPENAI_API_KEY` 필요). 환경변수를 수정하거나 의존성 없는 `json` 백엔드로 폴백하세요.",
        "es": "Habitualmente falta una API key de un proveedor de memoria externo (p.ej. `mem0` usa OpenAI por defecto y necesita `OPENAI_API_KEY`). Corrige la env var o vuelve al backend sin dependencias `json`.",
        "fr": "Le plus souvent il manque une clé API d'un fournisseur de mémoire externe (ex. `mem0` utilise OpenAI par défaut et requiert `OPENAI_API_KEY`). Corrigez la variable d'env ou revenez au backend `json` sans dépendances.",
        "de": "Meist fehlt ein API-Key eines externen Speicheranbieters (z. B. nutzt `mem0` standardmäßig OpenAI und benötigt `OPENAI_API_KEY`). Setze die Env-Variable oder fallback zum abhängigkeitsfreien `json`-Backend.",
        "pt-BR": "Quase sempre é uma API key faltando de um provedor de memória externo (ex.: `mem0` usa OpenAI por padrão e precisa `OPENAI_API_KEY`). Corrija a env var ou volte ao backend `json` sem dependências.",
    },
    "loom.fallback_to_json": {
        "en": "Fall back to `json` backend",
        "ja": "`json` バックエンドにフォールバック",
        "zh-CN": "回退到 `json` 后端",
        "ko": "`json` 백엔드로 폴백",
        "es": "Volver al backend `json`",
        "fr": "Revenir au backend `json`",
        "de": "Zum `json`-Backend zurückfallen",
        "pt-BR": "Voltar ao backend `json`",
    },
    "admin.settings.backend_h": {
        "en": "Tenant memory backend",
        "ja": "テナントのメモリバックエンド",
        "zh-CN": "租户记忆后端",
        "ko": "테넌트 메모리 백엔드",
        "es": "Backend de memoria del tenant",
        "fr": "Backend mémoire du tenant",
        "de": "Tenant-Memory-Backend",
        "pt-BR": "Backend de memória do tenant",
    },
    "admin.settings.backend_intro": {
        "en": "Which LTM backend the entire instance uses (JSON / Mem0 / LangMem / Letta / Zep). Tenant-wide — applies to all users.",
        "ja": "このインスタンス全体で使う LTM バックエンド (JSON / Mem0 / LangMem / Letta / Zep)。テナント単位 — 全ユーザに適用。",
        "zh-CN": "整个实例使用的 LTM 后端(JSON / Mem0 / LangMem / Letta / Zep)。租户级 — 对所有用户生效。",
        "ko": "이 인스턴스 전체가 사용하는 LTM 백엔드 (JSON / Mem0 / LangMem / Letta / Zep). 테넌트 단위 — 모든 사용자에 적용.",
        "es": "Backend LTM usado por toda la instancia (JSON / Mem0 / LangMem / Letta / Zep). Nivel tenant — aplica a todos los usuarios.",
        "fr": "Backend LTM utilisé par toute l'instance (JSON / Mem0 / LangMem / Letta / Zep). Niveau tenant — pour tous les utilisateurs.",
        "de": "LTM-Backend für die gesamte Instanz (JSON / Mem0 / LangMem / Letta / Zep). Tenant-weit — für alle Nutzer.",
        "pt-BR": "Backend LTM usado pela instância inteira (JSON / Mem0 / LangMem / Letta / Zep). Nível tenant — aplica a todos.",
    },
    "admin.settings.backend_apply": {
        "en": "💾 Apply tenant backend",
        "ja": "💾 テナントバックエンドを適用",
        "zh-CN": "💾 应用租户后端",
        "ko": "💾 테넌트 백엔드 적용",
        "es": "💾 Aplicar backend del tenant",
        "fr": "💾 Appliquer le backend tenant",
        "de": "💾 Tenant-Backend anwenden",
        "pt-BR": "💾 Aplicar backend do tenant",
    },
    "admin.settings.persistent_h": {
        "en": "Persistent: API keys + service credentials",
        "ja": "永続: API キー + サービス認証情報",
        "zh-CN": "持久: API 密钥 + 服务凭据",
        "ko": "영속: API 키 + 서비스 자격증명",
        "es": "Persistente: claves API + credenciales de servicio",
        "fr": "Persistant : clés API + credentials de service",
        "de": "Persistent: API-Keys + Service-Credentials",
        "pt-BR": "Persistente: chaves API + credenciais de serviço",
    },
    "admin.settings.intro": {
        "en": "Configure API keys, memory backend, OAuth client credentials, and other runtime settings. Values are persisted to `.praxia/config.toml`. Existing environment variables / `.env` entries take precedence.",
        "ja": "API キー、メモリバックエンド、OAuth クライアント資格情報など実行時設定を変更します。値は `.praxia/config.toml` に保存。既存の環境変数 / `.env` の設定が優先されます。",
        "zh-CN": "配置 API 密钥、记忆后端、OAuth 客户端凭据等运行时设置。值持久化到 `.praxia/config.toml`。已设的环境变量 / `.env` 优先。",
        "ko": "API 키, 메모리 백엔드, OAuth 클라이언트 자격증명 등 런타임 설정을 변경합니다. 값은 `.praxia/config.toml` 에 저장. 기존 환경변수 / `.env` 가 우선됩니다.",
        "es": "Configura claves API, backend de memoria, credenciales OAuth y otros ajustes runtime. Los valores se persisten en `.praxia/config.toml`. Las variables de entorno / `.env` existentes tienen prioridad.",
        "fr": "Configurez les clés API, le backend mémoire, les identifiants OAuth et autres réglages runtime. Les valeurs sont persistées dans `.praxia/config.toml`. Les variables d'environnement / `.env` existantes ont la priorité.",
        "de": "Konfiguriere API-Keys, Memory-Backend, OAuth-Client-Credentials und andere Laufzeit-Einstellungen. Werte werden in `.praxia/config.toml` gespeichert. Vorhandene Umgebungsvariablen / `.env` haben Vorrang.",
        "pt-BR": "Configure chaves API, backend de memória, credenciais OAuth e outros ajustes runtime. Valores são persistidos em `.praxia/config.toml`. Variáveis de ambiente / `.env` existentes têm prioridade.",
    },
    "admin.settings.role_ok": {
        "en": "✅ Signed in as **{user}** (admin) — settings are editable.",
        "ja": "✅ **{user}** (admin) でサインイン中 — 設定を変更できます。",
        "zh-CN": "✅ 当前以 **{user}** (admin) 登录 — 可编辑设置。",
        "ko": "✅ **{user}** (admin) 로 로그인 중 — 설정을 편집할 수 있습니다.",
        "es": "✅ Sesión como **{user}** (admin) — los ajustes se pueden editar.",
        "fr": "✅ Connecté en tant que **{user}** (admin) — réglages éditables.",
        "de": "✅ Angemeldet als **{user}** (admin) — Einstellungen sind editierbar.",
        "pt-BR": "✅ Sessão como **{user}** (admin) — os ajustes podem ser editados.",
    },
    "admin.settings.role_unknown": {
        "en": "⚠️ Sidebar user_id `{user}` is not in the auth store. Anyone can edit settings in this dev/single-user setup. Create users via the **Users** tab to enforce role-based access.",
        "ja": "⚠️ サイドバーの user_id `{user}` は認証ストアに存在しません。このデフォルト (開発 / 単一ユーザ) 環境では誰でも設定を変更可能。**ユーザ** タブからユーザを作成すると、ロールベースの制御が有効になります。",
        "zh-CN": "⚠️ 侧边栏 user_id `{user}` 不在 auth 存储中。在此开发 / 单用户环境下任何人都可编辑设置。通过 **用户** 标签创建用户以启用基于角色的访问控制。",
        "ko": "⚠️ 사이드바 user_id `{user}` 가 auth 저장소에 없습니다. 이 개발 / 단일 사용자 환경에서는 누구나 설정을 변경할 수 있습니다. **사용자** 탭에서 사용자를 만들면 역할 기반 제어가 활성화됩니다.",
        "es": "⚠️ El user_id `{user}` del sidebar no existe en el almacén de auth. En este modo dev/usuario-único cualquiera puede editar. Crea usuarios en la pestaña **Usuarios** para aplicar control por rol.",
        "fr": "⚠️ L'user_id `{user}` du sidebar n'existe pas dans le store d'auth. En mode dev/mono-utilisateur n'importe qui peut éditer. Créez des utilisateurs dans l'onglet **Utilisateurs** pour activer le contrôle par rôle.",
        "de": "⚠️ Sidebar-user_id `{user}` ist nicht im Auth-Store. In diesem Dev-/Einzelnutzer-Modus kann jeder Einstellungen bearbeiten. Lege im **Users**-Tab Nutzer an, um rollenbasierte Kontrolle zu aktivieren.",
        "pt-BR": "⚠️ O user_id `{user}` do sidebar não existe no auth store. Neste modo dev/usuário-único qualquer um pode editar. Crie usuários na aba **Usuários** para ativar controle por papel.",
    },
    "admin.settings.role_blocked": {
        "en": "🚫 **{user}** has role `{role}` — only `admin` users should change settings. Changes will be audit-logged with this role.",
        "ja": "🚫 **{user}** のロールは `{role}` — 設定変更は `admin` ロールのユーザのみ実施すべきです。変更はこのロールで監査ログに記録されます。",
        "zh-CN": "🚫 **{user}** 的角色为 `{role}` — 仅 `admin` 应更改设置。变更将以此角色记录到审计日志。",
        "ko": "🚫 **{user}** 의 역할은 `{role}` 입니다 — 설정 변경은 `admin` 역할만 수행해야 합니다. 변경은 이 역할로 감사 로그에 기록됩니다.",
        "es": "🚫 **{user}** tiene rol `{role}` — solo usuarios `admin` deberían cambiar ajustes. Los cambios se auditan con este rol.",
        "fr": "🚫 **{user}** a le rôle `{role}` — seuls les `admin` devraient changer les réglages. Les modifications seront auditées avec ce rôle.",
        "de": "🚫 **{user}** hat Rolle `{role}` — nur `admin`-Nutzer sollten Einstellungen ändern. Änderungen werden mit dieser Rolle protokolliert.",
        "pt-BR": "🚫 **{user}** tem papel `{role}` — apenas usuários `admin` devem alterar ajustes. Mudanças são auditadas com este papel.",
    },
    "admin.settings.memory_policy_h": {
        "en": "🧠 Memory policy",
        "ja": "🧠 メモリポリシー",
        "zh-CN": "🧠 内存策略",
        "ko": "🧠 메모리 정책",
        "es": "🧠 Política de memoria",
        "fr": "🧠 Politique mémoire",
        "de": "🧠 Speicher-Richtlinie",
        "pt-BR": "🧠 Política de memória",
    },
    "admin.settings.memory_policy_intro": {
        "en": "Persistent org-wide rules saved to `.praxia/admin/memory_policy.json`. The **default backend** here is the fallback used by every new PersonalMemory across processes and users; the runtime backend above only overrides it for the current process.",
        "ja": "組織全体に適用される永続ルール。`.praxia/admin/memory_policy.json` に保存。ここの **既定バックエンド** は全プロセス・全ユーザの PersonalMemory 構築時に使われるフォールバック。上のランタイムバックエンドは現プロセスのみの一時上書き。",
        "zh-CN": "组织级别的持久化规则。保存于 `.praxia/admin/memory_policy.json`。此处的 **默认后端** 是跨进程、跨用户的 PersonalMemory 回退值；上方的运行时后端仅临时覆盖当前进程。",
        "ko": "조직 전체에 적용되는 영구 규칙. `.praxia/admin/memory_policy.json` 에 저장. 여기의 **기본 백엔드** 는 모든 프로세스/사용자의 PersonalMemory 폴백; 위쪽 런타임 백엔드는 현재 프로세스만의 임시 오버라이드.",
        "es": "Reglas persistentes de toda la organización en `.praxia/admin/memory_policy.json`. El **backend por defecto** de aquí es el fallback de cada PersonalMemory en todos los procesos y usuarios; el backend runtime de arriba solo lo sobrescribe en el proceso actual.",
        "fr": "Règles persistantes au niveau organisation dans `.praxia/admin/memory_policy.json`. Le **backend par défaut** ici est le repli pour chaque PersonalMemory à travers les processus et utilisateurs ; le backend runtime ci-dessus ne le remplace que pour le processus actuel.",
        "de": "Persistente, organisationsweite Regeln in `.praxia/admin/memory_policy.json`. Das **Standard-Backend** hier ist der Fallback für jedes PersonalMemory über alle Prozesse und Nutzer; das Runtime-Backend oben überschreibt nur den aktuellen Prozess.",
        "pt-BR": "Regras persistentes para toda a organização em `.praxia/admin/memory_policy.json`. O **backend padrão** aqui é o fallback de cada PersonalMemory em todos os processos e usuários; o backend runtime acima só sobrescreve o processo atual.",
    },
    "admin.settings.mp_strategy_label": {
        "en": "Backend strategy",
        "ja": "バックエンド戦略",
        "zh-CN": "后端策略",
        "ko": "백엔드 전략",
        "es": "Estrategia de backend",
        "fr": "Stratégie de backend",
        "de": "Backend-Strategie",
        "pt-BR": "Estratégia de backend",
    },
    "admin.settings.mp_strategy_help": {
        "en": "Single = one backend for everyone. Composite = query several in parallel and fuse results. Routed = pick a backend per query.",
        "ja": "Single = 全ユーザ 1 バックエンド。Composite = 複数を並列クエリして結果融合。Routed = クエリ毎にルータが選択。",
        "zh-CN": "Single = 全员一个后端。Composite = 并行查询多个并融合。Routed = 每次查询由路由器决定。",
        "ko": "Single = 전체 1 백엔드. Composite = 여러 개 병렬 + 결과 융합. Routed = 쿼리마다 라우터 선택.",
        "es": "Single = un backend para todos. Composite = consulta varios en paralelo y fusiona. Routed = el router elige por consulta.",
        "fr": "Single = un seul backend pour tous. Composite = interroger plusieurs en parallèle et fusionner. Routed = le routeur choisit par requête.",
        "de": "Single = ein Backend für alle. Composite = parallel mehrere abfragen und fusionieren. Routed = Router wählt pro Anfrage.",
        "pt-BR": "Single = um backend para todos. Composite = consulta vários em paralelo e funde. Routed = roteador escolhe por consulta.",
    },
    "admin.settings.mp_strategy.single": {
        "en": "Single (one backend for everyone)",
        "ja": "Single (1 バックエンド)",
        "zh-CN": "Single (单一后端)",
        "ko": "Single (단일 백엔드)",
        "es": "Single (un backend)",
        "fr": "Single (un seul backend)",
        "de": "Single (ein Backend)",
        "pt-BR": "Single (um backend)",
    },
    "admin.settings.mp_strategy.composite": {
        "en": "Composite (parallel + fuse)",
        "ja": "Composite (並列 + 融合)",
        "zh-CN": "Composite (并行 + 融合)",
        "ko": "Composite (병렬 + 융합)",
        "es": "Composite (paralelo + fusión)",
        "fr": "Composite (parallèle + fusion)",
        "de": "Composite (parallel + Fusion)",
        "pt-BR": "Composite (paralelo + fusão)",
    },
    "admin.settings.mp_strategy.routed": {
        "en": "Routed (per-query)",
        "ja": "Routed (クエリ毎)",
        "zh-CN": "Routed (按查询)",
        "ko": "Routed (쿼리별)",
        "es": "Routed (por consulta)",
        "fr": "Routed (par requête)",
        "de": "Routed (pro Anfrage)",
        "pt-BR": "Routed (por consulta)",
    },
    "admin.settings.mp_single_backend": {
        "en": "Backend",
        "ja": "バックエンド",
        "zh-CN": "后端",
        "ko": "백엔드",
        "es": "Backend",
        "fr": "Backend",
        "de": "Backend",
        "pt-BR": "Backend",
    },
    "admin.settings.mp_single_backend_help": {
        "en": "The single Layer-1 backend used by every user. `json` is dependency-free; `mem0` / `letta` / `langmem` / `zep` / `hindsight` need their respective Python package installed and (for cloud variants) an API key.",
        "ja": "全ユーザが使う単一の Layer-1 バックエンド。`json` は依存ゼロ。`mem0` / `letta` / `langmem` / `zep` / `hindsight` は対応 Python パッケージのインストールと (クラウド版なら) API キー必要。",
        "zh-CN": "所有用户共用的单一 Layer-1 后端。`json` 无依赖。`mem0` / `letta` / `langmem` / `zep` / `hindsight` 需相应 Python 包(云版还需 API Key)。",
        "ko": "모든 사용자가 쓰는 단일 Layer-1 백엔드. `json` 은 의존성 없음. `mem0` / `letta` / `langmem` / `zep` / `hindsight` 는 해당 Python 패키지 + (클라우드 버전이면) API 키 필요.",
        "es": "El único backend de Layer-1 para todos. `json` no requiere dependencias; `mem0` / `letta` / `langmem` / `zep` / `hindsight` necesitan su paquete y (en versiones cloud) una API key.",
        "fr": "Le backend Layer-1 unique pour tous. `json` sans dépendance ; `mem0` / `letta` / `langmem` / `zep` / `hindsight` nécessitent le package Python et (pour les variantes cloud) une clé API.",
        "de": "Das einzige Layer-1-Backend für alle. `json` ohne Abhängigkeiten. `mem0` / `letta` / `langmem` / `zep` / `hindsight` brauchen das Paket plus (für Cloud) einen API-Key.",
        "pt-BR": "O único backend Layer-1 para todos. `json` sem dependências; `mem0` / `letta` / `langmem` / `zep` / `hindsight` precisam do pacote Python e (para cloud) uma API key.",
    },
    "admin.settings.mp_composite_intro": {
        "en": "Reads fan out to ALL listed backends in parallel; results are fused via the chosen strategy. Writes go to a single chosen target. Combining e.g. `mem0` + `zep` gives you Mem0's entity recall + Zep's temporal awareness in one query.",
        "ja": "読み取りはリストの全バックエンドに並列クエリ → 選択した戦略で結果融合。書き込みは指定先 1 つだけ。例: `mem0` + `zep` で Mem0 のエンティティ検索 + Zep の時系列推論を 1 クエリで両取り。",
        "zh-CN": "读取并行查询所有列表中的后端 → 按所选策略融合结果。写入仅去单一目标。例: `mem0` + `zep` 可在一次查询中同时获得 Mem0 实体检索 + Zep 时序能力。",
        "ko": "읽기는 목록의 모든 백엔드에 병렬 조회 → 선택한 전략으로 결과 융합. 쓰기는 지정 1 곳에만. 예: `mem0` + `zep` 로 Mem0 엔티티 검색 + Zep 시간 추론을 한 번에.",
        "es": "Las lecturas se distribuyen en paralelo a todos los backends listados; los resultados se fusionan según la estrategia. Las escrituras van a un solo destino. Combinar p.ej. `mem0` + `zep` da búsqueda por entidades + temporalidad en una consulta.",
        "fr": "Les lectures interrogent tous les backends listés en parallèle ; les résultats sont fusionnés selon la stratégie. Les écritures vont vers une seule cible. Combiner `mem0` + `zep` donne la recherche d'entités + le raisonnement temporel en une requête.",
        "de": "Lesevorgänge laufen parallel über alle gelisteten Backends; Ergebnisse werden per Strategie fusioniert. Schreibvorgänge gehen an ein Ziel. `mem0` + `zep` liefert Entitäts-Recall + zeitliches Denken in einer Anfrage.",
        "pt-BR": "Leituras consultam em paralelo todos os backends listados; resultados são fundidos pela estratégia escolhida. Escritas vão para um alvo único. Combinar `mem0` + `zep` dá busca de entidades + raciocínio temporal em uma consulta.",
    },
    "admin.settings.mp_composite_backends": {
        "en": "Backends to fan out to",
        "ja": "並列クエリ対象バックエンド",
        "zh-CN": "并行查询的后端",
        "ko": "병렬 조회 대상 백엔드",
        "es": "Backends a consultar en paralelo",
        "fr": "Backends interrogés en parallèle",
        "de": "Parallel abzufragende Backends",
        "pt-BR": "Backends consultados em paralelo",
    },
    "admin.settings.mp_composite_backends_help": {
        "en": "Each gets the same query in parallel. Backends that fail to initialize are skipped silently rather than crashing the whole stack.",
        "ja": "全部に同じクエリを並列発射。初期化失敗した backend は静かに無視 (スタック全停止より優先)。",
        "zh-CN": "全部并行收到同一查询。初始化失败的后端会被静默跳过(优于整个崩溃)。",
        "ko": "모두 같은 쿼리를 병렬 수신. 초기화 실패한 백엔드는 조용히 스킵 (전체 중단보다 우선).",
        "es": "Todos reciben la misma consulta en paralelo. Los backends que fallan al inicializar se omiten silenciosamente.",
        "fr": "Tous reçoivent la même requête en parallèle. Les backends qui échouent à l'init sont ignorés silencieusement.",
        "de": "Alle erhalten parallel die gleiche Anfrage. Backends, die nicht initialisieren, werden still übersprungen.",
        "pt-BR": "Todos recebem a mesma consulta em paralelo. Backends que falham na inicialização são ignorados silenciosamente.",
    },
    "admin.settings.mp_composite_fusion": {
        "en": "Fusion strategy",
        "ja": "融合戦略",
        "zh-CN": "融合策略",
        "ko": "융합 전략",
        "es": "Estrategia de fusión",
        "fr": "Stratégie de fusion",
        "de": "Fusionsstrategie",
        "pt-BR": "Estratégia de fusão",
    },
    "admin.settings.mp_composite_fusion_help": {
        "en": "rrf = Reciprocal Rank Fusion (recommended baseline). union = dedup + first-seen. intersection = only items in ≥2 backends. weighted = score × weight. llm_rerank = LLM picks the best (slow, accurate).",
        "ja": "rrf = Reciprocal Rank Fusion (推奨ベースライン)。union = 重複除外して先着順。intersection = 2 以上の backend にあるものだけ。weighted = score × weight。llm_rerank = LLM が最適選択 (遅いが精度高)。",
        "zh-CN": "rrf = Reciprocal Rank Fusion (推荐基线)。union = 去重先到先得。intersection = 至少 2 个后端命中。weighted = score × weight。llm_rerank = LLM 选最佳 (慢但准)。",
        "ko": "rrf = Reciprocal Rank Fusion (추천 기준선). union = 중복 제거 + 선착순. intersection = 2 개 이상 백엔드에 있는 것만. weighted = score × weight. llm_rerank = LLM 이 최적 선택 (느리지만 정확).",
        "es": "rrf = Reciprocal Rank Fusion (línea base recomendada). union = dedup + primero visto. intersection = solo en ≥2 backends. weighted = score × peso. llm_rerank = LLM elige (lento, preciso).",
        "fr": "rrf = Reciprocal Rank Fusion (référence recommandée). union = dédup + premier vu. intersection = uniquement dans ≥2 backends. weighted = score × poids. llm_rerank = LLM choisit (lent, précis).",
        "de": "rrf = Reciprocal Rank Fusion (empfohlen). union = Dedupe + zuerst gesehen. intersection = nur in ≥2 Backends. weighted = Score × Gewicht. llm_rerank = LLM wählt (langsam, präzise).",
        "pt-BR": "rrf = Reciprocal Rank Fusion (linha base recomendada). union = dedup + primeiro visto. intersection = apenas em ≥2 backends. weighted = score × peso. llm_rerank = LLM escolhe (lento, preciso).",
    },
    "admin.settings.mp_fusion.rrf": {
        "en": "rrf — Reciprocal Rank Fusion",
        "ja": "rrf — Reciprocal Rank Fusion",
        "zh-CN": "rrf — 倒数排名融合",
        "ko": "rrf — Reciprocal Rank Fusion",
        "es": "rrf — Reciprocal Rank Fusion",
        "fr": "rrf — Reciprocal Rank Fusion",
        "de": "rrf — Reciprocal Rank Fusion",
        "pt-BR": "rrf — Reciprocal Rank Fusion",
    },
    "admin.settings.mp_fusion.union": {
        "en": "union — dedup + first-seen rank",
        "ja": "union — 重複除外 + 先着順",
        "zh-CN": "union — 去重 + 先到先得",
        "ko": "union — 중복 제거 + 선착순",
        "es": "union — dedup + primero visto",
        "fr": "union — dédup + premier vu",
        "de": "union — Dedupe + zuerst gesehen",
        "pt-BR": "union — dedup + primeiro visto",
    },
    "admin.settings.mp_fusion.intersection": {
        "en": "intersection — only items in ≥2 backends",
        "ja": "intersection — 2 つ以上で出たものだけ",
        "zh-CN": "intersection — 至少 2 个后端命中",
        "ko": "intersection — 2 개 이상 백엔드에 있는 것만",
        "es": "intersection — solo en ≥2 backends",
        "fr": "intersection — uniquement dans ≥2 backends",
        "de": "intersection — nur in ≥2 Backends",
        "pt-BR": "intersection — apenas em ≥2 backends",
    },
    "admin.settings.mp_fusion.weighted": {
        "en": "weighted — score × weight",
        "ja": "weighted — score × weight",
        "zh-CN": "weighted — 分数 × 权重",
        "ko": "weighted — 점수 × 가중치",
        "es": "weighted — score × peso",
        "fr": "weighted — score × poids",
        "de": "weighted — Score × Gewicht",
        "pt-BR": "weighted — score × peso",
    },
    "admin.settings.mp_fusion.llm_rerank": {
        "en": "llm_rerank — LLM picks the best",
        "ja": "llm_rerank — LLM が最適選択",
        "zh-CN": "llm_rerank — LLM 选最佳",
        "ko": "llm_rerank — LLM 이 최적 선택",
        "es": "llm_rerank — LLM elige el mejor",
        "fr": "llm_rerank — LLM choisit le meilleur",
        "de": "llm_rerank — LLM wählt das Beste",
        "pt-BR": "llm_rerank — LLM escolhe o melhor",
    },
    "admin.settings.mp_composite_write_to": {
        "en": "Write target (one backend)",
        "ja": "書き込み先 (1 バックエンド)",
        "zh-CN": "写入目标 (单一后端)",
        "ko": "쓰기 대상 (1 백엔드)",
        "es": "Destino de escritura (un backend)",
        "fr": "Cible d'écriture (un backend)",
        "de": "Schreibziel (ein Backend)",
        "pt-BR": "Destino de escrita (um backend)",
    },
    "admin.settings.mp_composite_write_to_help": {
        "en": "Writes (record_episode / record_fact) go to this single backend to avoid duplication. Reads still fan out to all of them.",
        "ja": "書き込み (record_episode / record_fact) は重複防止のためこの 1 つだけ。読み取りは引き続き全 backend にファンアウト。",
        "zh-CN": "写入 (record_episode / record_fact) 仅去这一个,避免重复。读取仍并行所有。",
        "ko": "쓰기 (record_episode / record_fact) 는 중복 방지를 위해 이 하나에만. 읽기는 모두 fan-out.",
        "es": "Las escrituras (record_episode / record_fact) van solo aquí para evitar duplicación. Las lecturas siguen en paralelo.",
        "fr": "Les écritures (record_episode / record_fact) ne vont que là pour éviter les doublons. Les lectures restent en parallèle.",
        "de": "Schreibvorgänge (record_episode / record_fact) gehen nur hierher, um Duplikate zu vermeiden. Lesevorgänge bleiben parallel.",
        "pt-BR": "Escritas (record_episode / record_fact) vão só para aqui para evitar duplicação. Leituras continuam em paralelo.",
    },
    "admin.settings.mp_routed_intro": {
        "en": "A router inspects each query and picks the best backend(s) for it. RuleRouter uses regex patterns (temporal queries → Zep, entity queries → mem0+hindsight, etc.). LLMRouter asks the LLM to choose (more flexible, slower).",
        "ja": "ルータが各クエリを見て最適 backend を選択。RuleRouter は正規表現 (時系列 → Zep、エンティティ → mem0+hindsight 等)。LLMRouter は LLM に選択判断させる (柔軟だが遅い)。",
        "zh-CN": "路由器分析每个查询选择最佳后端。RuleRouter 使用正则规则 (时序 → Zep、实体 → mem0+hindsight 等)。LLMRouter 让 LLM 决策 (更灵活但慢)。",
        "ko": "라우터가 각 쿼리를 보고 최적 백엔드 선택. RuleRouter 는 정규식 (시계열 → Zep, 엔티티 → mem0+hindsight 등). LLMRouter 는 LLM 이 결정 (더 유연하지만 느림).",
        "es": "Un router inspecciona cada consulta y elige el(los) mejor(es) backend(s). RuleRouter usa regex (temporal → Zep, entidades → mem0+hindsight). LLMRouter pide al LLM que elija (más flexible, más lento).",
        "fr": "Un routeur examine chaque requête et choisit le(s) meilleur(s) backend(s). RuleRouter utilise des regex (temporel → Zep, entités → mem0+hindsight). LLMRouter demande au LLM (plus flexible, plus lent).",
        "de": "Ein Router prüft jede Anfrage und wählt die besten Backends. RuleRouter nutzt Regex (zeitlich → Zep, Entitäten → mem0+hindsight). LLMRouter lässt das LLM entscheiden (flexibler, langsamer).",
        "pt-BR": "Um roteador inspeciona cada consulta e escolhe o(s) melhor(es) backend(s). RuleRouter usa regex (temporal → Zep, entidades → mem0+hindsight). LLMRouter pede ao LLM (mais flexível, mais lento).",
    },
    "admin.settings.mp_routed_backends": {
        "en": "Available backends",
        "ja": "利用可能バックエンド",
        "zh-CN": "可用后端",
        "ko": "사용 가능 백엔드",
        "es": "Backends disponibles",
        "fr": "Backends disponibles",
        "de": "Verfügbare Backends",
        "pt-BR": "Backends disponíveis",
    },
    "admin.settings.mp_routed_backends_help": {
        "en": "The router picks from this set per query.",
        "ja": "ルータはここから選択。",
        "zh-CN": "路由器从此集合中选择。",
        "ko": "라우터가 이 집합에서 선택.",
        "es": "El router elige de este conjunto por consulta.",
        "fr": "Le routeur choisit dans cet ensemble par requête.",
        "de": "Der Router wählt pro Anfrage aus dieser Menge.",
        "pt-BR": "O roteador escolhe deste conjunto por consulta.",
    },
    "admin.settings.mp_routed_router": {
        "en": "Router",
        "ja": "ルータ",
        "zh-CN": "路由器",
        "ko": "라우터",
        "es": "Router",
        "fr": "Routeur",
        "de": "Router",
        "pt-BR": "Roteador",
    },
    "admin.settings.mp_routed_router_help": {
        "en": "rule = bilingual regex (no extra LLM call). llm = ask the model 'which backend?' (1 extra call per query).",
        "ja": "rule = JA/EN 正規表現 (追加 LLM コールなし)。llm = 「どの backend?」を毎回 LLM に聞く (クエリ毎 +1 コール)。",
        "zh-CN": "rule = 中英正则 (无额外 LLM 调用)。llm = 每次询问 LLM 「哪个后端」 (每查询多 1 次调用)。",
        "ko": "rule = 영/일 정규식 (추가 LLM 호출 없음). llm = 매번 LLM 에게 '어느 백엔드?' 질문 (쿼리당 +1 호출).",
        "es": "rule = regex bilingüe (sin LLM extra). llm = pregunta al modelo '¿qué backend?' (+1 llamada por consulta).",
        "fr": "rule = regex bilingue (pas d'appel LLM en plus). llm = demande au modèle 'quel backend ?' (+1 appel par requête).",
        "de": "rule = zweisprachige Regex (kein zusätzlicher LLM-Call). llm = fragt das Modell 'welches Backend?' (+1 Call pro Anfrage).",
        "pt-BR": "rule = regex bilíngue (sem LLM extra). llm = pergunta ao modelo 'qual backend?' (+1 chamada por consulta).",
    },
    "admin.settings.mp_router.rule": {
        "en": "rule — bilingual regex (fast, free)",
        "ja": "rule — JA/EN 正規表現 (高速・無料)",
        "zh-CN": "rule — 中英正则 (快速, 免费)",
        "ko": "rule — 영/일 정규식 (빠름, 무료)",
        "es": "rule — regex bilingüe (rápido, gratis)",
        "fr": "rule — regex bilingue (rapide, gratuit)",
        "de": "rule — zweisprachige Regex (schnell, kostenlos)",
        "pt-BR": "rule — regex bilíngue (rápido, grátis)",
    },
    "admin.settings.mp_router.llm": {
        "en": "llm — model decides (flexible, +1 call/query)",
        "ja": "llm — LLM が判断 (柔軟・+1 コール/クエリ)",
        "zh-CN": "llm — LLM 决策 (灵活, 每查询 +1 次调用)",
        "ko": "llm — LLM 결정 (유연, 쿼리당 +1 호출)",
        "es": "llm — el modelo decide (flexible, +1 llamada/consulta)",
        "fr": "llm — modèle décide (flexible, +1 appel/requête)",
        "de": "llm — Modell entscheidet (flexibel, +1 Call/Anfrage)",
        "pt-BR": "llm — modelo decide (flexível, +1 chamada/consulta)",
    },
    "admin.settings.mp_default_backend": {
        "en": "Default backend",
        "ja": "既定バックエンド",
        "zh-CN": "默认后端",
        "ko": "기본 백엔드",
        "es": "Backend predeterminado",
        "fr": "Backend par défaut",
        "de": "Standard-Backend",
        "pt-BR": "Backend padrão",
    },
    "admin.settings.mp_default_backend_help": {
        "en": "Used when a user has not chosen one. Falls through to `json` if missing.",
        "ja": "ユーザが選択していない場合に使われるバックエンド。未指定なら `json` にフォールバック。",
        "zh-CN": "用户未选择时的回退后端。未设置则回退至 `json`。",
        "ko": "사용자가 선택하지 않았을 때 사용. 미설정 시 `json` 으로 폴백.",
        "es": "Se usa cuando el usuario no ha elegido uno. Cae a `json` si falta.",
        "fr": "Utilisé quand l'utilisateur n'en a pas choisi. Repli sur `json` si absent.",
        "de": "Wird verwendet, wenn der Nutzer keines wählt. Fallback auf `json`.",
        "pt-BR": "Usado quando o usuário não escolhe um. Cai para `json` se ausente.",
    },
    "admin.settings.mp_enforced_backend": {
        "en": "Enforced backend",
        "ja": "強制バックエンド",
        "zh-CN": "强制后端",
        "ko": "강제 백엔드",
        "es": "Backend forzado",
        "fr": "Backend imposé",
        "de": "Erzwungenes Backend",
        "pt-BR": "Backend obrigatório",
    },
    "admin.settings.mp_enforced_backend_help": {
        "en": "Locks every user to this backend regardless of their preference. Use for compliance / regulated tenancies.",
        "ja": "ユーザの好みを無視して全員にこのバックエンドを強制。規制業種向けロックダウン用途。",
        "zh-CN": "无视用户偏好，强制所有人使用此后端。用于合规 / 受监管租户。",
        "ko": "사용자 설정과 무관하게 모두에게 이 백엔드를 강제. 규제 환경용.",
        "es": "Fuerza este backend para todos los usuarios. Para cumplimiento / inquilinos regulados.",
        "fr": "Impose ce backend à tous, quelle que soit leur préférence. Pour environnements régulés.",
        "de": "Erzwingt dieses Backend für alle Nutzer unabhängig von Vorlieben. Für regulierte Mandanten.",
        "pt-BR": "Força este backend para todos, ignorando preferências. Para tenancies regulamentadas.",
    },
    "admin.settings.mp_enforced_none": {
        "en": "(no enforcement)",
        "ja": "(強制しない)",
        "zh-CN": "(不强制)",
        "ko": "(강제 없음)",
        "es": "(sin imposición)",
        "fr": "(pas d'imposition)",
        "de": "(keine Erzwingung)",
        "pt-BR": "(sem imposição)",
    },
    "admin.settings.mp_allowed_backends": {
        "en": "Allowed backends (empty = any)",
        "ja": "許可バックエンド (空 = 全許可)",
        "zh-CN": "允许的后端 (空 = 全部)",
        "ko": "허용 백엔드 (비우면 모두 허용)",
        "es": "Backends permitidos (vacío = todos)",
        "fr": "Backends autorisés (vide = tous)",
        "de": "Erlaubte Backends (leer = alle)",
        "pt-BR": "Backends permitidos (vazio = todos)",
    },
    "admin.settings.mp_allowed_backends_help": {
        "en": "When non-empty, users can only choose from this list. Ignored if an enforced backend is set.",
        "ja": "空でなければユーザはこのリストからのみ選択可。強制バックエンド設定時は無視。",
        "zh-CN": "非空时用户只能从此列表选择。设置强制后端时忽略。",
        "ko": "비어있지 않으면 사용자는 이 목록에서만 선택 가능. 강제 백엔드 설정 시 무시.",
        "es": "Si no está vacía, los usuarios solo pueden elegir de esta lista. Ignorado si hay backend forzado.",
        "fr": "Si non vide, les utilisateurs ne choisissent que dans cette liste. Ignoré si backend imposé.",
        "de": "Falls nicht leer, dürfen Nutzer nur aus dieser Liste wählen. Ignoriert bei erzwungenem Backend.",
        "pt-BR": "Se não vazio, usuários só escolhem desta lista. Ignorado se houver backend obrigatório.",
    },
    "admin.settings.mp_default_mode": {
        "en": "Default accumulation mode",
        "ja": "既定の蓄積モード",
        "zh-CN": "默认累积模式",
        "ko": "기본 누적 모드",
        "es": "Modo de acumulación por defecto",
        "fr": "Mode d'accumulation par défaut",
        "de": "Standard-Akkumulationsmodus",
        "pt-BR": "Modo de acumulação padrão",
    },
    "admin.settings.mp_default_mode_help": {
        "en": "`accumulate` records every episode + extracted facts. `read_only` silently drops writes (compliance / shared kiosks).",
        "ja": "`accumulate` は全エピソード + 抽出ファクトを記録。`read_only` は書き込みを silent drop (規制対応 / 共有端末向け)。",
        "zh-CN": "`accumulate` 记录所有片段与提取的事实。`read_only` 静默丢弃写入 (合规 / 共享终端)。",
        "ko": "`accumulate` 는 모든 에피소드와 추출 사실을 기록. `read_only` 는 쓰기를 silent drop (규제 / 공용 단말).",
        "es": "`accumulate` graba cada episodio y hechos extraídos. `read_only` descarta escrituras silenciosamente (cumplimiento / kioscos compartidos).",
        "fr": "`accumulate` enregistre chaque épisode + faits extraits. `read_only` ignore silencieusement les écritures (conformité / postes partagés).",
        "de": "`accumulate` schreibt jede Episode + extrahierte Fakten. `read_only` verwirft Schreibvorgänge lautlos (Compliance / geteilte Geräte).",
        "pt-BR": "`accumulate` grava cada episódio + fatos extraídos. `read_only` descarta escritas silenciosamente (conformidade / quiosques compartilhados).",
    },
    "admin.settings.mp_mode.accumulate": {
        "en": "accumulate (default)",
        "ja": "accumulate (蓄積、既定)",
        "zh-CN": "accumulate (累积，默认)",
        "ko": "accumulate (누적, 기본)",
        "es": "accumulate (acumular, por defecto)",
        "fr": "accumulate (accumuler, par défaut)",
        "de": "accumulate (akkumulieren, Standard)",
        "pt-BR": "accumulate (acumular, padrão)",
    },
    "admin.settings.mp_mode.read_only": {
        "en": "read_only (no writes)",
        "ja": "read_only (書き込みなし)",
        "zh-CN": "read_only (不写入)",
        "ko": "read_only (쓰기 없음)",
        "es": "read_only (sin escrituras)",
        "fr": "read_only (sans écritures)",
        "de": "read_only (keine Schreibzugriffe)",
        "pt-BR": "read_only (sem escritas)",
    },
    "admin.settings.mp_mode_locked": {
        "en": "Lock mode (users cannot override)",
        "ja": "モードをロック (ユーザは変更不可)",
        "zh-CN": "锁定模式 (用户不可覆盖)",
        "ko": "모드 잠금 (사용자 변경 불가)",
        "es": "Bloquear modo (los usuarios no pueden cambiarlo)",
        "fr": "Verrouiller le mode (utilisateurs ne peuvent pas changer)",
        "de": "Modus sperren (Nutzer können nicht überschreiben)",
        "pt-BR": "Bloquear modo (usuários não podem sobrescrever)",
    },
    "admin.settings.mp_mode_locked_help": {
        "en": "When checked, every user runs in the default mode set above.",
        "ja": "チェック時、全ユーザが上記の既定モードで動作します。",
        "zh-CN": "勾选后所有用户均按上述默认模式运行。",
        "ko": "체크 시 모든 사용자가 위에 설정한 기본 모드로 동작합니다.",
        "es": "Si se marca, todos los usuarios usan el modo por defecto fijado arriba.",
        "fr": "Si coché, tous les utilisateurs fonctionnent dans le mode par défaut ci-dessus.",
        "de": "Wenn aktiviert, läuft jeder Nutzer im oben definierten Standardmodus.",
        "pt-BR": "Se marcado, todos os usuários rodam no modo padrão acima.",
    },
    "admin.settings.mp_accumulate_locked": {
        "en": "Roles forced to `accumulate`",
        "ja": "`accumulate` 強制対象ロール",
        "zh-CN": "强制 `accumulate` 的角色",
        "ko": "`accumulate` 강제 대상 역할",
        "es": "Roles forzados a `accumulate`",
        "fr": "Rôles forcés à `accumulate`",
        "de": "Rollen gezwungen auf `accumulate`",
        "pt-BR": "Papéis forçados a `accumulate`",
    },
    "admin.settings.mp_accumulate_locked_help": {
        "en": "Selected roles always accumulate, even if they prefer `read_only` (e.g. agents whose memory you want to grow).",
        "ja": "選択したロールは `read_only` を好んでも常に蓄積モード (メモリを成長させたいエージェント役向け)。",
        "zh-CN": "所选角色即便偏好 `read_only` 也始终累积 (适用于需要扩充内存的代理角色)。",
        "ko": "선택된 역할은 `read_only` 를 선호해도 항상 누적 (메모리를 키우고 싶은 에이전트 역할용).",
        "es": "Los roles seleccionados siempre acumulan, aunque prefieran `read_only` (p.ej. agentes cuya memoria quieres crecer).",
        "fr": "Les rôles sélectionnés accumulent toujours, même s'ils préfèrent `read_only` (ex. agents dont la mémoire doit croître).",
        "de": "Ausgewählte Rollen akkumulieren immer, selbst wenn sie `read_only` bevorzugen (z. B. Agentenrollen, deren Speicher wachsen soll).",
        "pt-BR": "Papéis selecionados sempre acumulam, mesmo se preferirem `read_only` (ex.: agentes cuja memória deve crescer).",
    },
    "admin.settings.mp_apply": {
        "en": "Save memory policy",
        "ja": "メモリポリシーを保存",
        "zh-CN": "保存内存策略",
        "ko": "메모리 정책 저장",
        "es": "Guardar política de memoria",
        "fr": "Enregistrer la politique mémoire",
        "de": "Speicher-Richtlinie speichern",
        "pt-BR": "Salvar política de memória",
    },
    "admin.settings.mp_saved": {
        "en": "✅ Memory policy updated.",
        "ja": "✅ メモリポリシーを更新しました。",
        "zh-CN": "✅ 内存策略已更新。",
        "ko": "✅ 메모리 정책을 업데이트했습니다.",
        "es": "✅ Política de memoria actualizada.",
        "fr": "✅ Politique mémoire mise à jour.",
        "de": "✅ Speicher-Richtlinie aktualisiert.",
        "pt-BR": "✅ Política de memória atualizada.",
    },
    "admin.settings.precedence_hint": {
        "en": "Resolution order: process env → `.env` → `.praxia/config.toml`. Editing here writes to the **lowest-precedence** layer, so a key already set in `.env` will not change unless you remove the `.env` line too.",
        "ja": "解決順序: プロセス環境変数 → `.env` → `.praxia/config.toml`。ここでの編集は **最下位の層** に書き込まれるため、`.env` で既に設定済みの値は `.env` 側を消さない限り上書きされません。",
        "zh-CN": "解析顺序: 进程环境变量 → `.env` → `.praxia/config.toml`。此处编辑写入 **最低优先级** 层,如已在 `.env` 中设置则需先移除 `.env` 中的条目。",
        "ko": "해결 순서: 프로세스 환경변수 → `.env` → `.praxia/config.toml`. 여기서의 편집은 **최하위** 레이어에 기록되므로, `.env` 에 이미 설정된 키는 `.env` 항목을 제거하지 않으면 변경되지 않습니다.",
        "es": "Orden de resolución: env del proceso → `.env` → `.praxia/config.toml`. Editar aquí escribe en la capa de **menor prioridad**; una clave ya en `.env` no cambiará a menos que también la borres del `.env`.",
        "fr": "Ordre de résolution: env processus → `.env` → `.praxia/config.toml`. Éditer ici écrit dans la couche de **plus basse priorité** ; une clé déjà dans `.env` ne changera pas tant que vous ne la supprimez pas aussi du `.env`.",
        "de": "Auflösungsreihenfolge: Prozess-Env → `.env` → `.praxia/config.toml`. Bearbeitungen hier landen in der **niedrigsten** Schicht; ein in `.env` gesetzter Key ändert sich nur, wenn du den `.env`-Eintrag ebenfalls entfernst.",
        "pt-BR": "Ordem de resolução: env do processo → `.env` → `.praxia/config.toml`. Editar aqui grava na camada de **menor prioridade**; uma chave já em `.env` não muda a menos que você também remova a linha do `.env`.",
    },
    "admin.settings.keys_label": {
        "en": "keys",
        "ja": "個",
        "zh-CN": "项",
        "ko": "개",
        "es": "claves",
        "fr": "clés",
        "de": "Keys",
        "pt-BR": "chaves",
    },
    "admin.settings.keys_set_label": {
        "en": "set",
        "ja": "件設定済",
        "zh-CN": "项已设置",
        "ko": "개 설정됨",
        "es": "establecidas",
        "fr": "définies",
        "de": "gesetzt",
        "pt-BR": "definidas",
    },
    "admin.settings.help.unset": {
        "en": "Currently unset.",
        "ja": "未設定。",
        "zh-CN": "当前未设置。",
        "ko": "현재 설정되지 않음.",
        "es": "Actualmente sin configurar.",
        "fr": "Actuellement non défini.",
        "de": "Aktuell nicht gesetzt.",
        "pt-BR": "Atualmente não definido.",
    },
    "admin.settings.help.secret_set": {
        "en": "Currently set: {masked}",
        "ja": "現在の値: {masked}",
        "zh-CN": "当前值: {masked}",
        "ko": "현재 값: {masked}",
        "es": "Valor actual: {masked}",
        "fr": "Valeur actuelle : {masked}",
        "de": "Aktueller Wert: {masked}",
        "pt-BR": "Valor atual: {masked}",
    },
    "admin.settings.help.secret_set_masked": {
        "en": "A value is on file. Type a new one to overwrite, or leave blank to keep the existing key.",
        "ja": "値が保存済です。新しい値を入力すると上書き、空欄のままで現在の値を維持します。",
        "zh-CN": "已保存一个值。输入新值会覆盖，留空则保留当前值。",
        "ko": "값이 저장되어 있습니다. 새 값을 입력하면 덮어쓰고, 비워두면 기존 값을 유지합니다.",
        "es": "Hay un valor guardado. Escribe uno nuevo para sobrescribir, o deja en blanco para mantener.",
        "fr": "Une valeur est enregistrée. Tapez une nouvelle valeur pour écraser, ou laissez vide pour garder.",
        "de": "Es ist ein Wert gespeichert. Neuen Wert eingeben zum Überschreiben oder leer lassen zum Behalten.",
        "pt-BR": "Há um valor salvo. Digite um novo para sobrescrever, ou deixe em branco para manter.",
    },
    "admin.settings.help.value_set": {
        "en": "Currently set: {value}",
        "ja": "現在の値: {value}",
        "zh-CN": "当前值: {value}",
        "ko": "현재 값: {value}",
        "es": "Valor actual: {value}",
        "fr": "Valeur actuelle : {value}",
        "de": "Aktueller Wert: {value}",
        "pt-BR": "Valor atual: {value}",
    },
    "admin.settings.placeholder.unchanged": {
        "en": "(leave blank to keep current)",
        "ja": "(空欄で現在値を維持)",
        "zh-CN": "(留空保持当前值)",
        "ko": "(비워두면 현재 값 유지)",
        "es": "(en blanco para mantener)",
        "fr": "(vide pour conserver)",
        "de": "(leer lassen = aktuell behalten)",
        "pt-BR": "(em branco para manter)",
    },
    "admin.settings.save_btn": {
        "en": "Save changes",
        "ja": "変更を保存",
        "zh-CN": "保存更改",
        "ko": "변경 사항 저장",
        "es": "Guardar cambios",
        "fr": "Enregistrer les modifications",
        "de": "Änderungen speichern",
        "pt-BR": "Salvar alterações",
    },
    "admin.settings.save_hint": {
        "en": "Type new values above, then click the button to write them to `.praxia/config.toml` and apply to the running process.",
        "ja": "上の入力欄に新しい値を入れてからボタンを押すと、`.praxia/config.toml` に保存され、起動中のプロセスにも即時反映されます。",
        "zh-CN": "在上方输入新值后点击按钮，将写入 `.praxia/config.toml` 并立即应用到当前进程。",
        "ko": "위에 새 값을 입력한 뒤 버튼을 누르면 `.praxia/config.toml` 에 저장되고 현재 프로세스에도 즉시 반영됩니다.",
        "es": "Introduce los nuevos valores arriba y haz clic en el botón para guardarlos en `.praxia/config.toml` y aplicarlos al proceso actual.",
        "fr": "Saisissez les nouvelles valeurs ci-dessus, puis cliquez pour les écrire dans `.praxia/config.toml` et les appliquer au processus en cours.",
        "de": "Neue Werte oben eingeben, dann den Button drücken — sie werden in `.praxia/config.toml` geschrieben und im laufenden Prozess sofort angewendet.",
        "pt-BR": "Digite os novos valores acima e clique no botão para gravar em `.praxia/config.toml` e aplicar ao processo atual.",
    },
    "admin.settings.delete_checkbox": {
        "en": "🗑 Delete",
        "ja": "🗑 削除",
        "zh-CN": "🗑 删除",
        "ko": "🗑 삭제",
        "es": "🗑 Eliminar",
        "fr": "🗑 Supprimer",
        "de": "🗑 Löschen",
        "pt-BR": "🗑 Excluir",
    },
    "admin.settings.delete_checkbox_help": {
        "en": "Check + Save to remove this key from `.praxia/config.toml`. Process env / `.env` rows are not touched.",
        "ja": "チェックして保存すると、このキーを `.praxia/config.toml` から削除します。プロセス env / `.env` の値は触りません。",
        "zh-CN": "勾选后点击保存即可从 `.praxia/config.toml` 删除该键。进程环境 / `.env` 不受影响。",
        "ko": "체크 후 저장하면 `.praxia/config.toml` 에서 이 키를 삭제합니다. 프로세스 env / `.env` 는 영향 없음.",
        "es": "Marca y Guarda para eliminar esta clave de `.praxia/config.toml`. No afecta a env de proceso ni a `.env`.",
        "fr": "Cochez puis Enregistrer pour supprimer cette clé de `.praxia/config.toml`. N'affecte pas l'env du processus ni `.env`.",
        "de": "Anhaken + Speichern, um diesen Key aus `.praxia/config.toml` zu entfernen. Prozess-Env / `.env` werden nicht angefasst.",
        "pt-BR": "Marque e Salve para remover esta chave de `.praxia/config.toml`. Não afeta env do processo nem `.env`.",
    },
    "admin.settings.deleted": {
        "en": "🗑 {count} key(s) removed from `.praxia/config.toml`.",
        "ja": "🗑 {count} 件のキーを `.praxia/config.toml` から削除しました。",
        "zh-CN": "🗑 已从 `.praxia/config.toml` 删除 {count} 个键。",
        "ko": "🗑 `.praxia/config.toml` 에서 {count} 개의 키를 삭제했습니다.",
        "es": "🗑 {count} clave(s) eliminadas de `.praxia/config.toml`.",
        "fr": "🗑 {count} clé(s) supprimée(s) de `.praxia/config.toml`.",
        "de": "🗑 {count} Key(s) aus `.praxia/config.toml` entfernt.",
        "pt-BR": "🗑 {count} chave(s) removida(s) de `.praxia/config.toml`.",
    },
    # ===== Top-level section headings in the Persistent settings form =====
    "settings.section.llm": {
        "en": "🤖 LLM providers",
        "ja": "🤖 LLM プロバイダ",
        "zh-CN": "🤖 LLM 提供商",
        "ko": "🤖 LLM 프로바이더",
        "es": "🤖 Proveedores LLM",
        "fr": "🤖 Fournisseurs LLM",
        "de": "🤖 LLM-Anbieter",
        "pt-BR": "🤖 Provedores LLM",
    },
    "settings.section.oauth": {
        "en": "🔑 OAuth (per-connector credentials)",
        "ja": "🔑 OAuth (コネクタ毎のクレデンシャル)",
        "zh-CN": "🔑 OAuth (各连接器凭据)",
        "ko": "🔑 OAuth (커넥터별 자격 증명)",
        "es": "🔑 OAuth (credenciales por conector)",
        "fr": "🔑 OAuth (identifiants par connecteur)",
        "de": "🔑 OAuth (Credentials je Connector)",
        "pt-BR": "🔑 OAuth (credenciais por conector)",
    },
    "settings.section.security": {
        "en": "🛡 Security (auth, KMS, SSO, SCIM)",
        "ja": "🛡 セキュリティ (Auth, KMS, SSO, SCIM)",
        "zh-CN": "🛡 安全 (Auth / KMS / SSO / SCIM)",
        "ko": "🛡 보안 (Auth, KMS, SSO, SCIM)",
        "es": "🛡 Seguridad (Auth, KMS, SSO, SCIM)",
        "fr": "🛡 Sécurité (Auth, KMS, SSO, SCIM)",
        "de": "🛡 Sicherheit (Auth, KMS, SSO, SCIM)",
        "pt-BR": "🛡 Segurança (Auth, KMS, SSO, SCIM)",
    },
    "settings.section.runtime": {
        "en": "⚙ Runtime defaults & integrations",
        "ja": "⚙ ランタイム既定値 / 連携",
        "zh-CN": "⚙ 运行时默认与集成",
        "ko": "⚙ 런타임 기본값 / 연동",
        "es": "⚙ Defaults de runtime e integraciones",
        "fr": "⚙ Defaults runtime et intégrations",
        "de": "⚙ Laufzeit-Defaults & Integrationen",
        "pt-BR": "⚙ Defaults de runtime e integrações",
    },
    "settings.section.other": {
        "en": "📦 Other",
        "ja": "📦 その他",
        "zh-CN": "📦 其他",
        "ko": "📦 기타",
        "es": "📦 Otros",
        "fr": "📦 Autres",
        "de": "📦 Sonstiges",
        "pt-BR": "📦 Outros",
    },
    # Identity (CLI / SDK default) — single-key category
    "settings.guide.identity.intro": {
        "en": "**Default user_id for CLI / SDK use.** Praxia tools that aren't part of a logged-in UI session (e.g. `praxia agent run` from a script) need a user_id for memory namespacing. The Streamlit UI ignores this — login provides user_id directly. Leave blank for single-user dev installs.",
        "ja": "**CLI / SDK 使用時のデフォルト user_id**。ログイン UI の外で動く Praxia ツール (`praxia agent run` スクリプト等) はメモリ名前空間用に user_id が必要。Streamlit UI はこの値を使わない (ログインから直接取得)。単独開発環境では空欄で OK。",
        "zh-CN": "**CLI / SDK 使用时的默认 user_id**。在登录 UI 之外运行的 Praxia 工具 (如脚本中的 `praxia agent run`) 需要 user_id 用于内存命名空间。Streamlit UI 不读取此值（直接从登录获取）。单用户开发环境可留空。",
        "ko": "**CLI / SDK 사용 시 기본 user_id**. 로그인 UI 외부에서 실행되는 Praxia 도구 (스크립트의 `praxia agent run` 등) 가 메모리 네임스페이스를 위해 사용. Streamlit UI 는 이 값을 무시 (로그인이 직접 user_id 제공). 단독 개발 환경이면 비워도 OK.",
        "es": "**user_id por defecto para CLI / SDK.** Las herramientas Praxia fuera de una sesión UI (p.ej. `praxia agent run` desde un script) necesitan un user_id para namespacing de memoria. La UI de Streamlit lo ignora — login provee el user_id. En instalaciones single-user dev, déjalo en blanco.",
        "fr": "**user_id par défaut pour CLI / SDK.** Les outils Praxia hors session UI (ex. `praxia agent run` depuis un script) ont besoin d'un user_id pour le namespacing mémoire. L'UI Streamlit l'ignore (le login fournit le user_id). Laissez vide pour une installation dev mono-utilisateur.",
        "de": "**Standard-user_id für CLI / SDK.** Praxia-Tools außerhalb einer UI-Session (z. B. `praxia agent run` aus einem Skript) brauchen eine user_id für Memory-Namespacing. Die Streamlit-UI ignoriert das — Login liefert die user_id direkt. Bei Single-User-Dev leer lassen.",
        "pt-BR": "**user_id padrão para CLI / SDK.** Ferramentas Praxia fora da sessão UI (p.ex. `praxia agent run` de um script) precisam de um user_id para namespacing de memória. A UI Streamlit ignora isso — o login fornece o user_id. Em instalações single-user dev, deixe em branco.",
    },
    "settings.guide.identity.PRAXIA_USER_ID": {
        "en": "Default user_id when none is supplied programmatically. Has no effect on the Streamlit UI.",
        "ja": "プログラムで明示指定されないときに使われる user_id。Streamlit UI には影響しません。",
        "zh-CN": "未通过程序指定时使用的 user_id。不影响 Streamlit UI。",
        "ko": "프로그램에서 user_id 가 명시되지 않을 때 사용되는 기본값. Streamlit UI 에는 영향 없음.",
        "es": "user_id por defecto cuando no se pasa programáticamente. No afecta a la UI de Streamlit.",
        "fr": "user_id par défaut lorsqu'il n'est pas fourni par programmation. N'affecte pas l'UI Streamlit.",
        "de": "Standard-user_id, wenn programmatisch keine angegeben ist. Beeinflusst die Streamlit-UI nicht.",
        "pt-BR": "user_id padrão quando não fornecido programaticamente. Não afeta a UI Streamlit.",
    },
    # ===== Per-category guidance for the Persistent settings form =====
    "admin.settings.keys_required_label": {
        "en": "required keys set",
        "ja": "必須キー設定済",
        "zh-CN": "已设置必填项",
        "ko": "필수 키 설정됨",
        "es": "claves requeridas establecidas",
        "fr": "clés requises définies",
        "de": "Pflicht-Keys gesetzt",
        "pt-BR": "chaves obrigatórias definidas",
    },
    "admin.settings.required_label": {
        "en": "Required keys (must be set together)",
        "ja": "必須キー (まとめて設定が必要)",
        "zh-CN": "必填项（需一起配置）",
        "ko": "필수 키 (모두 설정 필요)",
        "es": "Claves requeridas (deben configurarse juntas)",
        "fr": "Clés requises (à définir ensemble)",
        "de": "Pflicht-Keys (müssen gemeinsam gesetzt werden)",
        "pt-BR": "Chaves obrigatórias (configurar juntas)",
    },
    "admin.settings.cross_ref_label": {
        "en": "Also needs {keys} (set under another section).",
        "ja": "{keys} も必要 (別セクションで設定)。",
        "zh-CN": "另需 {keys}（在其他分组中设置）。",
        "ko": "{keys} 도 필요합니다 (다른 섹션에서 설정).",
        "es": "También requiere {keys} (configurado en otra sección).",
        "fr": "Nécessite aussi {keys} (défini dans une autre section).",
        "de": "Benötigt zusätzlich {keys} (in einem anderen Abschnitt gesetzt).",
        "pt-BR": "Também precisa de {keys} (definido em outra seção).",
    },

    # --- LLM · OpenAI ---
    "settings.guide.openai.intro": {
        "en": "**OpenAI** GPT-5.x / GPT-4o / o-series via api.openai.com. Direct OpenAI billing.",
        "ja": "**OpenAI** GPT-5.x / GPT-4o / o-series を api.openai.com 経由で利用。OpenAI 直契約。",
        "zh-CN": "**OpenAI** 通过 api.openai.com 调用 GPT-5.x / GPT-4o / o 系列。OpenAI 直接计费。",
        "ko": "**OpenAI** GPT-5.x / GPT-4o / o-series를 api.openai.com 으로 호출. OpenAI 직접 청구.",
        "es": "**OpenAI** GPT-5.x / GPT-4o / o-series vía api.openai.com. Facturación directa de OpenAI.",
        "fr": "**OpenAI** GPT-5.x / GPT-4o / o-series via api.openai.com. Facturation OpenAI directe.",
        "de": "**OpenAI** GPT-5.x / GPT-4o / o-Serie via api.openai.com. Direkte OpenAI-Abrechnung.",
        "pt-BR": "**OpenAI** GPT-5.x / GPT-4o / o-series via api.openai.com. Cobrança direta da OpenAI.",
    },
    "settings.guide.openai.OPENAI_API_KEY": {
        "en": "Get from platform.openai.com → API keys. Starts with `sk-`. **Not** for Azure OpenAI.",
        "ja": "platform.openai.com → API keys で取得。`sk-` で始まる。**Azure OpenAI 用ではない**。",
        "zh-CN": "从 platform.openai.com → API keys 获取。以 `sk-` 开头。**不适用于 Azure OpenAI**。",
        "ko": "platform.openai.com → API keys 에서 발급. `sk-` 로 시작. **Azure OpenAI 용 아님**.",
        "es": "Obtén en platform.openai.com → API keys. Empieza con `sk-`. **No** para Azure OpenAI.",
        "fr": "Récupérez sur platform.openai.com → API keys. Commence par `sk-`. **Pas** pour Azure OpenAI.",
        "de": "Von platform.openai.com → API keys. Beginnt mit `sk-`. **Nicht** für Azure OpenAI.",
        "pt-BR": "Obter em platform.openai.com → API keys. Começa com `sk-`. **Não** é para Azure OpenAI.",
    },

    # --- LLM · Anthropic ---
    "settings.guide.anthropic.intro": {
        "en": "**Anthropic Claude** (Opus / Sonnet / Haiku) via api.anthropic.com. For Bedrock-hosted Claude use the AWS Bedrock section instead.",
        "ja": "**Anthropic Claude** (Opus / Sonnet / Haiku) を api.anthropic.com 経由で利用。Bedrock 経由の Claude を使う場合は AWS Bedrock セクションを使ってください。",
        "zh-CN": "**Anthropic Claude** (Opus / Sonnet / Haiku) 通过 api.anthropic.com。Bedrock 部署的 Claude 请使用 AWS Bedrock 分组。",
        "ko": "**Anthropic Claude** (Opus / Sonnet / Haiku) 를 api.anthropic.com 경유. Bedrock 호스팅 Claude 는 AWS Bedrock 섹션을 사용하세요.",
        "es": "**Anthropic Claude** (Opus / Sonnet / Haiku) vía api.anthropic.com. Para Claude en Bedrock usa la sección AWS Bedrock.",
        "fr": "**Anthropic Claude** (Opus / Sonnet / Haiku) via api.anthropic.com. Pour Claude sur Bedrock utilisez la section AWS Bedrock.",
        "de": "**Anthropic Claude** (Opus / Sonnet / Haiku) via api.anthropic.com. Für Bedrock-Claude nutze stattdessen den AWS-Bedrock-Abschnitt.",
        "pt-BR": "**Anthropic Claude** (Opus / Sonnet / Haiku) via api.anthropic.com. Para Claude no Bedrock use a seção AWS Bedrock.",
    },
    "settings.guide.anthropic.ANTHROPIC_API_KEY": {
        "en": "Get from console.anthropic.com → Settings → API keys. Starts with `sk-ant-`.",
        "ja": "console.anthropic.com → Settings → API keys で取得。`sk-ant-` で始まる。",
        "zh-CN": "从 console.anthropic.com → Settings → API keys 获取。以 `sk-ant-` 开头。",
        "ko": "console.anthropic.com → Settings → API keys 에서 발급. `sk-ant-` 로 시작.",
        "es": "Obtén en console.anthropic.com → Settings → API keys. Empieza con `sk-ant-`.",
        "fr": "Récupérez sur console.anthropic.com → Settings → API keys. Commence par `sk-ant-`.",
        "de": "Von console.anthropic.com → Settings → API keys. Beginnt mit `sk-ant-`.",
        "pt-BR": "Obter em console.anthropic.com → Settings → API keys. Começa com `sk-ant-`.",
    },

    # --- LLM · Azure OpenAI ---
    "settings.guide.azure_openai.intro": {
        "en": "**Azure OpenAI Service** — OpenAI's GPT models hosted on Azure. Use this if your org bought Azure OpenAI deployments. **All three keys below are required together.** Different from Foundry's multi-vendor inference endpoint.",
        "ja": "**Azure OpenAI Service** — Azure 上の OpenAI GPT。組織で Azure OpenAI デプロイメントを契約している場合に使用。**下の 3 つすべてセットで必須**。Foundry のマルチベンダー inference エンドポイントとは別物。",
        "zh-CN": "**Azure OpenAI Service** — 部署在 Azure 上的 OpenAI GPT。组织购买了 Azure OpenAI 部署时使用。**下方三项必须一起设置**。与 Foundry 多厂商推理端点不同。",
        "ko": "**Azure OpenAI Service** — Azure 에 배포된 OpenAI GPT. 조직이 Azure OpenAI 배포를 구매한 경우 사용. **아래 세 항목 모두 필수**. Foundry 멀티벤더 inference 엔드포인트와는 다름.",
        "es": "**Azure OpenAI Service** — modelos GPT de OpenAI en Azure. Úsalo si tu org tiene despliegues de Azure OpenAI. **Las tres claves son obligatorias juntas.** Distinto del endpoint multivendor de Foundry.",
        "fr": "**Azure OpenAI Service** — modèles GPT d'OpenAI sur Azure. À utiliser si votre org a des déploiements Azure OpenAI. **Les trois clés sont requises ensemble.** Différent de l'endpoint multivendeur de Foundry.",
        "de": "**Azure OpenAI Service** — OpenAI GPT-Modelle auf Azure. Nutze dies, wenn deine Org Azure-OpenAI-Deployments hat. **Alle drei Keys sind gemeinsam erforderlich.** Anders als der Multi-Vendor-Inference-Endpunkt von Foundry.",
        "pt-BR": "**Azure OpenAI Service** — modelos GPT da OpenAI no Azure. Use se sua org tem deployments do Azure OpenAI. **As três chaves são obrigatórias juntas.** Diferente do endpoint multifornecedor do Foundry.",
    },
    "settings.guide.azure_openai.AZURE_API_KEY": {
        "en": "From Azure portal → your Azure OpenAI resource → Keys and Endpoint → KEY 1 or KEY 2. **Not** the same as your platform.openai.com key.",
        "ja": "Azure ポータル → Azure OpenAI リソース → Keys and Endpoint → KEY 1 または KEY 2。**platform.openai.com のキーとは別物**。",
        "zh-CN": "Azure 门户 → 你的 Azure OpenAI 资源 → Keys and Endpoint → KEY 1 或 KEY 2。**与 platform.openai.com 的密钥不同**。",
        "ko": "Azure 포털 → Azure OpenAI 리소스 → Keys and Endpoint → KEY 1 또는 KEY 2. **platform.openai.com 키와 다름**.",
        "es": "Portal de Azure → tu recurso Azure OpenAI → Keys and Endpoint → KEY 1 o KEY 2. **No** es la misma que la clave de platform.openai.com.",
        "fr": "Portail Azure → ressource Azure OpenAI → Keys and Endpoint → KEY 1 ou KEY 2. **Différente** de la clé platform.openai.com.",
        "de": "Azure-Portal → Azure-OpenAI-Ressource → Keys and Endpoint → KEY 1 oder KEY 2. **Nicht** dasselbe wie der Key von platform.openai.com.",
        "pt-BR": "Portal Azure → recurso Azure OpenAI → Keys and Endpoint → KEY 1 ou KEY 2. **Não** é a mesma chave de platform.openai.com.",
    },
    "settings.guide.azure_openai.AZURE_API_BASE": {
        "en": "Endpoint URL from the same screen. Format: `https://<your-resource>.openai.azure.com/` (trailing slash matters).",
        "ja": "同画面の Endpoint URL。形式: `https://<your-resource>.openai.azure.com/` (末尾スラッシュ必要)。",
        "zh-CN": "同界面的 Endpoint URL。格式: `https://<your-resource>.openai.azure.com/`（结尾斜杠不可少）。",
        "ko": "같은 화면의 Endpoint URL. 형식: `https://<your-resource>.openai.azure.com/` (끝의 슬래시 중요).",
        "es": "URL del endpoint en la misma pantalla. Formato: `https://<recurso>.openai.azure.com/` (la barra final importa).",
        "fr": "URL d'endpoint depuis le même écran. Format : `https://<ressource>.openai.azure.com/` (slash final requis).",
        "de": "Endpoint-URL aus demselben Bildschirm. Format: `https://<resource>.openai.azure.com/` (Schrägstrich am Ende wichtig).",
        "pt-BR": "URL do endpoint da mesma tela. Formato: `https://<resource>.openai.azure.com/` (barra final importa).",
    },
    "settings.guide.azure_openai.AZURE_API_VERSION": {
        "en": "Latest stable preview, e.g. `2024-08-01-preview` or `2024-12-01-preview`. Check Azure docs for current value.",
        "ja": "最新の preview バージョン、例: `2024-08-01-preview` / `2024-12-01-preview`。最新値は Azure ドキュメント参照。",
        "zh-CN": "最新预览版本，如 `2024-08-01-preview` 或 `2024-12-01-preview`。最新值参见 Azure 文档。",
        "ko": "최신 preview 버전, 예: `2024-08-01-preview` / `2024-12-01-preview`. 최신값은 Azure 문서 참조.",
        "es": "Última versión preview, p.ej. `2024-08-01-preview` o `2024-12-01-preview`. Revisa los docs de Azure.",
        "fr": "Dernière version preview, ex. `2024-08-01-preview` ou `2024-12-01-preview`. Voir les docs Azure.",
        "de": "Neueste Preview-Version, z. B. `2024-08-01-preview` oder `2024-12-01-preview`. Aktueller Wert in Azure-Docs.",
        "pt-BR": "Última versão preview, p.ex. `2024-08-01-preview` ou `2024-12-01-preview`. Veja a documentação Azure.",
    },

    # --- LLM · Azure AI Foundry ---
    "settings.guide.azure_ai.intro": {
        "en": "**Azure AI Foundry inference endpoint** — for non-OpenAI models on Azure (Mistral / Llama / Phi / Cohere / DeepSeek / custom Foundry deployments). If you only use OpenAI GPT, you don't need this section — use Azure OpenAI above instead.",
        "ja": "**Azure AI Foundry の推論エンドポイント** — Azure 上の非 OpenAI モデル用 (Mistral / Llama / Phi / Cohere / DeepSeek / Foundry カスタムデプロイ等)。OpenAI GPT しか使わないなら本セクションは不要、上の Azure OpenAI を使ってください。",
        "zh-CN": "**Azure AI Foundry 推理端点** — Azure 上非 OpenAI 模型 (Mistral / Llama / Phi / Cohere / DeepSeek / 自定义 Foundry 部署)。如果只用 OpenAI GPT，无需本节，使用上方 Azure OpenAI。",
        "ko": "**Azure AI Foundry 추론 엔드포인트** — Azure 의 비 OpenAI 모델용 (Mistral / Llama / Phi / Cohere / DeepSeek / 커스텀 Foundry 배포). OpenAI GPT 만 쓴다면 이 섹션은 불필요, 위의 Azure OpenAI 사용.",
        "es": "**Endpoint de inferencia de Azure AI Foundry** — para modelos no-OpenAI en Azure (Mistral / Llama / Phi / Cohere / DeepSeek / Foundry custom). Si solo usas OpenAI GPT, no necesitas esta sección.",
        "fr": "**Endpoint d'inférence Azure AI Foundry** — pour les modèles non-OpenAI sur Azure (Mistral / Llama / Phi / Cohere / DeepSeek / déploiements Foundry custom). Si vous n'utilisez que OpenAI GPT, cette section n'est pas nécessaire.",
        "de": "**Azure-AI-Foundry-Inference-Endpunkt** — für Nicht-OpenAI-Modelle auf Azure (Mistral / Llama / Phi / Cohere / DeepSeek / eigene Foundry-Deployments). Wer nur OpenAI GPT nutzt, braucht diesen Abschnitt nicht.",
        "pt-BR": "**Endpoint de inferência do Azure AI Foundry** — para modelos não-OpenAI no Azure (Mistral / Llama / Phi / Cohere / DeepSeek / deployments custom do Foundry). Se você só usa OpenAI GPT, esta seção é desnecessária.",
    },
    "settings.guide.azure_ai.AZURE_AI_API_KEY": {
        "en": "Foundry endpoint key from Azure AI Foundry → your endpoint → Keys.",
        "ja": "Azure AI Foundry → エンドポイント → Keys のキー。",
        "zh-CN": "Azure AI Foundry → 你的端点 → Keys 中的密钥。",
        "ko": "Azure AI Foundry → 엔드포인트 → Keys 의 키.",
        "es": "Clave del endpoint en Azure AI Foundry → tu endpoint → Keys.",
        "fr": "Clé de l'endpoint dans Azure AI Foundry → votre endpoint → Keys.",
        "de": "Endpoint-Key aus Azure AI Foundry → dein Endpoint → Keys.",
        "pt-BR": "Chave do endpoint em Azure AI Foundry → seu endpoint → Keys.",
    },
    "settings.guide.azure_ai.AZURE_AI_API_BASE": {
        "en": "Foundry endpoint URL, e.g. `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
        "ja": "Foundry エンドポイント URL、例: `https://<endpoint-name>.<region>.inference.ai.azure.com/`。",
        "zh-CN": "Foundry 端点 URL，如 `https://<endpoint-name>.<region>.inference.ai.azure.com/`。",
        "ko": "Foundry 엔드포인트 URL, 예: `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
        "es": "URL del endpoint Foundry, p.ej. `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
        "fr": "URL de l'endpoint Foundry, ex. `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
        "de": "Foundry-Endpoint-URL, z. B. `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
        "pt-BR": "URL do endpoint Foundry, p.ex. `https://<endpoint-name>.<region>.inference.ai.azure.com/`.",
    },

    # --- LLM · AWS Bedrock ---
    "settings.guide.aws_bedrock.intro": {
        "en": "**AWS Bedrock** — Anthropic Claude / Llama / Mistral / Cohere / Amazon Nova on AWS infra. Authenticates with **AWS IAM** (not an Anthropic key). Required: access-key pair. Region is shared with the KMS section — same `AWS_REGION` works for both.",
        "ja": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova を AWS 上で利用。**AWS IAM 認証** (Anthropic キーは使わない)。必須はアクセスキーのペア。リージョンは KMS セクションと共用 (`AWS_REGION` 1 つで両方 OK)。",
        "zh-CN": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova 部署在 AWS 上。使用 **AWS IAM 凭证** (不是 Anthropic 密钥)。必填: 访问密钥对。区域与 KMS 分组共用 — 一个 `AWS_REGION` 即可。",
        "ko": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova 를 AWS 인프라로. **AWS IAM 인증** (Anthropic 키 아님). 필수: 액세스 키 쌍. 리전은 KMS 섹션과 공유 — `AWS_REGION` 하나로 양쪽 적용.",
        "es": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova en infra de AWS. Autentica con **AWS IAM** (no clave Anthropic). Requerido: par de access keys. La región se comparte con KMS — un mismo `AWS_REGION` sirve.",
        "fr": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova sur infra AWS. Authentification **AWS IAM** (pas une clé Anthropic). Requis : paire de clés d'accès. La région est partagée avec KMS — un même `AWS_REGION`.",
        "de": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova auf AWS-Infrastruktur. Authentifiziert via **AWS IAM** (kein Anthropic-Key). Pflicht: Access-Key-Paar. Region geteilt mit KMS — ein `AWS_REGION` reicht.",
        "pt-BR": "**AWS Bedrock** — Claude / Llama / Mistral / Cohere / Amazon Nova em infra AWS. Autentica via **AWS IAM** (não é chave Anthropic). Obrigatório: par de access keys. Região compartilhada com KMS — um `AWS_REGION` serve.",
    },
    "settings.guide.aws_bedrock.AWS_ACCESS_KEY_ID": {
        "en": "From AWS console → IAM → Users → your user → Security credentials → Create access key. Format: `AKIA...` (20 chars). The IAM user/role needs `bedrock:InvokeModel` permission.",
        "ja": "AWS コンソール → IAM → Users → 該当ユーザ → Security credentials → Create access key で発行。形式: `AKIA...` (20 文字)。IAM ユーザ/ロールに `bedrock:InvokeModel` 権限が必要。",
        "zh-CN": "AWS 控制台 → IAM → Users → 用户 → Security credentials → Create access key。格式: `AKIA...`（20 字符）。IAM 用户/角色需要 `bedrock:InvokeModel` 权限。",
        "ko": "AWS 콘솔 → IAM → Users → 해당 사용자 → Security credentials → Create access key. 형식: `AKIA...` (20 자). IAM 사용자/역할에 `bedrock:InvokeModel` 권한 필요.",
        "es": "Consola AWS → IAM → Users → tu usuario → Security credentials → Create access key. Formato: `AKIA...` (20 caracteres). El usuario/rol IAM necesita permiso `bedrock:InvokeModel`.",
        "fr": "Console AWS → IAM → Users → votre utilisateur → Security credentials → Create access key. Format : `AKIA...` (20 caractères). L'utilisateur/rôle IAM doit avoir `bedrock:InvokeModel`.",
        "de": "AWS-Konsole → IAM → Users → dein Nutzer → Security credentials → Create access key. Format: `AKIA...` (20 Zeichen). IAM-User/-Role braucht `bedrock:InvokeModel`-Berechtigung.",
        "pt-BR": "Console AWS → IAM → Users → seu usuário → Security credentials → Create access key. Formato: `AKIA...` (20 caracteres). O usuário/role IAM precisa da permissão `bedrock:InvokeModel`.",
    },
    "settings.guide.aws_bedrock.AWS_SECRET_ACCESS_KEY": {
        "en": "Pair with the access key ID. Shown once when you create the access key — copy it then. ~40 char base64-ish string.",
        "ja": "上記アクセスキー ID とペア。アクセスキー作成時に 1 回だけ表示されるのでその場でコピー必須。base64 風 40 文字程度。",
        "zh-CN": "与 access key ID 配对。创建访问密钥时只显示一次，必须当场复制。base64 风格约 40 字符。",
        "ko": "위 access key ID 와 짝. 액세스 키 생성 시 한 번만 표시되므로 즉시 복사. base64 스타일 약 40 자.",
        "es": "Empareja con el access key ID. Solo se muestra al crear la clave — cópialo en ese momento. ~40 caracteres tipo base64.",
        "fr": "Associé à l'access key ID. Affiché une seule fois lors de la création — copiez-le à ce moment. ~40 caractères type base64.",
        "de": "Gehört zur Access-Key-ID. Wird nur einmal beim Erstellen angezeigt — sofort kopieren. ~40 Zeichen, base64-ähnlich.",
        "pt-BR": "Par com o access key ID. Mostrado uma vez ao criar a chave — copie na hora. ~40 caracteres tipo base64.",
    },
    "settings.guide.aws_bedrock.AWS_SESSION_TOKEN": {
        "en": "**Optional.** Only when you authenticate via AWS STS / AssumeRole / SSO temporary credentials. Long-lived IAM users don't need this.",
        "ja": "**任意。** AWS STS / AssumeRole / SSO 一時クレデンシャル使用時のみ。長寿命 IAM ユーザでは不要。",
        "zh-CN": "**可选。** 仅在使用 AWS STS / AssumeRole / SSO 临时凭证时填写。长期 IAM 用户无需。",
        "ko": "**선택.** AWS STS / AssumeRole / SSO 임시 자격 증명 사용 시에만. 장기 IAM 사용자는 불필요.",
        "es": "**Opcional.** Solo cuando autenticas con AWS STS / AssumeRole / credenciales temporales SSO. Usuarios IAM permanentes no lo necesitan.",
        "fr": "**Optionnel.** Uniquement avec AWS STS / AssumeRole / credentials temporaires SSO. Inutile pour les utilisateurs IAM permanents.",
        "de": "**Optional.** Nur bei AWS STS / AssumeRole / SSO-Kurzzeit-Credentials. Permanente IAM-User brauchen das nicht.",
        "pt-BR": "**Opcional.** Apenas com AWS STS / AssumeRole / credenciais temporárias SSO. Usuários IAM permanentes não precisam.",
    },
    "settings.guide.aws_bedrock.AWS_BEDROCK_RUNTIME_ENDPOINT": {
        "en": "**Optional.** Override the default Bedrock URL — typically only when you connect via VPC PrivateLink. Leave blank for the default public endpoint.",
        "ja": "**任意。** Bedrock の URL を上書き — VPC PrivateLink 経由のときのみ通常使用。デフォルトの公開エンドポイントを使うなら空欄。",
        "zh-CN": "**可选。** 覆盖 Bedrock 默认 URL — 通常仅在通过 VPC PrivateLink 接入时使用。使用默认公开端点请留空。",
        "ko": "**선택.** Bedrock 기본 URL 오버라이드 — 일반적으로 VPC PrivateLink 사용 시에만. 기본 공개 엔드포인트는 비워두기.",
        "es": "**Opcional.** Sobrescribe la URL por defecto de Bedrock — típicamente solo con VPC PrivateLink. Déjalo en blanco para el endpoint público.",
        "fr": "**Optionnel.** Remplace l'URL Bedrock par défaut — typiquement uniquement avec VPC PrivateLink. Laissez vide pour l'endpoint public par défaut.",
        "de": "**Optional.** Überschreibt die Standard-Bedrock-URL — meist nur bei VPC PrivateLink nötig. Für Standard-Endpoint leer lassen.",
        "pt-BR": "**Opcional.** Sobrescreve a URL padrão do Bedrock — tipicamente só com VPC PrivateLink. Deixe em branco para o endpoint público padrão.",
    },

    # --- LLM · Google ---
    "settings.guide.google.intro": {
        "en": "**Google Gemini.** Use `GEMINI_API_KEY` for the public Gemini API (aistudio.google.com). For Vertex AI (production GCP) use `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS` instead — pick one path, not both.",
        "ja": "**Google Gemini**。一般 Gemini API (aistudio.google.com) は `GEMINI_API_KEY`。Vertex AI (本番 GCP) は `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS` の 3 点セット。**どちらか片方** を選択 (両方は不要)。",
        "zh-CN": "**Google Gemini**。公共 Gemini API（aistudio.google.com）用 `GEMINI_API_KEY`。Vertex AI（生产 GCP）用 `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS`。**只选一种**路径。",
        "ko": "**Google Gemini**. 일반 Gemini API (aistudio.google.com) 는 `GEMINI_API_KEY`. Vertex AI (프로덕션 GCP) 는 `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS` 세 항목. **둘 중 하나** 만 선택.",
        "es": "**Google Gemini.** Usa `GEMINI_API_KEY` para la API pública (aistudio.google.com). Para Vertex AI (GCP producción) usa `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS`. Elige **un solo** camino.",
        "fr": "**Google Gemini.** Utilisez `GEMINI_API_KEY` pour l'API publique (aistudio.google.com). Pour Vertex AI (GCP prod) utilisez `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS`. Choisissez **un seul** chemin.",
        "de": "**Google Gemini.** Nutze `GEMINI_API_KEY` für die öffentliche Gemini-API (aistudio.google.com). Für Vertex AI (produktives GCP) `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS`. **Nur einen Weg** wählen.",
        "pt-BR": "**Google Gemini.** Use `GEMINI_API_KEY` para a API pública (aistudio.google.com). Para Vertex AI (GCP produção) use `VERTEX_PROJECT` + `VERTEX_LOCATION` + `GOOGLE_APPLICATION_CREDENTIALS`. Escolha **um só** caminho.",
    },
    "settings.guide.google.GEMINI_API_KEY": {
        "en": "Get from aistudio.google.com → Get API key. For the consumer Gemini API.",
        "ja": "aistudio.google.com → Get API key で取得。コンシューマ Gemini API 用。",
        "zh-CN": "从 aistudio.google.com → Get API key 获取。用于消费级 Gemini API。",
        "ko": "aistudio.google.com → Get API key 에서 발급. 컨슈머 Gemini API 용.",
        "es": "Obtén en aistudio.google.com → Get API key. Para la API Gemini consumer.",
        "fr": "Récupérez sur aistudio.google.com → Get API key. Pour l'API Gemini consumer.",
        "de": "Von aistudio.google.com → Get API key. Für die Consumer-Gemini-API.",
        "pt-BR": "Obter em aistudio.google.com → Get API key. Para a API Gemini consumer.",
    },
    "settings.guide.google.VERTEX_PROJECT": {
        "en": "GCP project ID (e.g. `my-praxia-prod`). Required for Vertex AI path.",
        "ja": "GCP プロジェクト ID (例: `my-praxia-prod`)。Vertex AI 経由のとき必須。",
        "zh-CN": "GCP 项目 ID（如 `my-praxia-prod`）。Vertex AI 路径必填。",
        "ko": "GCP 프로젝트 ID (예: `my-praxia-prod`). Vertex AI 경로 시 필수.",
        "es": "ID del proyecto GCP (p.ej. `my-praxia-prod`). Requerido para Vertex AI.",
        "fr": "ID du projet GCP (ex. `my-praxia-prod`). Requis pour Vertex AI.",
        "de": "GCP-Projekt-ID (z. B. `my-praxia-prod`). Pflicht für den Vertex-AI-Weg.",
        "pt-BR": "ID do projeto GCP (p.ex. `my-praxia-prod`). Obrigatório para Vertex AI.",
    },
    "settings.guide.google.VERTEX_LOCATION": {
        "en": "GCP region with Gemini availability, e.g. `us-central1` / `europe-west4` / `asia-northeast1`.",
        "ja": "Gemini が利用可能な GCP リージョン、例: `us-central1` / `europe-west4` / `asia-northeast1`。",
        "zh-CN": "支持 Gemini 的 GCP 区域，如 `us-central1` / `europe-west4` / `asia-northeast1`。",
        "ko": "Gemini 가용 GCP 리전, 예: `us-central1` / `europe-west4` / `asia-northeast1`.",
        "es": "Región GCP con Gemini, p.ej. `us-central1` / `europe-west4` / `asia-northeast1`.",
        "fr": "Région GCP avec Gemini, ex. `us-central1` / `europe-west4` / `asia-northeast1`.",
        "de": "GCP-Region mit Gemini-Verfügbarkeit, z. B. `us-central1` / `europe-west4` / `asia-northeast1`.",
        "pt-BR": "Região GCP com Gemini, p.ex. `us-central1` / `europe-west4` / `asia-northeast1`.",
    },
    "settings.guide.google.GOOGLE_APPLICATION_CREDENTIALS": {
        "en": "**Absolute path** to a service-account JSON file (NOT the JSON content). The service account needs the `Vertex AI User` role on the project.",
        "ja": "サービスアカウント JSON ファイルへの **絶対パス** (JSON 内容ではない)。アカウントにプロジェクト上の `Vertex AI User` ロールが必要。",
        "zh-CN": "服务账号 JSON 文件的 **绝对路径**（不是 JSON 内容）。该服务账号需在项目上具备 `Vertex AI User` 角色。",
        "ko": "서비스 계정 JSON 파일의 **절대 경로** (JSON 내용 아님). 서비스 계정은 프로젝트에서 `Vertex AI User` 역할이 필요.",
        "es": "**Ruta absoluta** al archivo JSON de la cuenta de servicio (NO el contenido JSON). La cuenta necesita el rol `Vertex AI User` en el proyecto.",
        "fr": "**Chemin absolu** vers le fichier JSON du compte de service (PAS le contenu JSON). Le compte doit avoir le rôle `Vertex AI User` sur le projet.",
        "de": "**Absoluter Pfad** zur Service-Account-JSON-Datei (nicht der JSON-Inhalt). Der Service Account benötigt die Rolle `Vertex AI User` im Projekt.",
        "pt-BR": "**Caminho absoluto** para o arquivo JSON da conta de serviço (NÃO o conteúdo). A conta precisa do papel `Vertex AI User` no projeto.",
    },

    # --- LLM · Local (Ollama) ---
    "settings.guide.ollama.intro": {
        "en": "**Ollama (local)** — runs models like Llama / Qwen / Gemma / Phi locally. Defaults work for a stock Ollama install on `localhost:11434`. No API key needed.",
        "ja": "**Ollama (ローカル)** — Llama / Qwen / Gemma / Phi 等をローカルで実行。`localhost:11434` の標準インストールならデフォルトのまま動作。API キー不要。",
        "zh-CN": "**Ollama 本地** — 在本机运行 Llama / Qwen / Gemma / Phi 等。`localhost:11434` 默认安装无需修改。无需 API Key。",
        "ko": "**Ollama (로컬)** — Llama / Qwen / Gemma / Phi 등을 로컬 실행. `localhost:11434` 기본 설치라면 그대로 동작. API 키 불필요.",
        "es": "**Ollama (local)** — ejecuta Llama / Qwen / Gemma / Phi localmente. Los valores por defecto sirven para una instalación estándar en `localhost:11434`. No requiere API key.",
        "fr": "**Ollama (local)** — exécute Llama / Qwen / Gemma / Phi localement. Les valeurs par défaut conviennent à une installation standard sur `localhost:11434`. Pas de clé API.",
        "de": "**Ollama (lokal)** — führt Llama / Qwen / Gemma / Phi lokal aus. Defaults passen für Standard-Installation auf `localhost:11434`. Kein API-Key nötig.",
        "pt-BR": "**Ollama (local)** — roda Llama / Qwen / Gemma / Phi localmente. Os defaults servem para instalação padrão em `localhost:11434`. Sem API key.",
    },
    "settings.guide.ollama.OLLAMA_API_BASE": {
        "en": "Override the default `http://localhost:11434`. Set this only if Ollama runs on another host or port.",
        "ja": "デフォルト `http://localhost:11434` を上書き。別ホスト / ポートで動かしているときのみ設定。",
        "zh-CN": "覆盖默认 `http://localhost:11434`。仅在 Ollama 运行于其他主机或端口时设置。",
        "ko": "기본 `http://localhost:11434` 오버라이드. 다른 호스트/포트에서 Ollama 가 동작할 때만 설정.",
        "es": "Sobrescribe el predeterminado `http://localhost:11434`. Solo si Ollama corre en otro host/puerto.",
        "fr": "Remplace `http://localhost:11434`. Uniquement si Ollama tourne sur un autre hôte / port.",
        "de": "Überschreibt den Standard `http://localhost:11434`. Nur wenn Ollama auf anderem Host/Port läuft.",
        "pt-BR": "Sobrescreve o padrão `http://localhost:11434`. Só se o Ollama rodar em outro host/porta.",
    },
    "settings.guide.ollama.PRAXIA_LOCAL_MODEL": {
        "en": "Optional — override the default local-model alias when no cloud key is available. e.g. `qwen-72b` / `llama-local`.",
        "ja": "任意 — クラウドキーが無いときに使われるローカルモデルのエイリアスを上書き。例: `qwen-72b` / `llama-local`。",
        "zh-CN": "可选 — 没有云端密钥时使用的本地模型别名。如 `qwen-72b` / `llama-local`。",
        "ko": "선택 — 클라우드 키가 없을 때 사용하는 로컬 모델 별칭 오버라이드. 예: `qwen-72b` / `llama-local`.",
        "es": "Opcional — sobrescribe el alias de modelo local usado cuando no hay clave en la nube. P.ej. `qwen-72b` / `llama-local`.",
        "fr": "Optionnel — remplace l'alias du modèle local utilisé quand aucune clé cloud n'est disponible. Ex. `qwen-72b` / `llama-local`.",
        "de": "Optional — überschreibt den Default-Local-Model-Alias, wenn kein Cloud-Key verfügbar ist. Z. B. `qwen-72b` / `llama-local`.",
        "pt-BR": "Opcional — sobrescreve o alias do modelo local usado quando não há chave cloud. P.ex. `qwen-72b` / `llama-local`.",
    },

    # --- KMS ---
    "settings.guide.kms.intro": {
        "en": "**KMS adapter** — encrypts OAuth tokens at rest with envelope encryption. `local` uses an in-process key (dev only). For prod, pick `aws` / `azure` / `gcp` / `vault` and fill the matching fields below.",
        "ja": "**KMS アダプタ** — OAuth トークンを envelope 暗号化で保存時暗号化。`local` はインプロセス鍵 (開発専用)。本番は `aws` / `azure` / `gcp` / `vault` から選択し下の該当フィールドを設定。",
        "zh-CN": "**KMS 适配器** — 通过信封加密加密静态 OAuth 令牌。`local` 使用进程内密钥（仅开发）。生产环境选 `aws` / `azure` / `gcp` / `vault` 并填写下面相应字段。",
        "ko": "**KMS 어댑터** — OAuth 토큰을 envelope 암호화로 저장. `local` 은 프로세스 내부 키 (개발 전용). 프로덕션은 `aws` / `azure` / `gcp` / `vault` 중 선택 후 아래 해당 필드 설정.",
        "es": "**Adaptador KMS** — cifra tokens OAuth en reposo con envelope encryption. `local` usa una clave en proceso (solo dev). En producción usa `aws` / `azure` / `gcp` / `vault` y rellena los campos correspondientes.",
        "fr": "**Adaptateur KMS** — chiffre les tokens OAuth au repos via envelope encryption. `local` utilise une clé en mémoire (dev). En prod, choisissez `aws` / `azure` / `gcp` / `vault` et remplissez les champs.",
        "de": "**KMS-Adapter** — verschlüsselt OAuth-Tokens at-rest per Envelope-Encryption. `local` nutzt einen In-Process-Key (nur Dev). Für Prod `aws` / `azure` / `gcp` / `vault` wählen und entsprechende Felder ausfüllen.",
        "pt-BR": "**Adaptador KMS** — cifra tokens OAuth em repouso via envelope encryption. `local` usa chave em processo (só dev). Em produção use `aws` / `azure` / `gcp` / `vault` e preencha os campos.",
    },
    "settings.guide.kms.PRAXIA_KMS_ADAPTER": {
        "en": "One of: `local` / `aws` / `azure` / `gcp` / `vault`.",
        "ja": "`local` / `aws` / `azure` / `gcp` / `vault` のいずれか。",
        "zh-CN": "可选: `local` / `aws` / `azure` / `gcp` / `vault`。",
        "ko": "`local` / `aws` / `azure` / `gcp` / `vault` 중 하나.",
        "es": "Uno de: `local` / `aws` / `azure` / `gcp` / `vault`.",
        "fr": "Parmi : `local` / `aws` / `azure` / `gcp` / `vault`.",
        "de": "Einer von: `local` / `aws` / `azure` / `gcp` / `vault`.",
        "pt-BR": "Um de: `local` / `aws` / `azure` / `gcp` / `vault`.",
    },
    "settings.guide.kms.PRAXIA_KMS_KEY_ID": {
        "en": "Identifier for the master key. AWS: KMS CMK ARN. Azure: Key Vault key URL. GCP: Cloud KMS resource name. Vault: not used (use VAULT_TRANSIT_KEY).",
        "ja": "マスター鍵の識別子。AWS: KMS CMK ARN。Azure: Key Vault key URL。GCP: Cloud KMS resource name。Vault: 不要 (VAULT_TRANSIT_KEY 使用)。",
        "zh-CN": "主密钥标识符。AWS: KMS CMK ARN; Azure: Key Vault key URL; GCP: Cloud KMS 资源名; Vault: 不使用 (用 VAULT_TRANSIT_KEY)。",
        "ko": "마스터 키 식별자. AWS: KMS CMK ARN. Azure: Key Vault key URL. GCP: Cloud KMS 리소스명. Vault: 미사용 (VAULT_TRANSIT_KEY 사용).",
        "es": "Identificador de la clave maestra. AWS: ARN de CMK KMS. Azure: URL de clave Key Vault. GCP: nombre de recurso Cloud KMS. Vault: no se usa (usa VAULT_TRANSIT_KEY).",
        "fr": "Identifiant de la clé maître. AWS : ARN de CMK KMS. Azure : URL de clé Key Vault. GCP : nom de ressource Cloud KMS. Vault : non utilisé (VAULT_TRANSIT_KEY).",
        "de": "Master-Key-Identifier. AWS: KMS-CMK-ARN. Azure: Key-Vault-Key-URL. GCP: Cloud-KMS-Ressourcenname. Vault: nicht genutzt (stattdessen VAULT_TRANSIT_KEY).",
        "pt-BR": "Identificador da master key. AWS: ARN da CMK KMS. Azure: URL da chave Key Vault. GCP: nome do recurso Cloud KMS. Vault: não usa (use VAULT_TRANSIT_KEY).",
    },
    "settings.guide.kms.AWS_REGION": {
        "en": "AWS region for KMS *and* Bedrock (same env var serves both). e.g. `us-east-1` / `ap-northeast-1`.",
        "ja": "KMS *と* Bedrock 共通の AWS リージョン (env var 1 つで両方カバー)。例: `us-east-1` / `ap-northeast-1`。",
        "zh-CN": "AWS 区域，KMS *与* Bedrock 共用同一 env var。如 `us-east-1` / `ap-northeast-1`。",
        "ko": "KMS *와* Bedrock 공용 AWS 리전 (환경변수 하나로 둘 다 커버). 예: `us-east-1` / `ap-northeast-1`.",
        "es": "Región AWS para KMS *y* Bedrock (la misma env var sirve para ambos). P.ej. `us-east-1` / `ap-northeast-1`.",
        "fr": "Région AWS pour KMS *et* Bedrock (même variable d'env pour les deux). Ex. `us-east-1` / `ap-northeast-1`.",
        "de": "AWS-Region für KMS *und* Bedrock (eine Env-Variable für beides). Z. B. `us-east-1` / `ap-northeast-1`.",
        "pt-BR": "Região AWS para KMS *e* Bedrock (mesma env var para ambos). P.ex. `us-east-1` / `ap-northeast-1`.",
    },
    "settings.guide.kms.VAULT_ADDR": {
        "en": "HashiCorp Vault address, e.g. `https://vault.internal:8200`.",
        "ja": "HashiCorp Vault アドレス、例: `https://vault.internal:8200`。",
        "zh-CN": "HashiCorp Vault 地址，如 `https://vault.internal:8200`。",
        "ko": "HashiCorp Vault 주소, 예: `https://vault.internal:8200`.",
        "es": "Dirección de HashiCorp Vault, p.ej. `https://vault.internal:8200`.",
        "fr": "Adresse HashiCorp Vault, ex. `https://vault.internal:8200`.",
        "de": "HashiCorp-Vault-Adresse, z. B. `https://vault.internal:8200`.",
        "pt-BR": "Endereço do HashiCorp Vault, p.ex. `https://vault.internal:8200`.",
    },
    "settings.guide.kms.VAULT_TOKEN": {
        "en": "Vault auth token. Long-lived service token or output of an AppRole / Kubernetes auth flow.",
        "ja": "Vault 認証トークン。長寿命サービストークン、または AppRole / Kubernetes 認証フローの結果。",
        "zh-CN": "Vault 认证令牌。长期服务令牌或 AppRole / Kubernetes 认证流程产出。",
        "ko": "Vault 인증 토큰. 장기 서비스 토큰 또는 AppRole / Kubernetes 인증 결과.",
        "es": "Token de auth de Vault. Service token de larga duración o resultado de AppRole / auth Kubernetes.",
        "fr": "Token d'auth Vault. Service token longue durée ou résultat d'AppRole / auth Kubernetes.",
        "de": "Vault-Auth-Token. Langlebiges Service-Token oder Ergebnis eines AppRole-/Kubernetes-Auth-Flows.",
        "pt-BR": "Token de auth do Vault. Service token de longa duração ou resultado de AppRole / auth Kubernetes.",
    },
    "settings.guide.kms.VAULT_TRANSIT_KEY": {
        "en": "Name of the Transit secret-engine key Vault uses to wrap/unwrap DEKs. e.g. `praxia-token-key`.",
        "ja": "Vault Transit エンジンが DEK の wrap/unwrap に使う鍵名。例: `praxia-token-key`。",
        "zh-CN": "Vault Transit 引擎用于 wrap/unwrap DEK 的密钥名。如 `praxia-token-key`。",
        "ko": "Vault Transit 엔진이 DEK wrap/unwrap 에 사용하는 키 이름. 예: `praxia-token-key`.",
        "es": "Nombre de la clave del secret-engine Transit que Vault usa para envolver DEKs. P.ej. `praxia-token-key`.",
        "fr": "Nom de la clé du secret engine Transit utilisée par Vault pour wrap/unwrap les DEKs. Ex. `praxia-token-key`.",
        "de": "Name des Transit-Secret-Engine-Schlüssels, mit dem Vault DEKs wrapt/unwrapt. Z. B. `praxia-token-key`.",
        "pt-BR": "Nome da chave do secret engine Transit que o Vault usa para wrap/unwrap DEKs. P.ex. `praxia-token-key`.",
    },
    "admin.settings.no_changes": {
        "en": "No fields filled in — nothing was saved.",
        "ja": "入力された項目がないため、保存されませんでした。",
        "zh-CN": "未填写任何字段 — 未保存。",
        "ko": "입력된 항목이 없어 저장되지 않았습니다.",
        "es": "No se rellenó ningún campo — nada guardado.",
        "fr": "Aucun champ rempli — rien n'a été enregistré.",
        "de": "Keine Felder ausgefüllt — nichts gespeichert.",
        "pt-BR": "Nenhum campo preenchido — nada salvo.",
    },
    "admin.settings.saved": {
        "en": "✅ Saved {count} key(s) to .praxia/config.toml",
        "ja": "✅ {count} 件を .praxia/config.toml に保存しました",
        "zh-CN": "✅ 已保存 {count} 项到 .praxia/config.toml",
        "ko": "✅ {count} 건을 .praxia/config.toml 에 저장했습니다",
        "es": "✅ Se guardaron {count} clave(s) en .praxia/config.toml",
        "fr": "✅ {count} clé(s) enregistrée(s) dans .praxia/config.toml",
        "de": "✅ {count} Key(s) in .praxia/config.toml gespeichert",
        "pt-BR": "✅ {count} chave(s) salva(s) em .praxia/config.toml",
    },
    "admin.settings.restart_hint": {
        "en": "Restart the Streamlit server (or reload the page) for changes that affect already-imported modules to take effect.",
        "ja": "既にインポート済みのモジュールに影響する変更は、Streamlit サーバを再起動 (またはページをリロード) すると反映されます。",
        "zh-CN": "对已导入模块产生影响的变更,需重启 Streamlit 服务(或刷新页面)生效。",
        "ko": "이미 임포트된 모듈에 영향을 주는 변경 사항은 Streamlit 서버를 재시작 (또는 페이지 새로고침) 해야 반영됩니다.",
        "es": "Reinicia el servidor Streamlit (o recarga la página) para que los cambios que afecten a módulos ya importados surtan efecto.",
        "fr": "Redémarrez le serveur Streamlit (ou rechargez la page) pour que les modifications affectant des modules déjà importés prennent effet.",
        "de": "Starte den Streamlit-Server neu (oder lade die Seite neu), damit Änderungen an bereits importierten Modulen wirksam werden.",
        "pt-BR": "Reinicie o servidor Streamlit (ou recarregue a página) para que mudanças em módulos já importados façam efeito.",
    },
    "admin.settings.applied_immediately": {
        "en": "Keys are now live in this process — no restart needed. New API keys are visible to LiteLLM, OpenAI SDK, Mem0 etc. on the next call.",
        "ja": "キーは現在のプロセスに即座に反映されました — 再起動不要。次回の LiteLLM / OpenAI SDK / Mem0 呼出から新しい API キーが使われます。",
        "zh-CN": "Key 已在当前进程立即生效，无需重启。下次调用 LiteLLM / OpenAI SDK / Mem0 时即使用新 API 密钥。",
        "ko": "키가 현재 프로세스에 즉시 반영되었습니다 — 재시작 불필요. 다음 LiteLLM / OpenAI SDK / Mem0 호출부터 새 API 키가 사용됩니다.",
        "es": "Las claves están activas en este proceso — sin reinicio. LiteLLM / OpenAI SDK / Mem0 verán las nuevas claves en la próxima llamada.",
        "fr": "Les clés sont actives dans ce processus — pas de redémarrage. LiteLLM / OpenAI SDK / Mem0 utiliseront les nouvelles clés à l'appel suivant.",
        "de": "Schlüssel sind in diesem Prozess sofort aktiv — kein Neustart nötig. LiteLLM / OpenAI SDK / Mem0 sehen die neuen Keys beim nächsten Aufruf.",
        "pt-BR": "As chaves já estão ativas neste processo — sem reinício. LiteLLM / OpenAI SDK / Mem0 verão as novas chaves na próxima chamada.",
    },
    "admin.gate.denied": {
        "en": "🚫 Admin access denied for **{user}** (role: `{role}`). Only admin users can open this view.",
        "ja": "🚫 **{user}** (ロール: `{role}`) は Admin にアクセスできません。admin ロールのユーザのみ閲覧可能です。",
        "zh-CN": "🚫 **{user}** (角色: `{role}`) 无 Admin 访问权限。仅 admin 角色用户可访问。",
        "ko": "🚫 **{user}** (역할: `{role}`) 는 Admin 에 접근할 수 없습니다. admin 역할만 가능합니다.",
        "es": "🚫 Acceso a Admin denegado para **{user}** (rol: `{role}`). Solo usuarios admin.",
        "fr": "🚫 Accès Admin refusé pour **{user}** (rôle : `{role}`). Réservé aux utilisateurs admin.",
        "de": "🚫 Admin-Zugriff verweigert für **{user}** (Rolle: `{role}`). Nur admin-Nutzer.",
        "pt-BR": "🚫 Acesso Admin negado para **{user}** (papel: `{role}`). Apenas usuários admin.",
    },
    "admin.gate.howto": {
        "en": (
            "**Switch user**: change `User ID` in the sidebar to an admin "
            "username.\n\n"
            "**Create an admin user** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "Then re-open this page with `User ID = alice`."
        ),
        "ja": (
            "**ユーザを切替**: サイドバーの `User ID` を admin ユーザ名に変更。\n\n"
            "**admin ユーザを作成** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "その後 `User ID = alice` でこのページを開き直してください。"
        ),
        "zh-CN": (
            "**切换用户**: 在侧边栏将 `User ID` 改为 admin 用户名。\n\n"
            "**创建 admin 用户**(CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "随后以 `User ID = alice` 重新打开本页。"
        ),
        "ko": (
            "**사용자 전환**: 사이드바의 `User ID` 를 admin 사용자명으로 변경.\n\n"
            "**admin 사용자 생성** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "그 후 `User ID = alice` 로 본 페이지를 다시 여세요."
        ),
        "es": (
            "**Cambiar usuario**: cambia `User ID` en la sidebar a un nombre admin.\n\n"
            "**Crear usuario admin** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "Luego abre esta página con `User ID = alice`."
        ),
        "fr": (
            "**Changer d'utilisateur** : modifiez `User ID` dans la sidebar vers un nom admin.\n\n"
            "**Créer un admin** (CLI) :\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "Puis rouvrez cette page avec `User ID = alice`."
        ),
        "de": (
            "**Nutzer wechseln**: ändere `User ID` in der Sidebar zu einem admin-Namen.\n\n"
            "**Admin-Nutzer anlegen** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "Danach diese Seite mit `User ID = alice` neu öffnen."
        ),
        "pt-BR": (
            "**Trocar usuário**: mude `User ID` na sidebar para um nome admin.\n\n"
            "**Criar usuário admin** (CLI):\n\n"
            "```bash\npraxia user create alice --role admin\n```\n\n"
            "Depois reabra esta página com `User ID = alice`."
        ),
    },
    "admin.gate.dev_mode": {
        "en": "⚠️ **Dev / single-user mode** — no users have been created yet, so anyone hitting this URL can change settings. Run `praxia user create <name> --role admin` to enable proper role gating.",
        "ja": "⚠️ **開発 / 単一ユーザモード** — ユーザ未作成のため、このページにアクセスできる人は誰でも設定を変更可能。`praxia user create <名前> --role admin` でロールベース制御を有効化してください。",
        "zh-CN": "⚠️ **开发/单用户模式** — 尚未创建任何用户,因此访问此 URL 的任何人都可更改设置。运行 `praxia user create <名字> --role admin` 启用角色控制。",
        "ko": "⚠️ **개발 / 단일 사용자 모드** — 사용자가 아직 생성되지 않아 이 URL 에 접근하는 누구든 설정을 변경할 수 있습니다. `praxia user create <이름> --role admin` 으로 역할 기반 제어를 활성화하세요.",
        "es": "⚠️ **Modo dev / usuario único** — aún no hay usuarios creados, por lo que cualquiera con la URL puede cambiar ajustes. Ejecuta `praxia user create <nombre> --role admin` para activar control por rol.",
        "fr": "⚠️ **Mode dev / mono-utilisateur** — aucun utilisateur créé, n'importe qui ayant l'URL peut modifier les réglages. Exécutez `praxia user create <nom> --role admin` pour activer le contrôle par rôle.",
        "de": "⚠️ **Dev-/Einzelnutzer-Modus** — noch keine Nutzer angelegt, jeder mit der URL kann Einstellungen ändern. Führe `praxia user create <name> --role admin` aus, um rollenbasierte Kontrolle zu aktivieren.",
        "pt-BR": "⚠️ **Modo dev / usuário único** — sem usuários criados ainda; qualquer um com a URL pode alterar ajustes. Execute `praxia user create <nome> --role admin` para ativar controle por papel.",
    },
    "admin.settings.role_required": {
        "en": "🚫 Save blocked — only `admin` users can change settings.",
        "ja": "🚫 保存できません — `admin` ロールのユーザのみ設定を変更可能です。",
        "zh-CN": "🚫 保存被拒 — 仅 `admin` 用户可更改设置。",
        "ko": "🚫 저장 차단 — `admin` 사용자만 설정을 변경할 수 있습니다.",
        "es": "🚫 Guardado bloqueado — solo usuarios `admin` pueden cambiar ajustes.",
        "fr": "🚫 Enregistrement bloqué — seuls les utilisateurs `admin` peuvent modifier.",
        "de": "🚫 Speichern blockiert — nur `admin`-Nutzer dürfen Einstellungen ändern.",
        "pt-BR": "🚫 Salvamento bloqueado — apenas usuários `admin` podem alterar ajustes.",
    },
    "common.run": {
        "en": "Run",
        "ja": "実行",
        "zh-CN": "运行",
        "ko": "실행",
        "es": "Ejecutar",
        "fr": "Exécuter",
        "de": "Ausführen",
        "pt-BR": "Executar",
    },
    "common.save": {
        "en": "Save",
        "ja": "保存",
        "zh-CN": "保存",
        "ko": "저장",
        "es": "Guardar",
        "fr": "Enregistrer",
        "de": "Speichern",
        "pt-BR": "Salvar",
    },
    "common.delete": {
        "en": "Delete",
        "ja": "削除",
        "zh-CN": "删除",
        "ko": "삭제",
        "es": "Eliminar",
        "fr": "Supprimer",
        "de": "Löschen",
        "pt-BR": "Excluir",
    },
    "common.cancel": {
        "en": "Cancel",
        "ja": "キャンセル",
        "zh-CN": "取消",
        "ko": "취소",
        "es": "Cancelar",
        "fr": "Annuler",
        "de": "Abbrechen",
        "pt-BR": "Cancelar",
    },
    "common.input": {
        "en": "Input",
        "ja": "入力",
        "zh-CN": "输入",
        "ko": "입력",
        "es": "Entrada",
        "fr": "Entrée",
        "de": "Eingabe",
        "pt-BR": "Entrada",
    },
    "common.output": {
        "en": "Output",
        "ja": "出力",
        "zh-CN": "输出",
        "ko": "출력",
        "es": "Salida",
        "fr": "Sortie",
        "de": "Ausgabe",
        "pt-BR": "Saída",
    },
    "common.file": {
        "en": "File",
        "ja": "ファイル",
        "zh-CN": "文件",
        "ko": "파일",
        "es": "Archivo",
        "fr": "Fichier",
        "de": "Datei",
        "pt-BR": "Arquivo",
    },
    "memory.search": {
        "en": "Search",
        "ja": "検索",
        "zh-CN": "搜索",
        "ko": "검색",
        "es": "Buscar",
        "fr": "Rechercher",
        "de": "Suchen",
        "pt-BR": "Buscar",
    },
    "memory.mode": {
        "en": "Memory mode",
        "ja": "メモリモード",
        "zh-CN": "记忆模式",
        "ko": "메모리 모드",
        "es": "Modo de memoria",
        "fr": "Mode mémoire",
        "de": "Speichermodus",
        "pt-BR": "Modo de memória",
    },
    "memory.accumulate": {
        "en": "accumulate (writes pass through)",
        "ja": "accumulate (書込み有効)",
        "zh-CN": "accumulate (写入有效)",
        "ko": "accumulate (쓰기 활성)",
        "es": "accumulate (escrituras activas)",
        "fr": "accumulate (écritures actives)",
        "de": "accumulate (Schreiben aktiv)",
        "pt-BR": "accumulate (escritas ativas)",
    },
    "memory.read_only": {
        "en": "read_only (writes silently dropped)",
        "ja": "read_only (書込み無効化)",
        "zh-CN": "read_only (写入静默丢弃)",
        "ko": "read_only (쓰기 비활성)",
        "es": "read_only (escrituras silenciosamente descartadas)",
        "fr": "read_only (écritures silencieusement abandonnées)",
        "de": "read_only (Schreibvorgänge stillschweigend verworfen)",
        "pt-BR": "read_only (escritas silenciosamente descartadas)",
    },
}


def _normalize_lang(raw: str | None) -> str:
    """Map a raw language string (e.g. 'ja-JP', 'zh-Hans') to a SUPPORTED key."""
    if not raw:
        return "en"
    raw = raw.strip()
    if raw in SUPPORTED:
        return raw
    prefix = raw.split("-")[0].lower()
    for s in SUPPORTED:
        if s.lower().startswith(prefix):
            return s
    return "en"


def detect_language() -> str:
    """Best-effort detection from env or Streamlit session state.

    Streamlit doesn't expose Accept-Language directly; we approximate via
    the LANG / LC_MESSAGES env vars (set by docker / kube), the session
    state override (sidebar selector), and a last-resort default.
    """
    try:
        import streamlit as st
        if "praxia_lang" in st.session_state:
            return st.session_state.praxia_lang
    except Exception:
        pass
    env = os.getenv("PRAXIA_UI_LANG") or os.getenv("LANG") or ""
    return _normalize_lang(env.split(".")[0].replace("_", "-"))


def t(key: str, lang: str | None = None) -> str:
    """Look up a translation key. Falls back to English, then the key itself."""
    lang = lang or detect_language()
    bundle = _T.get(key)
    if not bundle:
        return key
    return bundle.get(lang) or bundle.get("en") or key


def assert_complete_translations() -> list[str]:
    """Validate that every key has every supported language.

    Returns a list of human-readable issues (empty list = all good).
    Called at import time below to fail-fast on incomplete catalogs in
    development. The CI also runs ``tests/evaluation/test_eval_i18n.py``
    which enforces the same invariant.
    """
    issues: list[str] = []
    for key, bundle in _T.items():
        missing = [lang for lang in SUPPORTED if lang not in bundle]
        if missing:
            issues.append(f"{key}: missing {missing}")
    return issues


# Fail-fast in development if any new key skipped translations.
# Production deployments tolerate incomplete strings (they just fall
# back to English via t()), but development should surface the gap.
if os.getenv("PRAXIA_I18N_STRICT", "").lower() in ("1", "true", "yes"):
    _issues = assert_complete_translations()
    if _issues:
        raise RuntimeError(
            "Praxia i18n catalog is incomplete (PRAXIA_I18N_STRICT=1):\n  "
            + "\n  ".join(_issues)
        )


def language_selector_in_sidebar() -> str:
    """Render a language selector in the Streamlit sidebar.

    Stores the chosen language in `st.session_state.praxia_lang` so subsequent
    `t(...)` calls return the right strings without needing the param.

    Returns the active language code.
    """
    try:
        import streamlit as st
    except ImportError:
        return detect_language()

    current = st.session_state.get("praxia_lang") or detect_language()
    options = SUPPORTED
    labels = [LANG_DISPLAY[c] for c in options]
    chosen_label = st.sidebar.selectbox(
        t("sidebar.language", lang=current),
        options=labels,
        index=options.index(current) if current in options else 0,
        key="praxia_lang_select",
    )
    chosen = options[labels.index(chosen_label)]
    st.session_state.praxia_lang = chosen
    return chosen


__all__ = [
    "SUPPORTED",
    "LANG_DISPLAY",
    "t",
    "detect_language",
    "language_selector_in_sidebar",
]
