Newer
Older
gnexus-tasks / frontend / src / locales / en.ts
// English locale — typed as typeof ru so missing/extra keys fail vue-tsc.
import type ru from './ru'

export default {
  common: {
    all: 'All',
    noProject: '— no project —',
    none: '— none —',
    choose: '— choose —',
    notSet: '— not set —',
    error: 'Request failed',
    save: 'Save',
    cancel: 'Cancel',
    edit: 'Edit',
    preview: 'Preview',
    confirmTitle: 'Confirmation',
    delete: 'Delete',
    open: 'Open',
    move: 'Move',
    actions: 'Actions',
    expand: 'Expand',
    collapse: 'Collapse',
    deleteConfirmTask: 'Delete task "{title}"? This cannot be undone.',
    deleteConfirmProject: 'Delete project "{name}"? Tasks will remain, but without a project.',
    archive: 'To archive',
    archiveTitle: 'Send to archive',
    saved: 'Saved',
    created: 'Created',
    create: 'Create',
    taskDeleted: 'Task deleted',
    loading: 'Loading…',
    projectDeleted: 'Project deleted',
    taskApproved: 'Task approved',
    taskTaken: 'Task started',
    taskFinished: 'Task finished',
    yes: 'Yes',
    no: 'No',
    back: 'Back',
  },
  nav: {
    sections: 'Sections',
    subtitle: 'GNexus Tasks — personal tasks',
    signIn: 'Sign in',
    account: 'Account',
    signOut: 'Sign out',
    task: 'Task',
    home: 'Home',
    stack: 'Inbox stack',
    list: 'Task list',
    achievements: 'Achievements',
    stats: 'Statistics',
    projects: 'Projects',
    archive: 'Archive',
    journal: 'Journal',
    options: 'Task handout',
    settings: 'Settings',
    extension: 'Extension',
  },
  // Progress: shared by the "Achievements" page and the garden (the garden is
  // disabled in 0.58 and will return — wording stays neutral, no plants)
  progress: {
    title: 'Achievements',
    level: 'Level {n}',
    xpTotal: '{n} XP',
    levelProgress: 'To next level: {xp} / {span} XP',
    aboutOpen: 'How it works',
    aboutTitle: 'How it works',
    levelsTitle: 'Rank tree',
    levelsHint:
      'XP thresholds and ranks of each level. Levels grow from task XP — nothing expires and nothing is taken away.',
    levelCurrent: 'current',
    achievements: 'Achievements',
    coins: 'coins: {n}',
    coinsHint: 'Coins for completed tasks, created tasks and projects, new levels — they accumulate',
    achDone: 'All steps completed (highest — {r})',
    achStep: 'Step: roman numeral, fraction — progress to the next',
    about: [
      'Every completed task earns experience and coins — progress only grows and never shrinks.',
      'Completing a task earns XP: base 10 + a priority bonus (up to 15) + a size bonus from the time estimate (up to 15) + 10 for a “mentally hard” task — an honest reward for willpower. Bigger and more urgent work is worth more.',
      'Earned XP raises your level — from Sprout to Garden Legend. Levels never drop: XP does not expire and is not taken away, even if a task is deleted.',
      'Coins come from completed tasks (as much as the XP), from creating tasks and projects, and from new levels. For now they just accumulate — they will be useful when the garden returns.',
      'Achievements mark milestones: tasks completed, levels, different projects, hours of work, strict deadlines, “mentally hard” tasks. Each has steps I, II, III with always-visible progress.',
      'A task completed from the “3 options” mode earns the “chose and did” mark. Closing a “don’t want to do it” task is always celebrated in gold — the willpower was worth it. Nothing expires, no streaks or penalties — only pleasant rewards.',
    ],
    levels: [
      'Sprout',
      'Seedling',
      'Gardener',
      'Grower',
      'Arborist',
      'Forester',
      'Garden master',
      'Garden keeper',
      'Royal gardener',
      'Horticulture magister',
      'Landscape architect',
      'Keeper of legends',
      'Garden legend',
    ],
    ach: {
      firstDone: 'First sprout',
      done10: 'Dozen',
      level5: 'Heights',
      sprinter: 'Sprinter',
      explorer: 'All-rounder',
      marathon: 'Marathoner',
      deadlineBoss: 'Deadline boss',
      chooser: 'Chose and did',
      willpower: 'Willpower',
      recurring: 'Rhythm of life',
      projectDone: 'Project delivered',
    },
    achHint: {
      firstDone: 'Complete your first task — the milestone is yours.',
      done10: 'Complete 10, 50 and 100 tasks — one tier per milestone.',
      level5: 'Reach level 5, 10 and 15.',
      sprinter: 'Complete 3, 10 and 25 tasks in a single day.',
      explorer: 'Have completed tasks in 3, 5 and 8 different projects.',
      marathon: 'Accumulate 10, 50 and 100 hours on tasks — actual or estimated time.',
      deadlineBoss: 'Complete 5, 15 and 30 tasks with a strict deadline date.',
      chooser: 'Complete 5, 25 and 50 tasks picked from the “3 options” mode.',
      willpower: 'Complete 5, 25 and 50 tasks marked “don’t feel like doing it”.',
      recurring: 'Complete a recurring task.',
      projectDone: 'Finish a project: all of its tasks (three or more) completed.',
    },
  },
  garden: {
    title: 'Garden',
    plants: 'plants: {n}',
    levelsHint:
      'XP thresholds and rewards of each level: new plant species (seed price) and map expansions. Levels grow from task XP — nothing expires.',
    rewardCreateTask: 'task created',
    rewardCreateProject: 'project created',
    lastReward: 'Latest reward for: {title} — {date}',
    emptyTitle: 'The garden is empty',
    emptyText: 'Complete your first task — a plant will grow on the bed.',
    coins: 'coins: {n}',
    coinsHint: 'Garden currency: spent on plant growth and decorations',
    shop: 'Market',
    shopTitle: 'Garden market',
    buy: 'Buy',
    notEnoughCoins: 'Not enough coins — {n} short',
    lockedUntil: 'Unlocks at level {n}',
    expansion: 'Garden expansion',
    expansionHint: 'More land — {n} cells added to the map perimeter',
    expansionCurrent: 'Current map: {cols}×{rows}',
    expansionMax: 'All land unlocked',
    inventory: 'Inventory',
    inventoryHint: 'Drag a decoration or a seed onto the map; decorations can be dragged back',
    inventoryEmpty: 'Empty for now: bought decorations wait here — drag them onto the map',
    zoomIn: 'Zoom in',
    zoomOut: 'Zoom out',
    zoomReset: 'Reset view',
    fullscreen: 'Fullscreen',
    fullscreenExit: 'Exit fullscreen',
    boughtHint: 'Bought: {name} — drag it from the inventory below the map into the garden',
    decorations: 'Decorations',
    decorationsHint: 'Decorate your garden — decorations give no bonuses, just joy',
    unique: 'unique',
    rareOnly: 'rare plants only',
    seeds: 'Plant seeds',
    seedsHint:
      'Species unlocked by level can be bought: a seed lands in the inventory — drag it onto a free cell. Rare/epic plants only grow from tasks.',
    seedBought: 'Seed bought — drag it from the inventory onto the bed',
    speciesHint:
      'Experience unlocks new species and land, coins buy seeds, growth and décor. A species is fixed to a plant at birth.',
    upgrade: 'Grow — {n} coins',
    maxStage: 'Fully grown',
    stage: { sprout: 'Sprout', bush: 'Bush', bloom: 'Bloom' },
    speciesNames: {
      'ph-flower': 'Flower',
      'ph-leaf': 'Greens',
      'ph-tree-evergreen': 'Pine',
      'ph-flower-lotus': 'Lotus',
      'ph-cactus': 'Cactus',
      'ph-tree': 'Oak',
      'ph-drop': 'Dewdrop',
      'ph-sun': 'Sunflower',
      'ph-tree-structure': 'Bonsai',
      'ph-butterfly': 'Butterfly bush',
      'ph-campfire': 'Rowan',
      'ph-sparkle': 'Starflower',
      'ph-fire': 'Firebloom',
    },
    decorNames: {
      fence: 'Fence',
      bush: 'Bush',
      flowerbed: 'Flowerbed',
      lantern: 'Lantern',
      bench: 'Bench',
      birdbath: 'Birdbath',
      flag: 'Weather vane',
      birdhouse: 'Birdhouse',
      gem: 'Garden gem',
      pond: 'Pond',
      greenhouse: 'Greenhouse',
      gazebo: 'Gazebo',
    },
  },
  gamify: {
    praise: [
      'Well done!',
      'Done — halfway there!',
      'Another step forward.',
      'Beautiful!',
      'Keep it up!',
      'One task down, mood up.',
    ],
    chosen: 'chose and did',
    willpower: 'willpower',
    willpowerText: 'Willpower! It was worth it.',
    coins: 'coins',
    createdReward: 'Created — a drop of experience is yours',
    daily: 'Daily visit reward',
    // AI agent mandate (spec 3.20): events arrive over SSE from another session —
    // the agent took a task, or closed it and awaits review
    claimed: 'An agent took a task',
    claimedText: '{name} got to work — leave the task alone while she works',
    review: 'Work awaits review',
    reviewText: '“{title}” — check what was done, then accept or return it',
  },
  stats: {
    title: 'Statistics',
    modeDay: 'Day',
    modeWeek: 'Week',
    modeMonth: 'Month',
    today: 'Today, {date}',
    prevPeriod: 'Previous period',
    nextPeriod: 'Next period',
    ofDays: 'of {n} days',
    totalVs: 'Completed this period: {n} · previous period: {m}',
    chartTitle: 'Completed tasks',
    legendNow: 'Now',
    legendPrev: 'Previous period',
    heatmapHalf: 'Activity over 6 months',
    heatmapYear: 'Activity over the year',
    heatTasks: 'Tasks',
    heatXp: 'XP',
    heatLess: 'less',
    heatMore: 'more',
    heatHalf: 'Half a year',
    heatYear: 'Year',
    emptyTitle: 'No data yet',
    emptyText: 'Complete a couple of tasks — dynamics with comparisons will appear here.',
    metric: {
      closed: 'Tasks completed',
      xp: 'XP earned',
      created: 'Tasks created',
      hours: 'Hours worked',
      activeDays: 'Productive days',
    },
  },
  home: {
    title: 'Home',
    stackCount: 'in stack: {n}',
    activeCount: 'active: {n}',
    inProgress: 'In progress',
    overdue: 'Overdue',
    deadlines: 'Deadlines this week',
    next: 'Up next',
    overview: 'Overview',
    projects: 'Active projects',
    totalTasks: 'Total tasks',
    doneMonth: 'Done this month',
    doneAll: 'Done all time',
    clearTitle: 'All clear',
    clearText: 'No active tasks — a good moment to work through the stack.',
  },
  stack: {
    title: 'Inbox stack',
    count: 'Tasks in stack: {n}',
    quickPlaceholder: 'Throw in a task — just the text, details later…',
    quickAdd: 'Throw in',
    newTask: 'New task',
    added: 'Task added to the stack',
    detailTitle: 'Task details',
    emptyTitle: 'Stack is empty',
    emptyText: 'Throw in your first task — detailing is picked automatically.',
    inStack: 'in stack',
    uploading: 'uploading…',
    proposal: 'AI proposal:',
    proposalPending: 'Detailing in progress…',
    approveProposal: 'Yes, looks right',
    detail: 'Detail it',
    redetail: 'Ask AI again',
    deleteTask: 'Delete task',
    deleteAttachment: 'Delete attachment',
    promptProject: 'Name of the new project:',
    promptTag: 'Name of the new tag:',
    newProject: 'New project',
    newTag: 'New tag',
    approve: 'Approve',
    form: {
      title: 'Title',
      description: 'Description (Markdown, Ctrl+V for image)',
      preview: 'Markdown preview',
      project: 'Project',
      tagsPlaceholder: 'Add a tag…',
      tags: 'Tags',
      priority: 'Priority',
      estimate: 'Time estimate',
      budget: 'Budget (in settings currency)',
      cost: 'Cost estimate (in settings currency)',
      estimateLegend: 'Estimates',
      extra: 'Additional',
      bugtrailDone: 'Filled from the bug report',
      bugtrailFailed: 'Could not open the BugTrail report',
    },
    deadline: {
      legend: 'Deadline',
      date: 'Strict — date',
      period: 'Soft — period',
    },
    recur: {
      legend: 'Task type',
      oneTime: 'One-time',
      recurring: 'Recurring (repeats)',
      kind: 'Repeat rule',
      interval: 'Interval, days',
      weekdays: 'Days of week',
      monthlyDay: 'Day of month (1–31, empty — last)',
    },
  },
  tree: {
    addSubtask: 'Add subtask',
    promptSubtask: 'Subtask:',
  },
  task: {
    notFoundTitle: 'Task not found',
    notFoundText: 'The task may have been deleted or the link is stale.',
    proposalTitle: 'AI proposal',
    proposalHint: 'Review the details and approve — the task joins the list.',
    proposalNotRight: 'Not that',
    description: 'Description',
    editTitle: 'Edit title',
    editDescription: 'Edit description',
    deadlineConflict: 'Deadline: either a date or a period — not both',
    descriptionEmpty: 'No description yet — detail the task.',
    readmeFrom: 'README.md from the repository',
    attachments: 'Attachments',
    fields: 'Details',
    dates: 'Dates',
    field: {
      project: 'Project',
      taskType: 'Task type',
      priority: 'Priority',
      estimate: 'Time estimate',
      actual: 'Actual',
      money: 'Money',
      deadline: 'Deadline',
      recurrence: 'Recurrence',
      created: 'Created',
      approved: 'Approved',
      done: 'Done',
    },
    subtasks: 'Subtasks',
    noSubtasks: 'No subtasks',
    statusTitle: 'Status',
    changeStatus: 'Change status',
    takeWork: 'Take on',
    finishWork: 'Done',
    finishTitle: 'Finish the task?',
    finishComment: 'Closing comment (optional)',
    mentallyHard: {
      set: "Don't want to do it",
      unset: 'Remove “mentally hard”',
      badge: 'mentally hard',
    },
    // AI agent mandate (spec 3.20): task marks and the lease plaque
    mandate: {
      eligible: 'Available to the AI agent',
      eligibleHint: 'Navi, the AI agent, will be able to take this task. Without the mark she never touches it.',
      shortBadge: 'AI',
      createdBadge: 'agent created',
      createdBy: 'Created by agent “{name}”',
      agent: 'agent',
      claimedUntil: 'Taken by {name} · until {time}',
    },
    // Reviewing agent work (spec 3.20): closed, but not accepted yet
    accept: {
      title: 'Work review',
      pendingBadge: 'awaiting review',
      pendingHint: 'An agent closed this task — the work must be accepted or returned',
      hint: '{name} closed this task. Check what was done, then accept the work or return it.',
      report: 'Agent report',
      accept: 'Accept',
      reject: 'Return to work',
      accepted: 'Work accepted',
      rejected: 'Task is back in work',
      rejectTitle: 'Return the task to work?',
      rejectComment: 'What is wrong (optional)',
    },
    subtaskCreated: 'Subtask created — it went to the stack for detailing',
    createdRaw: 'Task went to the stack — detail it there',
    // Prompt for an AI agent (0.87): the task as text, copied and handed to the
    // owner's agent. Facts only — what to do with the task is the owner's call
    ai: {
      menu: 'Prompt for AI',
      title: 'Prompt for an AI agent',
      hint: 'The task as text to hand to an AI agent. Edit it if needed, then copy.',
      copy: 'Copy prompt',
      close: 'Close',
      intro: 'A task from GNexus Tasks.',
      taskSection: 'Task',
      descriptionSection: 'Description',
      proposalSection: 'Detailing (AI proposal, not approved)',
      subtasksSection: 'Subtasks',
      linkSection: 'Link',
      id: 'ID',
      titleField: 'Title',
      status: 'Status',
      tags: 'Tags',
      parentTask: 'Parent task',
      eligible: 'Available to an AI agent',
      eligibleYes: 'yes',
      eligibleNo: 'no',
      claimed: 'Claimed',
      descriptionEmpty: 'No description.',
    },
    actions: 'Actions',
    addTag: 'Add a tag…',
    // Проект задачи в меню карточки (0.82): перейти к проекту и перенести
    // в другой — соседние пункты, это один вопрос «в каком проекте задача»
    goToProject: 'Go to project',
    moveToProject: 'Move to project',
    // Card menu item (0.83): "Move to project" wrapped onto two lines in the kit's
    // 220px menu, and inside the menu the question is "which project"
    moveToOther: 'To another project',
    moveHint: 'Task "{title}" will move to the selected project',
    moved: 'Task moved to "{project}"',
    movedOut: 'Task taken out of its project',
  },
  projectPage: {
    notFoundTitle: 'Project not found',
    notFoundText: 'The project may have been deleted or the link is stale.',
    note: 'Note',
    editNote: 'Edit note',
    noteEmpty: 'No note yet — add one via "Edit".',
    readmeTitle: 'README from the repository',
    readmeMissing: 'No README found in the repository — check the link in the project settings.',
    readmeError: 'Could not read the README — the repository did not respond.',
    noteCollapsedHint: 'The note is long — only its beginning is shown',
    noteExpand: 'Expand',
    noteCollapse: 'Collapse',
    progress: 'Project tasks: {done}/{total}',
    newTask: 'New task',
    taskCreated: 'Task created — it went to the stack for detailing',
    promptTask: 'New project task:',
    emptyTitle: 'No tasks',
    emptyText: 'Create the first project task or relax the filters.',
    tree: 'Project tree',
    stats: 'Statistics',
    total: 'Total tasks',
    doneN: 'Done',
    inProgress: 'In progress',
    toDo: 'To do',
    overdue: 'Overdue',
    taskCount: '{n} tasks',
    openSite: 'Open site',
    // Project activity (0.83): the same GitHub-style grid as on the stats page,
    // but over one project's tasks; half a year, the card sits in the project sidebar
    activity: 'Activity',
    heatCell: '{date} — closed {done}, created {created}',
    // Tag cloud (0.83): a click sets a substring filter by the tag name
    tagShow: 'Show tasks tagged "{name}"',
    tagHide: 'Clear the "{name}" tag filter',
    tagCount: 'Tasks with this tag: {n}',
  },
  list: {
    title: 'Task list',
    count: 'Found: {n}',
    emptyTitle: 'Nothing found',
    emptyText: 'Try relaxing the filters or throw a new task into the stack.',
    filterStatus: 'Status',
    filterTag: 'Tag',
    filterTagSearch: 'Search by tag',
    filterTagHint: 'Start typing a tag name',
    filterTagClear: 'Clear the tag filter',
    filterPrioritized: 'High priority',
    // Second switch (0.91, spec 3.5): keep only recurring tasks in the list
    filterRecurring: 'Recurring',
    noTagsFound: 'No tags found',
    // Review (0.85, spec 3.20): a separate tab-plane, not a status
    tabReview: 'Awaiting review',
    filterCreated: 'Created by',
    createdAll: 'All tasks',
    createdMe: 'Created by me',
    createdAgent: 'Created by agent',
  },
  // Action journal (spec 3.20): who did what to tasks, and when
  journal: {
    title: 'Journal',
    count: '{n} records',
    empty: 'No records yet — task actions will show up here',
    filterKind: 'Event type',
    filterKindAll: 'All events',
    filterActor: 'Actor',
    filterActorAll: 'All actors',
    filterProject: 'Project',
    filterProjectAll: 'All projects',
    actorUser: 'Me',
    actorAgent: 'Agent',
    col: {
      when: 'When',
      event: 'Event',
      task: 'Task',
      project: 'Project',
      actor: 'Actor',
      comment: 'Comment',
    },
    // Record kinds — values from tasklog.py, read as human words
    kind: {
      created: 'Task created',
      eligible_changed: 'Agent availability',
      claimed: 'Taken by agent',
      released: 'Returned by agent',
      status_changed: 'Status change',
      completed: 'Task closed',
      accepted: 'Work accepted',
      rejected: 'Work returned',
      deleted: 'Task deleted',
    },
    // Machine comment codes for the flag change (on/off) and a deleted project
    eligibleOn: 'Opened to the agent',
    eligibleOff: 'Closed to the agent',
    projectGone: 'Project deleted',
    taskDeleted: 'Task deleted — the title is kept in the record',
    via: {
      ui: 'from the interface',
      api: 'over the API',
      mcp: 'over MCP',
    },
  },
  options: {
    title: 'Task handout',
    done: 'Done',
    notNow: 'Not now — other options',
    availableHours: 'Available time, hours',
    suggest: 'Suggest',
    choose: 'Do it now',
    emptyTitle: 'No options',
    emptyText: 'No free tasks fit this time — throw something into the stack or lower the time.',
  },
  projects: {
    title: 'Projects',
    count: 'Projects: {n}',
    new: 'New project',
    emptyTitle: 'No projects',
    emptyText:
      'Create a project — tasks can be grouped and get notes with resources.',
    prompt: 'Name of the new project:',
    promptLabel: 'Project name',
    taskCounts: 'Tasks done {done}/{total}',
    noTasksYet: 'No tasks in this project yet',
    progressLabel: 'Done {done} of {total}',
    inProgress: '{n} in progress',
    overdue: '{n} overdue',
    nextDeadline: 'Next deadline: {date}',
    lastActivity: 'Last task activity: {date}',
    noActivity: 'No activity',
    colorNone: 'No color',
    sitePlaceholder: 'https://example.com',
    repositoryPlaceholder: 'https://git.example.com/owner/repo',
    withTasks: 'With tasks',
    withoutTasks: 'No tasks',
    pinned: 'Pinned',
    pinnedLabel: 'Pinned',
    pin: 'Pin project',
    unpin: 'Unpin project',
    archived: 'Project sent to archive',
    archiveConfirm:
      'Send project "{name}" and its tasks ({n}) to the archive? Everything can be restored later.',
    edit: 'Edit',
    delete: 'Delete project',
    form: {
      name: 'Name',
      relevance: 'Relevance',
      priority: 'Priority',
      note: 'Note (Markdown: links, context)',
      preview: 'Preview',
      color: 'Color',
      siteUrl: 'Site',
      repositoryUrl: 'Repository',
    },
  },
  pagination: {
    prev: 'Previous',
    next: 'Next',
    pageOf: 'Page {n} of {m}',
    aria: 'Pagination',
  },
  archive: {
    title: 'Archive',
    count: 'Projects: {n}',
    emptyTitle: 'Archive is empty',
    emptyText: 'Projects sent to the archive end up here — with all their tasks and history.',
    restore: 'Restore',
    restored: '"{name}" restored from the archive',
    deleteForever: 'Delete forever',
    deleteConfirm:
      'Delete "{name}" forever? The project and all its tasks will be lost irreversibly.',
    banner: 'This project is in the archive — history is read-only. Restore it to keep working.',
  },
  settings: {
    title: 'Settings',
    currencyTitle: 'Budget currency',
    currencyHint:
      'The unit is chosen once and applies to all amounts: task budget, cost estimate.',
    currencyUnit: 'Unit',
    saved: 'Saved — applied in all views.',
    languageTitle: 'Interface language',
    languageHint:
      'The chosen language applies immediately. "Same as account" takes it from gnexus auth.',
    languageUnit: 'Language',
    languageAuto: 'Same as account (SSO)',
    langRu: 'Русский',
    langEn: 'English',
    langUk: 'Українська',
    mcpTokenTitle: 'MCP tokens',
    mcpTokenHint:
      'A token for an AI agent (e.g. Claude): the agent acts on your behalf and sees only your data. The value is shown once at creation — copy it right away into the agent config.',
    mcpTokenCreated: 'Token created. It will never be shown again — copy it now.',
    mcpTokenShown: 'I saved the token',
    mcpTokenCopyFailed: 'Could not copy — select and copy manually',
    mcpTokenUnnamed: 'Unnamed',
    mcpTokenDelete: 'Revoke',
    mcpTokenNone: 'No tokens yet — create one to connect an agent.',
    mcpTokenLabel: 'Label (e.g. "laptop")',
    mcpTokenLabelPlaceholder: 'what this agent is for',
    mcpTokenCreate: 'Generate',
    mcpOpen: 'How to connect',

    // Системные уведомления (ТЗ 3.21)
    pushTitle: 'Notifications',
    pushHint:
      'System notifications on this device — they arrive even when the app is closed: an agent took a task, work awaits review, a deadline is due, a routine is up.',
    pushSwitch: 'Send notifications to this device',
    pushDevices: 'Connected devices: {n}',
    pushOn: 'Notifications are on for this device.',
    pushOff: 'Notifications are off for this device.',
    pushDenied:
      'The browser has blocked notifications for this site. Allow them in the browser settings — the page cannot ask again.',
    pushUnsupported:
      'This browser has no system notifications, or the page is not on HTTPS. An installed phone app works: on iPhone — since iOS 16.4.',
    pushUnconfigured:
      'The server is not configured to send notifications — it needs VAPID keys in its environment.',
    pushRequestDenied:
      'The browser did not show the prompt. Allow notifications for this site in the browser settings and try again.',
    pushFailed: 'Could not enable notifications',
    quietSwitch: 'Do not disturb from 22:00 to 09:00',
    quietHint:
      'Reminders stay silent during this window and are not queued: once it ends you get a reminder for the state of things that day. Agent work is reported even during quiet hours — it awaits your decision.',
  },
  ext: {
    title: 'Quick-capture extension',
    whatTitle: 'What it is',
    whatText:
      'Click the extension icon in the browser toolbar — the task is in your inbox without opening the service. The popup has two tabs: "Add" (first line — title, the rest — description; a project is optional) and "Active" — view-only, clicking a task opens it in the service.',
    tokenTitle: 'Step 1. Access token',
    tokenText:
      'The extension connects with a personal MCP token (like AI agents): create it in "Settings → MCP tokens" — the value is shown once.',
    tokenButton: 'Open Settings',
    downloadTitle: 'Step 2. Download and unpack',
    downloadButton: 'Download ZIP',
    downloadHint: 'Unpack the archive into any folder.',
    installTitle: 'Step 3. Load the extension into the browser',
    chromeText:
      'Chrome/Chromium: open chrome://extensions, enable "Developer mode" → "Load unpacked" → pick the unpacked folder.',
    firefoxText:
      'Firefox: open about:debugging#/runtime/this-firefox → "Load Temporary Add-on…" → the manifest.json file from the archive.',
    connectTitle: 'Step 4. Connect',
    connectText:
      'Click the extension icon, paste the token from step 1 and press "Connect". Revoking the token in "Settings" disables the extension.',
    pwaTitle: 'Available in the web version',
    pwaNote:
      'This page is hidden in the installed app (PWA) — open the service in a regular browser tab.',
  },
  mcp: {
    title: 'MCP for AI agents',
    whatTitle: 'What it is',
    whatText:
      'The app has a built-in MCP server (Model Context Protocol): AI agents connect to it and manage your tasks on your behalf — creating, finding, updating and closing them. Closing a task via an agent earns the same rewards as in the app: XP, coins, a plant in the garden; the next instance of a recurring task is created automatically.',
    toolsTitle: 'Tools',
    toolsHint:
      'The server explains the workflow to the agent itself: start with projects, attach tasks to a project, never invent identifiers, and follow the hints in error messages.',
    toolListProjects: 'list of projects: notes, status, open task count',
    toolGetProject: 'project context: note and open tasks',
    toolCreateTask: 'create a task (a title is enough, project recommended)',
    toolUpdateTask: 'update task fields; closing is status="done"',
    toolCompleteTask: 'complete a task (actual time optional)',
    toolListTasks: 'search and filters: project, tag, status, substring',
    toolGetTask: 'full task data, including attachments',
    toolListTags: 'tag reference',
    connectTitle: 'How to connect an agent',
    connectText:
      'Transport is Streamable HTTP. The address matches this app’s address. You will need an access token to connect.',
    connectUrlLabel: 'Server address',
    connectTokenLabel: 'Access token',
    connectTokenText:
      'The agent acts on your behalf. Create a personal token in Settings — the “MCP tokens” section — and paste it here.',

    connectClaudeLabel: 'Claude Code — one command',
    connectJsonLabel: 'Universal JSON (Claude Desktop and other clients)',
    copy: 'Copy',
    copied: 'Address copied',
    copyFailed: 'Failed to copy',
    projectTitle: 'Project context',
    projectText:
      'The agent sees your projects with their notes and open tasks. The server instructs the agent to start from projects (list_projects → get_project), attach created tasks to a project, and re-read get_project when returning to a conversation after a break — so tasks never lose their project context.',
  },
  md: {
    bold: 'Bold',
    boldText: 'bold text',
    italic: 'Italic',
    italicText: 'italic text',
    heading: 'Heading',
    list: 'List',
    checklist: 'Checklist',
    link: 'Link',
    linkText: 'link text',
    code: 'Code',
  },
  login: {
    signIn: 'Sign in with GNEXUS',
    subtitle: 'Your tasks, projects and garden — in one place',
  },
  duration: {
    hours: 'Hours',
    minutes: 'Minutes',
    h: 'h',
    min: 'min',
  },
  taskui: {
    openProject: 'Open project',
    priority: {
      very_low: 'Very low',
      low: 'Low',
      medium: 'Medium',
      high: 'High',
      urgent: 'Urgent',
    },
    status: {
      to_do: 'To do',
      in_progress: 'In progress',
      done: 'Done',
      cancelled: 'Cancelled',
      deferred: 'Deferred',
    },
    relevance: {
      active: 'Active',
      paused: 'Paused',
    },
    time: {
      hm: '{h} h {m} m',
      h: '{h} h',
      m: '{m} m',
    },
    money: {
      budget: 'budget {amount}',
      estimate: 'estimate {amount}',
    },
    currency: {
      UAH: '₴ Hryvnia (UAH)',
      USD: '$ Dollar (USD)',
      EUR: '€ Euro (EUR)',
      GBP: '£ Pound (GBP)',
      PLN: 'zł Zloty (PLN)',
    },
    deadline: {
      day: 'within a day',
      week: 'within a week',
      month: 'within a month',
      year: 'within a year',
      until: 'by {date}',
    },
    countdown: {
      today: 'Today',
      tomorrow: 'Tomorrow',
      inDays: 'In {n} day | In {n} days',
      overdueDays: 'Overdue by {n} day | Overdue by {n} days',
    },
    ago: {
      today: 'Today',
      yesterday: 'Yesterday',
      days: '{n} day ago | {n} days ago',
      weeks: '{n} week ago | {n} weeks ago',
      weeksOne: '1 week ago',
      months: '{n} month ago | {n} months ago',
      monthsOne: '1 month ago',
      years: '{n} year ago | {n} years ago',
      yearsOne: '1 year ago',
    },
    recur: {
      kind: {
        interval: 'Every N days',
        weekdays: 'Days of week',
        monthly: 'Day of month',
      },
      daily: 'daily',
      weekly: 'weekly',
      everyN: 'every {n} d',
      byWeekdays: 'by days of week',
      monthlyDay: 'monthly on day {day}',
      recurring: 'recurring',
      // For a recurring task the same date reads as "when it comes round" (0.91)
      next: 'next {date}',
      // Hint on the list marker (0.91, spec 3.5)
      hintNext: 'Recurring: {rule}. Next instance on {date}',
      hint: 'Recurring: {rule}. Closing it creates the next instance',
    },
  },
} satisfies typeof ru