{
  "agentReminders": {
    "policyTitle": "Payment reminders",
    "changeTitle": "Change payment reminders",
    "current": "Current schedule",
    "proposed": "New schedule",
    "on": "On",
    "off": "Off",
    "notConfigured": "Not set up yet. This is the default schedule if reminders are turned on.",
    "noSteps": "No reminder steps are set, so no reminder email is sent.",
    "daysAfterDue": "{days} days after the due date",
    "onDueDate": "On the due date",
    "tones": {
      "gentle": "Gentle reminder",
      "firm": "Firm reminder",
      "final": "Final notice"
    },
    "daily": "Checked daily for unpaid invoices with a customer email. Each step is sent once; paid invoices and unsubscribed customers receive no more reminders.",
    "confirm": "Confirm change",
    "cancel": "Cancel",
    "saving": "Saving...",
    "saved": "Payment reminders updated.",
    "unchanged": "This schedule is already current.",
    "cancelled": "Cancelled. Nothing was changed.",
    "confirmed": "You confirmed this change.",
    "expired": "This change was prepared more than {minutes} minutes ago and can no longer be confirmed. Ask Groot to prepare it again for a new card.",
    "confirmationHint": "This changes the business reminder schedule. Nothing is saved until you press Confirm change.",
    "openSettings": "Open payment reminder settings",
    "historical": "Past proposal. Open settings to see the current schedule.",
    "roleRequired": "Only the business owner or a finance admin can change payment reminders. Ask them to make this change.",
    "changed": "The reminder settings changed after this card was prepared. Ask Groot for a new proposal.",
    "invalid": "Use up to 6 reminders, on different days from 0 to 365 after the due date.",
    "browserRequired": "Sign in as the owner or a finance admin and confirm in the browser.",
    "failed": "The change could not be saved. Try again in a moment.",
    "unavailable": "This reminder schedule could not be displayed. Open settings to review it."
  },
  "transactionVisibility": {
    "noneVisible": "No visible transactions. Turn on Show voided to view preserved history.",
    "showVoided": "Show voided"
  },
  "refundInvoice": {
    "action": "Refund",
    "description": "Record money returned to the customer. The amount is allocated proportionally over the remaining sale and tax.",
    "receiptValid": "The Official Receipt stays valid.",
    "amount": "Amount",
    "ceiling": "Available to refund: {amount} {currency}",
    "method": "Refund method",
    "account": "Refund account",
    "chooseAccount": "Choose an account",
    "date": "Refund date",
    "reason": "Reason",
    "confirm": "Confirm refund",
    "recorded": "Refund recorded",
    "email": "Customer email",
    "send": "Send refund note",
    "sent": "Refund note email sent.",
    "noEmail": "Enter one email address to send this refund note.",
    "errors": {
      "ceiling": "This exceeds what was paid net of earlier refunds and credits. Review the invoice history.",
      "amount": "Enter a positive amount with at most two decimal places.",
      "allocation": "Review the invoice tax and income allocation before refunding.",
      "conflict": "This request already recorded different details. Review the refund history before starting another refund.",
      "notPaid": "Choose a paid credit invoice.",
      "currency": "Foreign-currency refunds need an accountant to review the exchange difference.",
      "date": "Choose a valid refund date on or after the source document.",
      "reason": "Give a reason within 500 characters.",
      "account": "Choose a bank, cash or clearing account allowed for this method under Payment & posting.",
      "history": "Review the document history before refunding again.",
      "posting": "The refund was not posted. Check the accounting period and posting accounts before retrying.",
      "deliveryPending": "The earlier email outcome is unresolved. Review delivery history before sending again.",
      "send": "The refund note email was not confirmed. Check the contact email and delivery history before retrying.",
      "generic": "The refund was not confirmed. Review the invoice history before retrying."
    }
  },
  "gatewayPayout": {
    "refund": "Refund",
    "title": "Settle gateway payout",
    "hint": "Use this when one bank credit pays out many gateway orders. For a single customer payment, use Find match instead.",
    "hintShort": "For one credit that pays many orders.",
    "description": "Select the orders included in this bank credit. The full selected clearing balance will be settled. Any fee needs your confirmation.",
    "loading": "Loading unsettled orders...",
    "alreadySettled": "Settled {count} orders: bank credit {amount}, fee {fee}. If unmatched, rematch the existing journal entry.",
    "empty": "No unsettled gateway orders are available for this bank currency.",
    "account": "Clearing account",
    "hasMore": "Only the first 1000 unsettled orders are shown. Confirm only when every order in this bank credit is selected.",
    "selected": "Selected clearing balance",
    "bankAmount": "Bank credit",
    "difference": "Fee difference",
    "overSettlement": "The bank credit exceeds the selection. Select the remaining orders.",
    "tolerance": "Maximum fee difference you accept",
    "acceptFee": "I confirm this difference is a gateway fee.",
    "failed": "Could not settle. Check the selected orders, fee confirmation, bank match and accounting period, then try again.",
    "confirm": "Confirm payout settlement",
    "errors": {
      "postingChanged": "One of the selected orders was reversed, refunded or changed after it posted. Review that order before settling.",
      "alreadySettledItem": "One of the selected orders is already settled by another payout. Refresh and select again.",
      "feeNotConfirmed": "Confirm the exact fee difference, within the maximum you accept.",
      "conflict": "This bank line already settled a different payout. Open its match to review it.",
      "bankUnavailable": "This bank line can't be used. Choose an unused incoming credit from a reviewed bank statement in the clearing currency.",
      "feeAccount": "Set a bank charges account in Chart of Accounts, Payment & posting, then try again."
    }
  },
  "paidInvoice": {
    "action": "Issue & record as paid",
    "effect": "Issue the invoice and record {currency} {amount} as received in one step.",
    "method": "Payment method",
    "account": "Receiving account",
    "chooseAccount": "Choose a receiving account",
    "fee": "Per-order fee",
    "date": "Payment date",
    "reference": "Reference",
    "external": "Customer already has a receipt from another system",
    "externalSystem": "Receipt system",
    "externalReference": "External receipt reference",
    "willIssue": "An Official Receipt will be issued.",
    "externalPreview": "The external receipt is the receipt of record. No Groot receipt or email.",
    "pendingPreview": "The cheque awaits clearance. No Official Receipt yet.",
    "settingOff": "Official Receipts are turned off for this business.",
    "loading": "Checking receipt eligibility...",
    "confirm": "Issue & record payment",
    "working": "Recording...",
    "failed": "The invoice and payment could not be recorded. Check the account, date and posting settings, then retry.",
    "feeSettingError": "Set Bank charges under Accounting, Chart of Accounts, Payment & posting, then retry.",
    "feeInvalidError": "Enter a fee of zero or more, below the invoice total, to two decimal places.",
    "paymentRecorded": "Payment recorded",
    "externalRecorded": "Receipt of record: {system} {reference}",
    "pending": "Cheque awaiting clearance",
    "instrumentDate": "Cheque date",
    "clearanceDate": "Expected clearance date",
    "stockException": "Stock relief needs attention",
    "stockHelp": "The invoice and payment are recorded. Review product formulas, source locations and available stock, then retry stock relief.",
    "retryStock": "Retry stock relief",
    "stockRetryFailed": "Stock relief is still blocked. Review inventory availability, setup and the posting period before retrying.",
    "paidBy": "Paid by",
    "bankOrCash": "Bank or cash",
    "feeRecorded": "Fee: {currency} {amount}",
    "methods": {
      "bank_transfer": "Bank transfer",
      "cash": "Cash",
      "card": "Card",
      "cheque": "Cheque",
      "other": "Other"
    },
    "noAccountForMethod": "No receiving account is set for this payment method. Choose one in Chart of Accounts, Payment & posting.",
    "fxRateUnresolvedError": "There is no exchange rate for this currency on the invoice date, so the invoice cannot be issued yet. Add one under Accounting → Chart of Accounts → Currencies & rates, or type the rate on the invoice, then retry.",
    "lineDescriptionRequiredError": "Line {line} has no description, so the invoice was not issued. Describe it, or pick a product from the catalogue on the invoice, then record it as paid again."
  },
  "lineCategorySuggestions": {
    "title": "Category suggestions",
    "hint": "Review suggestions before applying. Save your draft to keep changes.",
    "request": "Suggest categories",
    "loading": "Finding suggestions...",
    "apply": "Apply suggestions",
    "dismiss": "Dismiss",
    "suggested": "Suggested",
    "held": "Needs your review",
    "unavailableLabel": "Unavailable",
    "kept": "Your choice kept",
    "protected": "Your category and stock choices are kept.",
    "unavailable": "Suggestions are unavailable. Choose categories manually.",
    "error": "Could not get suggestions. Try again or choose categories manually.",
    "stale": "These lines have changed. Save and request new suggestions.",
    "saveFirst": "Save changes to the line items before requesting suggestions.",
    "loadingSaved": "Loading saved line items...",
    "noEligible": "Each line already has a category or a stock decision. Your choices are kept.",
    "applied": "Suggestions applied to this draft. Save to keep them.",
    "empty": "No suggestions this time. Choose categories manually."
  },
  "statementPdf": {
    "printedPeriod": "Printed statement period: {period}. A date without a year is resolved only when it has one calendar reading within this period.",
    "printedStatementDate": "Printed statement date: {date}. A date printed without a year takes the latest matching date on or before it, and the dates must stay in order.",
    "source": "View original PDF",
    "sourceHelp": "Compare each extracted date, description, money in and money out with the original page before importing.",
    "sourceUnavailable": "The original PDF could not be opened. Try again or reopen the uploaded file.",
    "openSource": "Open PDF in a new tab",
    "sourceLoading": "Opening the original PDF…",
    "uploadHelp": "Text and scanned PDFs are supported, up to 2 MB and 12 pages. You will review the extracted rows before import.",
    "processing": "Reading the PDF pages. Scanned documents can take a little longer.",
    "imageReview": "These rows were read from page images. Check them against the original PDF. Row numbers count transactions from top to bottom on each page; uncertain rows are held for verification."
  },
  "cashManual": {
    "close": "Close entry",
    "title": "New Cash Book entry",
    "newEntry": "New entry",
    "description": "Record a cash or bank receipt or payment, then review the accounts before posting.",
    "loading": "Loading accounts…",
    "denied": "Only an owner or finance administrator can record a Cash Book entry.",
    "incomplete": "Your chart of accounts could not be loaded completely. Please try again before posting.",
    "movement": "Movement",
    "receive": "Receive",
    "pay": "Pay",
    "moneyAccount": "Bank / cash account",
    "chooseMoneyAccount": "Select a bank or cash account",
    "noMoneyAccounts": "Set up an active Cash or Bank account in your chart of accounts first.",
    "openChart": "Open Chart of Accounts",
    "date": "Date",
    "amount": "Amount ({currency})",
    "payer": "Received from",
    "payee": "Paid to",
    "particulars": "Particulars",
    "reference": "Reference",
    "allocations": "Account allocations",
    "allocationsHint": "Choose GL accounts by code or name. The allocations must add up to the receipt or payment amount.",
    "allocationAccount": "GL account for line {number}",
    "allocationAmount": "Amount for line {number}",
    "allocationDescription": "Description for line {number} (optional)",
    "searchGl": "Search by GL code or account name",
    "removeAllocation": "Remove line {number}",
    "addAllocation": "Add allocation",
    "allocated": "Allocated: {amount}",
    "remaining": "Remaining: {amount}",
    "overAllocated": "Over allocated: {amount}",
    "allocationLimit": "An entry can contain up to 20 allocations.",
    "sourceGuidance": "Accounts with their own workflow",
    "sourceGuidanceHint": "Record invoice collections, bill payments and other source transactions in their own workflow so their balances and documents stay linked.",
    "openSource": "Open workflow",
    "acknowledgement": "This is a separate receipt or payment. It is not already recorded through an invoice, bill, expense, claim, payroll, inventory or imported settlement.",
    "review": "Review entry",
    "preparing": "Preparing review…",
    "reviewTitle": "Review before posting",
    "reviewHint": "Confirming posts this entry to the ledger and Cash Book. A receipt creates an internal Receipt Voucher, not a customer Official Receipt.",
    "editDetails": "Edit details",
    "confirm": "Confirm and post",
    "posting": "Posting…",
    "posted": "Entry posted to the Cash Book.",
    "total": "Total",
    "voucher": "Voucher",
    "numberingOn": "Automatic numbering on",
    "numberingOff": "Automatic numbering off",
    "postingLines": "Journal posting",
    "glAccount": "GL account",
    "debit": "Debit",
    "credit": "Credit",
    "detailsTitle": "Cash Book entry",
    "detailsDescription": "View the recorded details, voucher and posting history.",
    "entryUnavailable": "This entry is unavailable or you do not have access to it.",
    "statementEntry": "This entry was recorded from a reviewed bank statement. Use its original source correction route.",
    "statementEntryTitle": "Record from a reviewed statement line",
    "openEntry": "View entry",
    "openJournal": "View journal entry",
    "openCashBook": "View in Cash Book",
    "voidLabel": "Void",
    "voucherFamily": {
      "rv": "Receipt Voucher",
      "pv": "Payment Voucher",
      "pcv": "Petty Cash Voucher"
    },
    "status": {
      "posted": "Posted",
      "reversed": "Reversed",
      "voided": "Voided"
    },
    "validation": {
      "account": "Select an active bank or cash account.",
      "date": "Enter a valid posting date.",
      "amount": "Enter a positive amount with no more than two decimal places.",
      "counterparty": "Enter who the money was received from or paid to.",
      "particulars": "Enter what this receipt or payment is for.",
      "reference": "Enter a receipt, payment or other supporting reference.",
      "allocations": "Choose a GL account and enter a positive amount for every allocation.",
      "totals": "The allocations must equal the receipt or payment amount exactly.",
      "acknowledgement": "Confirm that this movement has not already been recorded in another workflow."
    },
    "errors": {
      "conversionDate": "This date is before your accounting conversion date. Record opening balances through the opening balance workflow, or choose a date after conversion.",
      "access": "Your access changed. An owner or finance administrator with Accounting access must review this entry.",
      "account": "The bank or cash account is no longer available for posting. Choose an active money account and review again.",
      "allocationAccount": "One of the GL accounts is no longer available. Check the allocations and review again.",
      "sourceAccount": "This account must be posted through its own source workflow. Open that workflow to record the transaction.",
      "period": "The posting date is in a closed or locked period. Choose an open date or follow your period correction workflow.",
      "stale": "The reviewed entry is no longer current. Check the details and prepare a new review.",
      "expired": "This review expired. Check the details and review the entry again before posting.",
      "totals": "The allocations do not match the total. Check the amounts and review again.",
      "amount": "Check the amounts. Every amount must be positive and use no more than two decimal places.",
      "currency": "This entry must use the supported currency of your bank or cash account.",
      "date": "Check the posting date and review the entry again.",
      "details": "Check the payer or payee, particulars and supporting reference.",
      "acknowledgement": "Confirm that this is a separate movement before reviewing again.",
      "chart": "Your chart could not be loaded completely. Please retry before posting.",
      "voucher": "The voucher settings could not be confirmed. Check the settings before posting.",
      "alreadyPosted": "This request has already posted an entry. Check the Cash Book before starting a new entry.",
      "unexpected": "We could not complete this step. Please try again. If a posting was submitted, retrying the same confirmation will not create a duplicate."
    }
  },
  "accountingCorrections": {
    "modes": {
      "audit_first": "Audit-first correction",
      "adjustment": "Adjustment",
      "official_reversal": "Official reversal",
      "refused": "Correction unavailable"
    },
    "modeDescriptions": {
      "audit_first": "Updates this posted record and keeps its prior values in history.",
      "adjustment": "Keeps the original record and posts only the required difference.",
      "official_reversal": "Cancels the complete economic event with an exact linked mirror.",
      "refused": "This record has reached a protected accounting boundary."
    },
    "nextActions": {
      "adjustment": "an adjustment",
      "official_reversal": "an official reversal",
      "view_source": "the source record",
      "reimport": "a re-import"
    },
    "reasons": {
      "eligible_open": "This record can be corrected with a complete audit trail.",
      "period_locked": "The accounting period is locked.",
      "paid_or_settled": "This record has been paid or settled.",
      "reconciled": "This record is linked to a bank reconciliation.",
      "inventory_dependency": "This record has an inventory or cost-of-goods dependency.",
      "externally_finalized": "This record was finalized in an external system.",
      "payroll_finalized": "This payroll record is finalized.",
      "active_correction_document": "A correction document already exists.",
      "source_owned": "Make this change from the source record.",
      "stale_version": "This record changed after you opened it.",
      "unbalanced": "The corrected journal would not balance.",
      "invalid_account": "One or more ledger accounts are no longer valid.",
      "unsupported_dependency": "A linked record prevents this correction.",
      "source_attribute_not_allowed": "This field cannot be corrected on this record.",
      "unknown_finality": "We could not confirm whether this record is still open for correction. Refresh and try again.",
      "metadata_field_not_allowed": "That note or reference cannot be edited on this record."
    },
    "errors": {
      "period_locked": "The period is locked. Record an adjustment in an open period.",
      "paid_or_settled": "This record is settled. Use the available adjustment or reversal action.",
      "reconciled": "Unmatch the bank transaction before changing this record.",
      "inventory_dependency": "Use the inventory correction flow for this record.",
      "externally_finalized": "This record is final in an external system and cannot be edited here.",
      "payroll_finalized": "Use the payroll correction flow for this finalized run.",
      "active_correction_document": "Review the existing correction document before creating another.",
      "source_owned": "Open the source record to make this change.",
      "stale_version": "This record was updated by someone else. Reload it and review the latest values.",
      "unbalanced": "Debits and credits must balance before saving.",
      "invalid_account": "Choose active ledger accounts before saving.",
      "unsupported_dependency": "A linked record prevents this correction.",
      "autocount_write_in_flight": "This invoice is being written to AutoCount, or its AutoCount outcome is still unknown. Wait for the write to finish, or resolve it from the AutoCount card, before correcting it.",
      "unauthorized": "You do not have permission to correct this record.",
      "unknown": "The correction could not be saved. Reload the record and try again.",
      "sql_bridge_write_in_flight": "This invoice is being written to SQL Account, or its SQL Account outcome is still unknown. Wait for the write to finish, or resolve it from the SQL Bridge settings, before correcting it.",
      "correction_raises_approved_claim": "This correction raises the claim above what was approved. Use \"Send back for correction\" on the claim in Payment Processing so it can be approved again."
    },
    "dialog": {
      "title": "Correct posted record",
      "description": "Review what changes before saving. The previous values remain in Change history.",
      "preview": "Before and after",
      "field": "Field",
      "before": "Before",
      "after": "After",
      "noChanges": "No changed fields to review.",
      "previewLimit": "{count} more changes are recorded in the full history.",
      "reasonLabel": "Reason for change",
      "reasonPlaceholder": "Explain why this record needs correcting",
      "reasonHint": "Finance reviewers will see this reason in the audit trail.",
      "blockedTitle": "This record cannot be corrected in place",
      "errorTitle": "Correction not saved",
      "nextAction": "Continue with {action}",
      "cancel": "Cancel",
      "save": "Save correction",
      "saving": "Saving…"
    },
    "actions": {
      "title": "Correction options",
      "createCreditNote": "Create credit note",
      "createDebitNote": "Create debit note",
      "cancelInvoice": "Cancel invoice in full",
      "inPlaceUnavailable": "In-place correction is unavailable",
      "review": "Review correction",
      "correctPosting": "Correct posting",
      "supplierCreditNote": "Supplier credit note",
      "supplierDebitNote": "Supplier debit note"
    },
    "fields": {
      "supplier": "Supplier",
      "invoiceNumber": "Invoice number",
      "supplierInvoiceDate": "Supplier invoice date",
      "dueDate": "Due date",
      "subtotal": "Subtotal",
      "tax": "Tax",
      "discount": "Discount",
      "total": "Total",
      "issueDate": "Issue date",
      "lineItems": "Line items",
      "line": "Line {number}",
      "lineField": "Line {number} {field}",
      "description": "Description",
      "quantity": "Quantity",
      "unitPrice": "Unit price",
      "vendor": "Vendor",
      "amount": "Amount",
      "receiptDate": "Receipt date",
      "category": "Category",
      "accountingDate": "Accounting date",
      "expenseAccount": "Expense account",
      "account": "Account"
    },
    "purchaseInvoice": {
      "title": "Correct posted invoice",
      "description": "The invoice and journal entry keep their identity. Previous values remain in Change history.",
      "locked": {
        "receivedTitle": "Stock from this bill is in your inventory",
        "receivedDescription": "The goods on this bill have been received into inventory, so its amounts and lines are locked. That keeps your stock value and your books in step.",
        "paidTitle": "This bill has a payment recorded",
        "paidDescription": "A payment has been recorded against this bill, so its amounts are locked to match what you paid.",
        "nextSteps": "If the supplier gives you a discount or refund, create a credit note. If they add a charge, create a debit note."
      }
    },
    "salesInvoice": {
      "title": "Correct posted invoice",
      "description": "Update this internally controlled invoice without creating reversal entries. Previous values remain in Change history.",
      "checking": "Checking correction options…",
      "paymentRecorded": {
        "title": "Invoices with a payment can't be edited",
        "description": "A payment has been recorded against this invoice, so its details are locked to keep your books consistent with what the customer paid.",
        "nextSteps": "To lower the amount or credit the customer, create a credit note. To add a charge, create a debit note. If the payment itself was recorded by mistake, reverse it in Payment history.",
        "cashSaleNextSteps": "To lower the amount or credit the customer, create a credit note. To add a charge, create a debit note. If the sale itself was entered by mistake, use Void at the top of this page."
      },
      "locked": {
        "title": "This invoice is locked",
        "sent": "It has been sent to the customer, so its lines and amounts can't be edited.",
        "stock": "Its goods have left your stock, so its lines and amounts can't be edited.",
        "sentAndStock": "It has been sent to the customer and its goods have left your stock, so its lines and amounts can't be edited.",
        "lhdn": "It has been submitted to LHDN as an e-invoice, so its lines and amounts can't be edited.",
        "lhdnAndStock": "It has been submitted to LHDN as an e-invoice and its goods have left your stock, so its lines and amounts can't be edited.",
        "peppol": "It has been sent to the customer as a Peppol e-invoice, so its lines and amounts can't be edited.",
        "peppolAndStock": "It has been sent to the customer as a Peppol e-invoice and its goods have left your stock, so its lines and amounts can't be edited.",
        "nextSteps": "To lower the amount or credit the customer, create a credit note. To add a charge, create a debit note.",
        "voidNextStep": "If the whole invoice was a mistake, use Void at the top of this page.",
        "facts": {
          "sent": "It has been sent to the customer.",
          "stock": "Its goods have left your stock.",
          "lhdn": "It has been submitted to LHDN as an e-invoice.",
          "peppol": "It has been sent to the customer as a Peppol e-invoice."
        }
      }
    },
    "expenseClaim": {
      "ariaLabel": "Posted claim correction"
    },
    "businessExpense": {
      "ariaLabel": "Posted business expense correction"
    },
    "dimensions": {
      "all": "All",
      "unassigned": "Unassigned",
      "project": "Project",
      "department": "Department",
      "location": "Location",
      "salesAgent": "Sales agent",
      "teamMember": "Team member"
    },
    "salesAgent": {
      "label": "Sales agent",
      "unassigned": "Unassigned",
      "teamMember": "Team member"
    },
    "agentConfirmation": {
      "ariaLabel": "Accounting correction review",
      "title": "Review accounting correction",
      "before": "Before",
      "after": "After",
      "fingerprint": "Fingerprint: {fingerprint}",
      "completed": "Correction completed",
      "historical": "Historical confirmation (read only)",
      "expired": "This confirmation expired.",
      "confirming": "Confirming…",
      "confirm": "Confirm correction",
      "errors": {
        "stale": "This record changed. Review a fresh preview before confirming.",
        "unauthorized": "You no longer have permission to confirm this correction.",
        "expired": "This confirmation expired. Prepare a fresh correction.",
        "alreadyConfirmed": "This correction was already confirmed.",
        "unknown": "We could not confirm this correction. Please try again.",
        "raisesApprovedClaim": "This correction raises the claim above what was approved, so nothing was changed. Send the claim back for correction from Payment Processing so it can be approved again."
      }
    },
    "sourceOwned": {
      "title": "Corrections",
      "unavailable": "We can't show correction guidance for this record right now.",
      "draft": "You can discard this draft and import a corrected file.",
      "voidImport": "Void import",
      "route": {
        "void_and_reimport": "Void this import, correct the source file, then import it again.",
        "recommit_statement": "Re-commit the statement to replace this posting.",
        "reingest_week": "Upload that week's statement again to replace this posting.",
        "resolve_hold": "Resolve the overlapping settlement to continue.",
        "none": "This record is corrected in the system it came from.",
        "unmatch_and_rematch": "Clear the bank match in Bank reconciliation, correct this record, then match it again."
      },
      "reversedPostings": "Reversed postings: {count}",
      "bankRoute": {
        "unmatchTransaction": {
          "cta": "Unmatch in Bank reconciliation",
          "guidance": "This record is matched to a bank transaction. Unmatch it in Bank reconciliation before correcting it, then match the corrected record again."
        },
        "rejectSuggestedMatch": {
          "cta": "Reject match in Bank reconciliation",
          "guidance": "A suggested bank match is waiting on this record. Reject the match in Bank reconciliation before correcting it, then match the corrected record again."
        }
      }
    },
    "documentActivity": {
      "title": "Document activity",
      "description": "Every recorded action for this document.",
      "empty": "No activity recorded for this document yet.",
      "error": "Document activity could not be loaded. Refresh and try again.",
      "showDetails": "Show details",
      "hideDetails": "Hide details",
      "loadMore": "Load more activity",
      "loading": "Loading activity…",
      "system": "System",
      "by": "By {actor}",
      "details": "Details"
    },
    "history": {
      "title": "Change history",
      "empty": "No changes recorded yet.",
      "error": "Change history could not be loaded. Refresh and try again.",
      "incomplete": "Some revision details are too large to display here. Open the related source or journal for the complete record.",
      "reason": "Reason",
      "by": "By {actor}",
      "showChanges": "Show changes",
      "hideChanges": "Hide changes",
      "field": "Field",
      "before": "Before",
      "after": "After",
      "loadMore": "Load more",
      "loading": "Loading…",
      "system": "System",
      "navigation": "Related accounting records",
      "viewSource": "View source",
      "viewJournal": "View journal entry",
      "reversalGroup": "Linked reversal group {id}",
      "modes": {
        "audit_first": "Audit-first correction",
        "adjustment": "Adjustment",
        "official_reversal": "Official reversal",
        "refused": "Correction unavailable"
      }
    },
    "settlement": {
      "laneLabel": "How this was paid",
      "laneHelp": "Credit means the supplier is still owed. Direct means it was already paid when you got the document.",
      "payFromLabel": "Paid from",
      "lane": {
        "ap": "Credit purchase (still owed)",
        "cash": "Direct purchase (already paid)"
      }
    },
    "reasonFallback": "This record can't be changed here right now. Contact support if you need help correcting it."
  },
  "operationalSalesOrders": {
    "page": {
      "title": "Sales orders",
      "subtitle": "Create, approve and convert customer commitments"
    },
    "title": "Sales orders",
    "description": "Turn accepted customer commitments into linked AR invoices.",
    "actions": {
      "new": "New sales order",
      "revise": "Revise order",
      "submit": "Submit",
      "accept": "Accept order",
      "cancelOrder": "Cancel order",
      "cancelReasonPrompt": "Why is this order being cancelled?",
      "convert": "Convert to invoice",
      "viewInvoice": "View linked invoice",
      "close": "Close",
      "cancel": "Cancel",
      "saving": "Saving…",
      "saveDraft": "Save draft",
      "saveRevision": "Save revision",
      "viewQuotation": "View source quotation",
      "downloadPdf": "Download PDF"
    },
    "list": {
      "navigationLabel": "Sales orders",
      "empty": "No sales orders yet.",
      "loadMore": "Load more orders",
      "loading": "Loading orders…",
      "poNumber": "Customer PO {number}",
      "searchLabel": "Search by customer PO number",
      "searchPlaceholder": "Customer PO number",
      "searchAction": "Search",
      "noPoMatch": "No sales order has the customer PO number {number}.",
      "statusFilterLabel": "Status",
      "statusAll": "All statuses",
      "noStatusMatch": "Nothing has this status."
    },
    "detail": {
      "selectPrompt": "Select an order to review it.",
      "versionStatus": "Version {version} · {status}",
      "subtotal": "Subtotal",
      "discount": "Discount",
      "tax": "Tax",
      "total": "Order total",
      "customer": "Customer",
      "oneOffBadge": "One-off customer",
      "oneOffHint": "Not in your customer list. The details are kept on this order only.",
      "priceChangeReason": "Reason for the price change",
      "lines": "Lines",
      "lineQuantity": "{quantity} at {price}",
      "lineDiscount": "Less {amount}"
    },
    "status": {
      "draft": "Draft",
      "submitted": "Submitted",
      "accepted": "Accepted",
      "converted": "Converted",
      "cancelled": "Cancelled",
      "declined": "Declined",
      "expired": "Expired"
    },
    "history": {
      "title": "Change history",
      "versionChange": "Version {from} → {to}",
      "loadMore": "Load more history",
      "loading": "Loading history…",
      "actions": {
        "created": "Created",
        "revised": "Revised",
        "submitted": "Submitted",
        "accepted": "Accepted",
        "converted": "Converted",
        "cancelled": "Cancelled",
        "declined": "Declined",
        "expired": "Expired",
        "reopened": "Reopened after its draft invoice was deleted"
      }
    },
    "editor": {
      "createTitle": "New sales order",
      "reviseTitle": "Revise {number}",
      "description": "Terms, reporting dimensions and line details carry into the linked invoice."
    },
    "form": {
      "orderDetails": "Order details",
      "unassigned": "Unassigned",
      "customer": "Customer",
      "chooseCustomer": "Choose a customer",
      "orderDate": "Order date",
      "paymentTerms": "Payment terms",
      "currency": "Currency",
      "fxHint": "For foreign-currency orders, the invoice captures the configured FX rate on its invoice date.",
      "notes": "Notes",
      "revisionReason": "Reason for revision",
      "customerPoNumber": "Customer's PO number",
      "sourceChannel": "Received by",
      "sourceFiles": "Customer PO or order photo",
      "sourceFilesHint": "PDF or image, up to 10 MB each and 10 files per order. Files you add stay on the order; they are never replaced.",
      "customerChoice": "Who is this for?",
      "customerExisting": "Customer on file",
      "customerNew": "New customer",
      "newCustomer": {
        "hint": "Only the name is needed. Add a TIN or registration number only if you have it: the invoice made from this document is filed with them.",
        "businessName": "Company or person name",
        "email": "Email",
        "contactPerson": "Contact person",
        "phone": "Phone",
        "address": "Address",
        "tin": "TIN (tax identification number)",
        "brn": "Registration number",
        "save": "Save as a regular customer",
        "saveHintOn": "Adds this customer to your customer list so you can pick them next time. An email address is needed.",
        "saveHintOff": "A one-off customer. The details stay on this order and nothing is added to your customer list.",
        "alreadyExists": "{name} is already in your customer list.",
        "useExisting": "Use this customer"
      },
      "deliveryTolerance": "Over-delivery tolerance, %",
      "deliveryToleranceHint": "Optional. How many percent past the ordered quantity a delivery may go, for each line. Leave blank for none: a delivery can then never exceed the order.",
      "priceChangeReason": "Why is the price different from the standard price?",
      "priceChangeReasonHint": "Finance sees this. The customer does not."
    },
    "terms": {
      "due_on_receipt": "Due on receipt",
      "net_14": "Net 14",
      "net_15": "Net 15",
      "net_30": "Net 30",
      "net_60": "Net 60",
      "custom": "Custom"
    },
    "lines": {
      "title": "Line items",
      "add": "Add line",
      "rowLabel": "Line item {number}",
      "description": "Description",
      "itemCode": "Item code",
      "itemCodeLabel": "Item code for line {number}",
      "quantity": "Quantity",
      "quantityLabel": "Quantity for line {number}",
      "unit": "Unit",
      "unitLabel": "Unit for line {number}",
      "unitPrice": "Unit price",
      "unitPriceLabel": "Unit price for line {number}",
      "taxRate": "Tax %",
      "taxRateLabel": "Tax rate for line {number}",
      "discountType": "Discount type",
      "discountTypeLabel": "Discount type for line {number}",
      "discountValue": "Discount value",
      "discountValueLabel": "Discount value for line {number}",
      "noDiscount": "No discount",
      "percentageDiscount": "Percentage",
      "fixedDiscount": "Fixed amount",
      "removeLabel": "Remove line {number}",
      "item": "Item",
      "itemLabel": "Item for line {number}",
      "standardPrice": "Standard price {price}",
      "tierPrice": "{tier} price {price}",
      "promotionPrice": "Promotion price {price}",
      "useStandardPrice": "Use this price"
    },
    "dimensions": {
      "title": "Reporting dimensions",
      "project": "Project",
      "department": "Department",
      "location": "Location",
      "salesAgent": "Sales agent",
      "repNoAgent": "No sales agent is linked to you, so you can save only a one-off customer. Ask the business owner or a finance admin to link one."
    },
    "errors": {
      "invalidForm": "Choose a customer and complete every line with a description, positive quantity and valid amounts.",
      "reasonRequired": "Enter a reason for this revision.",
      "createFailed": "The sales order could not be saved. Reload the page and try again.",
      "reviseFailed": "The revision could not be saved. Reload the latest order and try again.",
      "actionFailed": "This order changed or the action is no longer available. Reload it before trying again.",
      "loadFailed": "Sales orders could not be loaded. Refresh and try again.",
      "documentNotFound": "We could not find that document. It may have been removed, or it may not be available to you.",
      "cancelHasDeliveries": "This order has delivery orders. Cancel or void them first, then cancel the order.",
      "sourceFilesInvalid": "Each file must be 10 MB or smaller, and an order holds at most 10 files.",
      "dueDateRequired": "Choose a due date first. Custom payment terms have no number of days to work it out from.",
      "dueDateInvalid": "The due date must be today or later.",
      "newCustomerName": "Enter the new customer's name.",
      "newCustomerEmail": "Enter a valid email address. A one-off customer can leave it empty (switch off \"Save as a regular customer\").",
      "newCustomerInvalid": "Some of the new customer's details are not valid. Check them and try again.",
      "customerAlreadyExists": "A customer with this name is already in your customer list. Choose them from the list instead.",
      "actionNotCompleted": "That could not be completed. Nothing was changed. Try again, and if it keeps happening, contact support.",
      "priceReasonRequired": "A line is priced differently from its catalogue price, and no reason was given for the difference. Nothing was converted. Create the invoice from New Sales Invoice and give the reason there.",
      "catalogItemNotSellable": "A catalogue item on this document is switched off for sale, so it cannot be invoiced. Switch it back on in the catalogue, then convert it again.",
      "invoiceLimitReached": "This month's invoice limit for your plan has been reached, so nothing was converted. Upgrade to Pro to issue more invoices.",
      "deliveryToleranceInvalid": "Enter the tolerance as a percent from 0 to 100, with at most two decimals.",
      "billedOnDelivery": "This order is invoiced delivery by delivery, so it cannot be converted whole. Invoice its delivery orders instead.",
      "customerNameTaken": "A customer with this name already exists. Use a different name, or ask the business owner or a finance admin to assign that customer to you.",
      "salesAgentNeeded": "To save a new customer to your list you need a sales agent linked to you. Ask the business owner or a finance admin to link one, or turn off \"Save as a regular customer\".",
      "customerNotFound": "That customer is not available to you. Choose a customer from the list.",
      "dimensionNotFound": "One of the choices on this form (project, department, location or sales agent) is not available to you. Reload the page and choose again.",
      "priceChangeReasonRequired": "Say why the price or discount differs from the standard price."
    },
    "loading": "Loading sales orders…",
    "source": {
      "title": "Where this order came from",
      "poNumber": "Customer's PO number",
      "channel": "Received by",
      "receivedAt": "Received on",
      "none": "Not recorded",
      "fileUnavailable": "file unavailable",
      "channels": {
        "manual": "Entered by hand",
        "customer_po": "Customer PO",
        "email": "Email",
        "chat": "Chat message",
        "whatsapp": "WhatsApp",
        "photo": "Photo or note",
        "other": "Other"
      }
    },
    "quotation": {
      "page": {
        "title": "Quotations",
        "subtitle": "Quote a customer, then turn it into a sales order or an invoice"
      },
      "title": "Quotations",
      "description": "Send a price to a customer. When they accept, turn it into a sales order or straight into an invoice.",
      "actions": {
        "new": "New quotation",
        "submit": "Mark as sent",
        "accept": "Customer accepted",
        "decline": "Customer declined",
        "declineReasonPrompt": "Why did the customer decline?",
        "expire": "Mark as expired",
        "convertToOrder": "Convert to sales order",
        "viewOrder": "View sales order",
        "cancelOrder": "Cancel quotation",
        "cancelReasonPrompt": "Why is this quotation being cancelled?",
        "downloadPdf": "Download PDF",
        "send": "Send by email"
      },
      "editor": {
        "createTitle": "New quotation",
        "reviseTitle": "Revise {number}"
      },
      "list": {
        "empty": "No quotations yet.",
        "loading": "Loading quotations…",
        "loadMore": "Load more quotations"
      },
      "form": {
        "quotationDate": "Quotation date",
        "fxHint": "For foreign-currency quotations, the invoice captures the configured FX rate on its invoice date.",
        "validUntil": "Valid until",
        "orderDetails": "Quotation details",
        "sourceFiles": "Customer request or reference file",
        "sourceFilesHint": "PDF or image, up to 10 MB each and 10 files per quotation. Files you add stay on the quotation; they are never replaced."
      },
      "detail": {
        "validUntil": "Valid until {date}.",
        "expiredNote": "This quotation has passed its validity date.",
        "total": "Quotation total",
        "selectPrompt": "Select a quotation to review it."
      },
      "errors": {
        "validUntilInvalid": "Choose a validity date on or after the quotation date.",
        "expired": "This quotation passed its validity date. Mark it expired, or issue a new quotation.",
        "createFailed": "The quotation could not be saved. Reload the page and try again.",
        "reviseFailed": "The revision could not be saved. Reload the latest quotation and try again.",
        "actionFailed": "This quotation changed or the action is no longer available. Reload it before trying again.",
        "sourceFilesInvalid": "Each file must be 10 MB or smaller, and a quotation holds at most 10 files."
      },
      "source": {
        "title": "Where this quotation came from"
      },
      "toast": {
        "created": "Quotation saved.",
        "revised": "Quotation revised."
      },
      "send": {
        "title": "Send {number} to the customer",
        "description": "Emails the quotation to the customer as a PDF attachment. Replies go to your business email address.",
        "loading": "Loading…",
        "recipientLabel": "Send to",
        "recipientHint": "The customer's email address. Change it or add more, separated by commas. The customer record is not changed.",
        "recipientHintSeveral": "{count} addresses. They all get the same email and can see each other's address. The customer record is not changed.",
        "recipientsAndMore": "{recipients} and {count} more",
        "noRecipient": "This customer has no email address on file. Enter one to send.",
        "invalidRecipient": "{address} is not a valid email address. Separate several addresses with commas.",
        "tooManyRecipients": "One send can go to at most {max} addresses. You have {count}.",
        "draftNote": "Sending also marks this draft as sent.",
        "alreadySentTitle": "This quotation was already sent",
        "alreadySent": "Sent {when} to {recipient}. Sending again emails everyone in the Send to box.",
        "unconfirmedTitle": "An earlier send could not be confirmed",
        "unconfirmed": "A send to {recipient} may or may not have reached the customer. Ask them before sending again.",
        "confirmResend": "Yes, send it again",
        "submit": "Send quotation",
        "submitAgain": "Send again",
        "sending": "Sending…",
        "toast": {
          "sent": "Quotation sent to {recipient}.",
          "alreadySent": "This quotation was already sent to {recipient}. Nothing new was sent."
        },
        "closed": {
          "expired": "This quotation passed its validity date, so it cannot be sent. Issue a new quotation instead.",
          "declined": "The customer declined this quotation, so it cannot be sent.",
          "notOpen": "This quotation was cancelled or converted, so it is no longer open and cannot be sent."
        },
        "errors": {
          "notFound": "This quotation could not be found. Reload the page and try again.",
          "signedOut": "Your session has ended. Sign in again, then send the quotation.",
          "invalidRecipient": "Enter valid email addresses, separated by commas.",
          "tooManyRecipients": "That is too many addresses for one send. Send it in smaller groups.",
          "noRecipient": "This customer has no email address on file. Enter one to send.",
          "alreadySent": "This quotation was already sent. Tick the box to send it again.",
          "blocked": "Another send of this quotation to one of these addresses is still in progress or unresolved. Check the list below before trying again.",
          "failed": "The email could not be sent, so nothing was recorded as sent. Check the address and try again. If it keeps failing, contact support.",
          "unknown": "We could not confirm that the email reached the customer. Do not send it again yet: ask the customer whether it arrived.",
          "generic": "We could not confirm that the quotation was sent. Look at \"Sent to the customer\" below before trying again.",
          "changed": "This quotation was changed while you were sending it. Nothing was sent. Reload it and send it again."
        },
        "history": {
          "title": "Sent to the customer",
          "empty": "Not sent by email yet.",
          "by": "by {name}",
          "truncated": "Only the most recent sends are shown.",
          "state": {
            "queued": "Sending",
            "attempting": "Sending",
            "accepted": "Sent",
            "failed": "Not sent (failed)",
            "unknown": "Not confirmed",
            "reconciliation_required": "Needs checking"
          },
          "version": "Version {version}",
          "revisedSince": "revised since"
        },
        "retryNote": "The last attempt did not give an answer. Retrying sends this same request again, so it cannot email the customer twice."
      }
    },
    "handoff": {
      "title": "Waiting for your confirmation ({count})",
      "description": "A manager prepared these drafts through the assistant. Only an owner or finance admin can confirm them.",
      "newOrder": "New order",
      "revision": "Change to {number}",
      "preparedBy": "Prepared by {name} on {date}",
      "unknownPreparer": "a team member",
      "viewOrder": "View order",
      "confirm": "Confirm",
      "confirming": "Confirming...",
      "errors": {
        "changed": "This draft changed or expired. Ask the manager to prepare it again.",
        "failed": "We could not confirm this draft. Nothing was saved. Please try again.",
        "customerExists": "A customer with this name is already in your customer list. Ask the manager to prepare the draft again with that customer."
      },
      "newQuotation": "New quotation",
      "reviewLines": "Review lines ({count})",
      "hideLines": "Hide lines ({count})",
      "reviewFirst": "Open the lines to review them before you confirm.",
      "detail": {
        "detailsTitle": "Details",
        "changesTitle": "What changes",
        "before": "Before",
        "after": "After",
        "linesTitle": "Lines",
        "linesUnchanged": "The lines do not change.",
        "reason": "Reason for the change",
        "notSet": "Not set",
        "noLines": "This draft has no lines.",
        "amount": "Amount",
        "total": "Total",
        "truncated": "Showing the first {shown} of {count} lines. The total above covers all {count}.",
        "tax": "Tax {rate}%",
        "discountPercent": "Discount {value}%",
        "discountFixed": "Discount {value}",
        "shortened": "(text shortened)",
        "changedShortened": "Changed (text shortened)",
        "otherChanges": "Other changes: {fields}",
        "lineChanged": "Changed",
        "changedLinesHidden": "Changed lines not shown here: {count}",
        "itemCode": "Item code: {code}"
      },
      "newCustomerSaved": "New customer, added to your customer list when you confirm",
      "newCustomerOneOff": "One-off customer, not added to your customer list"
    },
    "readyToInvoice": {
      "title": "Ready to invoice ({count})",
      "description": "Accepted sales orders that nobody has invoiced yet. Open one to convert it to an invoice.",
      "agent": "Sales agent: {name}",
      "priceMatches": "Prices match the catalogue",
      "priceNotChecked": "Prices were not checked against the catalogue",
      "priceDiffers": "{count, plural, one {# line is priced away from the catalogue} other {# lines are priced away from the catalogue}}",
      "truncated": "Showing the newest {count}. Convert or cancel some to see older orders.",
      "loadFailed": "We could not load the orders that are ready to invoice. Reload the page to try again.",
      "priceReason": "Reason: {reason}",
      "customLines": "{count, plural, one {# custom line, not in the catalogue} other {# custom lines, not in the catalogue}}"
    },
    "toast": {
      "created": "Sales order saved.",
      "revised": "Sales order revised."
    },
    "convertDueDate": {
      "label": "Due date",
      "hint": "Custom payment terms have no number of days, so choose the day this invoice falls due."
    },
    "deliveries": {
      "title": "Deliveries",
      "description": "What has gone out against this order, counted in the order's own units.",
      "loading": "Loading deliveries...",
      "loadFailed": "The deliveries of this order could not be loaded. Reload the page to try again.",
      "blocked": "What was delivered on this order is counted in units that cannot be added together, so no balance is shown. Open the deliveries to see which.",
      "tolerance": "Tolerance {percent}%",
      "raise": "Raise a delivery",
      "columns": {
        "line": "Line",
        "ordered": "Ordered",
        "delivered": "Delivered",
        "remaining": "Remaining",
        "allowedOver": "Allowed over",
        "valueLeft": "Value left (estimate)"
      },
      "valueLeftHint": "The value left is the remaining quantity at the order price. It is an estimate and posts nothing.",
      "none": "Nothing has been delivered against this order yet.",
      "listLabel": "Deliveries of this order",
      "noStockMoved": "No stock moved",
      "overBy": "{quantity} over the ordered quantity",
      "sourceVoided": "The invoice this order became was voided, deleted or cancelled, so no delivery can be raised against it any more.",
      "page": {
        "title": "Deliveries",
        "subtitle": "Raise a delivery for an accepted sales order. Your finance team posts it when the goods go out."
      }
    },
    "billedOnDelivery": "Billed on delivery",
    "convertDialog": {
      "title": "Convert the whole order?",
      "lead": "Converting makes one invoice for the whole order, whatever has been delivered so far.",
      "confirm": "Convert the whole order",
      "cancel": "Cancel"
    },
    "repAcceptedNote": "Finance takes it from here: they turn an accepted order into an invoice. If your business ships on delivery orders, you can still draft one for it.",
    "repDescription": "Your sales orders. Finance turns an accepted order into an invoice."
  },
  "bankAccountSelect": {
    "label": "Bank Account",
    "placeholder": "Select bank account",
    "placeholderNoBank": "Select an account",
    "help": "The bank account this money moves through. Used for the ledger and bank reconciliation.",
    "onlyDefaultHint": "Only your default account is listed. To choose a specific bank, pick where your bank accounts live under Accounting → Chart of Accounts → Posting accounts.",
    "payFromLabel": "Paid from",
    "payFromAccountLabel": "Pay from account",
    "payFromHelp": "The bank or cash account this money left. Used for the ledger and bank reconciliation.",
    "receivedIntoLabel": "Received into",
    "depositToAccountLabel": "Deposit to account",
    "receivedIntoHelp": "The ledger account this money landed in. The choices match the payment method.",
    "paymentAccountPlaceholder": "Choose an account",
    "paymentAccountHelp": "Only accounts configured for this payment method are shown.",
    "loading": "Loading accounts…",
    "noAccountsForMethod": "No account is configured for this payment method. Add one under Accounting → Chart of Accounts → Posting accounts.",
    "paymentAccountRequired": "Choose the account this payment uses."
  },
  "salesImportV2": {
    "setup": "Import settings",
    "setupHelp": "Set the default tax treatment, compensation handling, and posting accounts for sales imports.",
    "setupRules": "Tax and compensation",
    "setupRulesHelp": "Set the default tax and compensation treatment. Posting accounts are set on this page.",
    "salesTaxBasis": "How does GrabFood report sales tax?",
    "sourceTax": "Use tax from the file",
    "inclusiveTax": "Prices include 9% GST",
    "sourceTaxHelp": "Use the order tax reported by GrabFood.",
    "inclusiveTaxHelp": "Separate the GST already included in customer prices.",
    "taxBasisRequired": "Choose one to continue.",
    "taxBasisHelp": "Only GrabFood imports use this setting. Groot templates use the tax amount entered in the file.",
    "taxProfile": "Tax profile: {context}",
    "taxContextSgRegistered": "Singapore, GST registered",
    "taxContextSgUnregistered": "Singapore, not GST registered",
    "taxContextMy": "Malaysia",
    "taxContextOther": "Country not set",
    "taxContextHelp": "Update the country and tax registration in Business Profile.",
    "inputTreatment": "Tax on platform fees",
    "expenseTax": "Include in expenses",
    "reviewTax": "Record as Input GST, review later",
    "claimTax": "Record as Input GST, claim after posting",
    "expenseTaxHelp": "No Input GST claim will be created.",
    "reviewTaxHelp": "Record Input GST and review it in the GST report before filing.",
    "claimTaxHelp": "Record Input GST as claimable. A report date and confirmation are required.",
    "claimHelp": "Platform GST comes from the uploaded file.",
    "nonRegisteredHelp": "Platform tax is included in expenses.",
    "zeroOrderTaxTitle": "Grab reports zero sales tax",
    "zeroOrderTaxHelp": "Every row reports zero Tax on Order Value. If prices include Singapore GST, select Prices include 9% GST instead.",
    "zeroOrderTaxConfirm": "I checked the file and confirm that Output GST is zero.",
    "compensation": "Positive order compensation",
    "otherIncome": "Other income",
    "reduceFees": "Reduce platform fees",
    "salesRevenue": "Sales revenue",
    "salesRevenueLegacy": "Sales revenue (existing setting)",
    "compensationHelp": "The original compensation remains identifiable, whichever destination you choose.",
    "compensationWarning": "Choose a new treatment before saving. Sales revenue is no longer available for new settings.",
    "destinations": "Posting accounts",
    "assignmentTitle": "Meaning-specific account assignments",
    "agentReviewTitle": "AI bookkeeping review",
    "agentReviewPending": "The bookkeeping agent is reading this statement. Posting stays blocked until review is ready.",
    "agentReviewReady": "Review each proposed meaning and account, then confirm the bookkeeping review.",
    "agentReviewConfirmed": "Bookkeeping review confirmed by a human reviewer.",
    "agentReviewFailed": "The bookkeeping agent could not produce a valid review. This import cannot be confirmed yet.",
    "confirmAgentReview": "Confirm bookkeeping review",
    "agentReviewConfirmedToast": "Bookkeeping review confirmed",
    "agentReviewMeaning": "Meaning",
    "agentReviewTreatment": "Treatment",
    "agentReviewRole": "Posting role",
    "agentReviewAccount": "Resolved account",
    "agentReviewConfidence": "Confidence",
    "agentReviewReason": "Why",
    "assignmentHelp": "Choose a tenant account for a specific economic meaning. Leave it on default to use the posting account above.",
    "assignmentDefault": "Use posting account default",
    "assignmentTreatment": "Treatment",
    "assignmentRole": "Posting role",
    "assignmentAccount": "Account",
    "assignmentTreatment_revenue": "Revenue",
    "assignmentTreatment_contra_revenue": "Contra revenue",
    "assignmentTreatment_expense": "Expense",
    "assignmentTreatment_input_tax": "Input tax",
    "assignmentTreatment_output_tax": "Output tax",
    "assignmentTreatment_clearing": "Clearing",
    "assignmentTreatment_other_income": "Other income",
    "assignmentTreatment_other_expense": "Other expense",
    "assignmentSourceLabel": "from {labels}",
    "businessAssignmentReason": "Selected by the business accounting practice.",
    "sourceMappingTitle": "Source column needs a meaning",
    "sourceMappingHelp": "This column contains money but is not part of the controlled source format. Choose its economic meaning before continuing.",
    "sourceMappingMeaning": "Meaning for source column",
    "sourceMappingChoose": "Choose a meaning",
    "sourceMappingEvidence": "{nonZero} non-zero values across {total} rows",
    "meaning_sales_revenue": "Sales revenue",
    "meaning_merchant_funded_discount": "Merchant-funded discount",
    "meaning_platform_commission": "Platform commission",
    "meaning_platform_service_charge": "Platform service charge",
    "meaning_marketing_fee": "Marketing or advertising fee",
    "meaning_payment_processing_fee": "Payment processing fee",
    "meaning_provider_tax": "Tax on provider charges",
    "meaning_output_tax": "Output tax on sales",
    "meaning_order_compensation": "Order compensation",
    "meaning_settlement_clearing": "Settlement clearing",
    "meaning_other_income_adjustment": "Other income adjustment",
    "meaning_other_expense_adjustment": "Other expense adjustment",
    "chooseAccount": "Choose an account",
    "cancel": "Cancel",
    "saved": "Sales Import defaults saved",
    "saving": "Saving…",
    "saveFailed": "Couldn't save these defaults. Check your accounts and try again.",
    "saveDefaults": "Save business defaults",
    "loading": "Loading…",
    "unavailable": "This setup is unavailable for your business or permissions.",
    "reviewTitle": "Review sales import",
    "importTitle": "Import sales",
    "importDescription": "Upload a file, check the totals, and create a draft.",
    "sourceStep": "Source",
    "mapStep": "Map",
    "previewStep": "Preview",
    "dailySummary": "Daily summary",
    "adapter": "Import parser",
    "recommended": "Recommended",
    "dailyHelp": "{rows} source rows grouped into {count} daily journals.",
    "locations": "Match stores to Locations",
    "allRows": "All rows",
    "locationFor": "Location for {store}",
    "unassigned": "Unassigned",
    "rememberLocations": "Remember these Store ID mappings for future imports",
    "accounting": "Accounting treatment",
    "overrideHelp": "These changes apply only to this import.",
    "defaultsHelp": "Using business defaults.",
    "override": "Change for this import",
    "useDefaults": "Use business defaults",
    "gstClaim": "Input GST report",
    "claimDateHelp": "Choose the GST period for this claim. You can change it later in the GST report.",
    "claimDate": "Report date",
    "documentDetails": "Add tax document details",
    "documentDate": "Tax document date",
    "documentReference": "Tax document reference",
    "evidence": "I have supporting tax records and have checked that this GST is claimable.",
    "settlement": "Expected settlement",
    "inputGst": "Input GST",
    "outputGst": "Output GST",
    "outputTax": "Output tax",
    "providerTax": "Provider tax (included in costs)",
    "sourceOrderTax": "Source-stated order tax",
    "missingLocations": "Assign a Location to every store before continuing.",
    "varianceWarning": "Source settlement and calculated settlement differ. Review the source amounts.",
    "missingAccounts": "Choose posting accounts for: {roles}.",
    "accountNeeded": "Pick the account where Groot books {what}.",
    "accountNeededWhat_sales": "your sales",
    "accountNeededWhat_salesSettlementClearing": "the money the platform still owes you",
    "accountNeededWhat_platformFees": "the platform fees",
    "accountNeededWhat_marketingAdvertising": "the platform's advertising and marketing fees",
    "accountNeededWhat_inputTax": "the tax you pay on platform fees",
    "accountNeededWhat_outputTax": "the sales tax you collect",
    "accountNeededWhat_otherIncome": "other income from the platform, such as compensation",
    "accountNeededWhat_otherExpense": "other charges from the platform",
    "accountNoneAvailable": "Your chart of accounts has no account of the right kind for this yet. Add one in Chart of accounts, then choose it here.",
    "accountBlockedReason": "{count, plural, one {Choose the account above to create the draft.} other {Choose the accounts above to create the draft.}}",
    "date": "Date / journal preview",
    "sales": "Net sales",
    "costs": "Platform costs incl. tax",
    "debit": "Debit",
    "credit": "Credit",
    "back": "Back",
    "createDraft": "Create review draft",
    "templates": "Import templates",
    "templatesHelp": "Use the simple template for prepared totals, or the detailed template for platform charges.",
    "simpleTemplate": "Simple sales summary",
    "simpleHelp": "For POS sales or totals you've already prepared. Enter sales, adjustments and output tax; no separate platform-charge breakdown.",
    "detailedTemplate": "Detailed platform sales",
    "detailedHelp": "For delivery or marketplace data with commission, advertising, other charges and their separate tax amounts.",
    "exportFailed": "Couldn't export the file. Please try again.",
    "savedAccounting": "Accounting details",
    "snapshotHelp": "These accounts were used for this import.",
    "importDetails": "Import details",
    "taxSnapshotLabel": "Tax registration",
    "taxSnapshot": "{country}: {status}",
    "notSet": "Not set",
    "registrationUnknown": "unknown",
    "registrationYes": "yes",
    "registrationNo": "no",
    "exportDetailHelp": "Exports include every source field.",
    "exportDetail": "Download {format}",
    "reviewGst": "Review Input GST",
    "viewGst": "View Input GST",
    "gstReviewRequired": "GST review required",
    "gstReviewAfterPosting": "Review Input GST after posting.",
    "gstIncludedAfterPosting": "Input GST will be included after posting.",
    "sourceRequired": "Upload a source file to continue.",
    "nonNativeHelp": "Use a Groot template or map an existing summary file.",
    "downloadXlsx": "Download Excel",
    "downloadCsv": "CSV instead",
    "showOtherTemplate": "Need the {name} template instead?",
    "readingProvenance_rules": "Read by Groot's bookkeeping rules",
    "readingProvenance_model": "Proposed by the AI reader",
    "readingProvenance_human": "Confirmed by you",
    "readingRulesHeading": "Read from the statement",
    "readingJudgedHeading": "Read with AI and confirmed by you",
    "readingWhere": "Where it lands",
    "readingSign": "What the sign means",
    "readingAccount": "Account",
    "readingNotDecided": "Not decided",
    "readingNotPosted": "Not posted",
    "readingAccountUnset": "Account not set",
    "questionsTitle": "{count, plural, one {# question} other {# questions}} on this statement",
    "questionsHelp": "Groot read every line it recognises. These lines need a decision before the draft can be created: ask Groot to read them like an accountant, then confirm or correct each one. Nothing is posted until you confirm the review.",
    "questionsRead": "Ask Groot to read",
    "questionsReadAgain": "Read again",
    "questionsReadingLabel": "Groot's reading",
    "questionsReadFailed_MODEL_UNAVAILABLE": "The reader is unavailable right now. Try again in a moment, or decide each line yourself.",
    "questionsReadFailed_INVALID_READING": "The reader returned something Groot could not accept. Try again, or decide each line yourself.",
    "questionsReadFailed_NO_QUESTIONS": "There is nothing left to read.",
    "questionsReadFailed_UNAUTHORIZED": "You do not have permission to run the reader for this business.",
    "questionKind_unknown_column": "Unrecognised column",
    "questionKind_unknown_line_group": "Unrecognised line type",
    "questionKind_sign_anomaly": "Unexpected sign",
    "questionKind_tax_registration": "Tax registration",
    "questionKind_withholding_tax": "Withholding tax",
    "questionKind_identity_residual": "Does not reconcile",
    "questionEvidence": "{nonZero} non-zero rows, total {total}, {sign}. Sample: {samples}",
    "questionGlossary": "Platform definition",
    "questionDecided": "Decided. Groot will include this in the arithmetic under that meaning.",
    "questionSuggested": "Groot suggests a meaning. Confirm it, or choose another.",
    "questionUndecided": "Choose what this amount means to include it, or exclude it as the platform's own money.",
    "questionSuggestedTag": "suggested",
    "questionGuidance_sign_anomaly": "Groot keeps this line and flags it for your review; the arithmetic still has to tie.",
    "questionGuidance_tax_registration": "Complete the tax registration in Business Profile before this statement can be imported.",
    "questionGuidance_withholding_tax": "Groot does not post withholding tax automatically. Settle its treatment with your accountant before importing.",
    "questionGuidance_identity_residual": "These rows do not add up with the columns Groot reads. A column above may be carrying the difference; decide it first.",
    "questionGuidance_unknown_column": "",
    "questionGuidance_unknown_line_group": "",
    "section_pnl_revenue": "Profit and loss: revenue",
    "section_pnl_contra_revenue": "Profit and loss: reduction of revenue",
    "section_pnl_expense": "Profit and loss: expense",
    "section_pnl_other_income": "Profit and loss: other income",
    "section_pnl_other_expense": "Profit and loss: other expense",
    "section_bs_platform_receivable": "Balance sheet: receivable from the platform",
    "section_bs_tax_payable": "Balance sheet: tax payable",
    "section_bs_tax_recoverable": "Balance sheet: tax recoverable",
    "section_not_posted": "Not posted",
    "sign_money_in": "Money to you",
    "sign_money_out": "A deduction",
    "sign_reversal": "A reversal",
    "sign_balance_movement": "A balance movement",
    "signPattern_all_positive": "all positive",
    "signPattern_all_negative": "all negative",
    "signPattern_mixed": "mixed signs",
    "signPattern_zero": "zero",
    "principal_merchant_principal": "Your sale (you are principal)",
    "principal_purchase_from_platform": "A service you bought from the platform",
    "principal_tax_authority": "Held for the tax authority",
    "principal_platform_principal": "The platform's own money",
    "principal_not_a_sale": "Not a sale",
    "holdReason_UNKNOWN_MEANING": "Groot could not read this line honestly. Decide it yourself.",
    "holdReason_LOW_CONFIDENCE": "Groot is not confident about this reading. Confirm or correct it.",
    "holdReason_SECTION_MISMATCH": "The reading contradicts your accounting policy for this meaning.",
    "holdReason_NOT_POSTABLE": "Groot cannot post this line type yet.",
    "holdReason_WITHHOLDING_TAX_PRESENT": "Withholding tax needs your accountant's decision.",
    "holdReason_TAX_REGISTRATION_UNKNOWN": "Tax registration must be completed first.",
    "holdReason_IDENTITY_RESIDUAL": "The rows do not reconcile.",
    "holdReason_SIGN_ANOMALY": "The sign does not match the line's nature.",
    "meaning_sales_refund": "Sales refund or chargeback",
    "meaning_delivery_income": "Delivery income (your own delivery)",
    "meaning_delivery_cost": "Delivery cost charged by the platform",
    "meaning_withholding_tax": "Withholding tax",
    "meaning_platform_pass_through": "Platform's own money (excluded)",
    "meaning_unknown": "Unknown",
    "agentReviewHeld": "One or more readings are held. Resolve them before confirming.",
    "agentReviewFailedLegacy": "This draft was reviewed by an earlier version of the reader and cannot be confirmed. Discard it and import the file again.",
    "agentReviewMissing": "This draft was made before the bookkeeping review existed, so it can't be confirmed. Discard it and import the file again to get the review.",
    "alreadyImportedOpening": "This file was already imported. Opening the existing batch.",
    "reviewBatchCreated": "Review draft created",
    "headlineTitle": "File totals ({currency})",
    "headlineOrders": "Orders",
    "headline_gross": "Gross sales",
    "headline_discounts": "Discounts and promotions",
    "headline_refunds": "Refunds",
    "headline_serviceCharge": "Service charge",
    "headline_platformFees": "Platform fees",
    "salesWithServiceCharge": "Net sales incl. service charge",
    "expectedAfterAdjustments": "Expected settlement (after adjustments)",
    "previewOverlapNote": "Overlap with sales already recorded is checked when the draft is created. Anything that overlaps is held for you to decide.",
    "previewValidationTitle": "Preview validation",
    "previewReadyIssues": "{ready} ready · {issues} need review",
    "settlementCheckTitle": "{currency} settlement check",
    "settlementSource": "Source {amount}",
    "settlementCalculated": "Calculated {amount}",
    "settlementGross": "Gross {amount}",
    "readyToCreate": "Ready to create a review draft",
    "readyToCreateHelp": "Server validation will retain every invalid row as an exception. Confirmation and posting remain separate actions.",
    "createFailed": "Could not create the review draft. Check the mapped fields and try again."
  },
  "gstRegister": {
    "title": "GST reporting",
    "description": "Review the tax claim linked to these posted journal lines. Saving does not create or change a journal.",
    "loading": "Loading GST details…",
    "unavailable": "No eligible GST activity is available here. Use a posted manual journal with an Input Tax line, or open the claim from its source.",
    "manualWarning": "Manual journal: check the GST amount, purchase value, claim period and supporting records before including it. An uploaded invoice in Groot is not required.",
    "platformWarning": "Platform charges are already booked. This review changes claim eligibility and timing, not the expense or journal amounts.",
    "postImportFirst": "Post the full import before reviewing its Input GST.",
    "stale": "The linked journal changed after GST review. Review its current lines again; the previous claim is excluded until resolved.",
    "treatment": "Claim treatment",
    "needs_review": "Leave for review",
    "claimable": "Fully claimable",
    "partial": "Partially claimable",
    "non_claimable": "Exclude from the claim",
    "claimDate": "GST claim date",
    "claimDateHelp": "This date selects the GST reporting period; it does not move the journal posting.",
    "documentDate": "Tax document date (optional)",
    "supplier": "Supplier (optional)",
    "reference": "Tax document reference (optional)",
    "journal": "Journal date / Location",
    "bookedTax": "Booked GST (SGD)",
    "purchase": "Eligible purchase (SGD)",
    "claim": "Claimable GST (SGD)",
    "purchaseFor": "Eligible purchase for line {index}",
    "claimFor": "Claimable GST for line {index}",
    "taxOnly": "This is a tax-only adjustment with no purchase-value contribution. I have explained why below.",
    "evidence": "I retain supporting tax records and confirm that the claim date and tax eligibility are correct.",
    "note": "Reason for this review",
    "exclusionHelp": "Excluding a claim does not reclassify the booked Input Tax balance. Opening balances and transfers usually need exclusion; any expense reclassification must be recorded separately.",
    "cancel": "Cancel",
    "save": "Save GST review",
    "saving": "Saving…",
    "saved": "GST review saved",
    "refresh": "Refresh report",
    "sales_import": "Sales import",
    "manual_journal": "Manual journal",
    "reversal": "Reversal",
    "viewJournal": "View journal",
    "viewSource": "View source",
    "supportingDocument": "Supporting invoice",
    "evidenceOnly": "Use an unposted supplier document as evidence only; its charges must not be posted again.",
    "evidenceSaved": "Supporting document updated",
    "removeEvidence": "Remove document",
    "chooseEvidence": "Choose an unposted supplier document",
    "attachEvidence": "Attach document",
    "evidenceLocked": "This document is locked while its linked accounting remains effective, preventing the same charges from being posted twice.",
    "evidenceDocumentNotice": "Evidence only. These charges are already recorded by another source and cannot be posted again from this document.",
    "evidenceOnlyBadge": "GST evidence only"
  },
  "gstReport": {
    "title": "Purchase GST register",
    "subtitle": "Review input GST from supplier invoices, sales-import charges and manual journals for your selected claim period.",
    "notEnabled": "Enable Singapore GST in Settings → Business → Business Profile to start reviewing and reporting input GST.",
    "invalidRange": "The claim-period start date must be on or before the end date.",
    "presets": {
      "label": "Calendar period shortcuts",
      "this-month": "This month",
      "last-month": "Last month",
      "this-quarter": "This quarter",
      "last-quarter": "Last quarter"
    },
    "filters": {
      "from": "Claim period from",
      "to": "Claim period to",
      "treatment": "GST treatment",
      "allTreatments": "All treatments",
      "location": "Location",
      "allLocations": "All locations"
    },
    "status": {
      "needs_review": "Needs review",
      "claimable": "Fully claimable",
      "partial": "Partially claimable",
      "non_claimable": "Not claimable"
    },
    "summary": {
      "box5": "Box 5 contribution",
      "box5Caption": "Eligible purchases excluding GST from reviewed, posted sources.",
      "box7": "Box 7 contribution",
      "box7Caption": "Claimable input GST from reviewed, posted sources.",
      "included": "Included items",
      "includedCaption": "Reviewed, posted and claimable in this period.",
      "reviewQueue": "Action required",
      "reviewCaption": "{needs} need GST review · {drafts} reviewed but not posted"
    },
    "scopeNotice": "Includes reviewed input GST from AP invoices, sales-import charges and manual journals. These figures are not a complete GST F5 return and are not submitted to IRAS.",
    "exportCsv": "Export CSV",
    "exportXlsx": "Export Excel",
    "columnPicker": {
      "label": "Columns",
      "description": "Choose what appears in this table.",
      "shownCount": "{shown} of {total}",
      "reset": "Reset to default",
      "exportNote": "Exports always include all fields."
    },
    "reconciliation": {
      "title": "Input GST journal tie-out",
      "caption": "Compares the register with exact Input GST lines in linked posted journals. Unreviewed manual GST remains visible but outside Box 7.",
      "journal": "Linked journal",
      "journalShort": "Journal",
      "difference": "Journal less register",
      "differenceShort": "Difference",
      "exceptions": "Exceptions",
      "viewJournal": "View journal",
      "status": {
        "not_applicable": "Not applicable",
        "matched": "Matched",
        "mismatch": "Difference",
        "missing": "Journal missing"
      }
    },
    "table": {
      "claimDate": "Claim date",
      "invoice": "Invoice",
      "invoiceDate": "Invoice date",
      "supplier": "Supplier",
      "supplierGstNumber": "Supplier GST no.",
      "location": "Location",
      "treatment": "Treatment",
      "sourceAmounts": "Purchase before GST",
      "gross": "Gross",
      "invoiceGst": "Invoice GST",
      "purchaseSgd": "Eligible purchase (SGD)",
      "claimableSgd": "Claimable GST (SGD)",
      "reviewNote": "Review note",
      "reconciliation": "Journal tie-out",
      "journalInputGst": "Journal Input GST (SGD)",
      "difference": "Tie-out difference (SGD)",
      "journalAction": "Linked journal",
      "accounting": "Return status"
    },
    "accounting": {
      "included": "Included",
      "excluded": "Excluded",
      "draft": "Not posted"
    },
    "empty": "No input GST items match this claim period and filter.",
    "drillthrough": {
      "invoiceTitle": "Supplier invoice",
      "loadingInvoice": "Loading the source supplier invoice…",
      "invoiceUnavailable": "This supplier invoice is no longer available to your account.",
      "readOnlyJournal": "Read-only journal evidence for this GST register row.",
      "postedLedger": "Posted ledger entry"
    }
  },
  "gstInvoiceReview": {
    "title": "Input GST review",
    "subtitle": "Confirm what may be claimed before this invoice posts to Accounts Payable.",
    "needsReview": "Needs review",
    "permissionNotice": "An owner or finance admin must confirm the GST treatment before this invoice can be posted.",
    "invoiceTotal": "Invoice total",
    "gstOnInvoice": "GST on invoice",
    "claimDate": "GST claim date",
    "treatment": "Claim treatment",
    "status": {
      "claimable": "Fully claimable",
      "partial": "Partially claimable",
      "non_claimable": "Not claimable"
    },
    "help": {
      "claimable": "Use when the full GST amount is supported by a valid tax invoice and relates to taxable business activity.",
      "partial": "Use when only part is eligible. Enter the exact claimable GST and the separate Box 5 purchase value; one is not derived from the other.",
      "non_claimable": "The full invoice remains an expense; no amount posts to Input GST or contributes to the GST return."
    },
    "partialAmount": "Claimable GST ({currency})",
    "foreignTitle": "Singapore GST amounts in SGD",
    "foreignHint": "Enter the SGD amounts stated on a valid Singapore tax invoice. Do not convert foreign tax yourself.",
    "foreignNonClaimableHint": "Foreign tax is not automatically claimable in Singapore. Choose Fully claimable only if you have a valid Singapore tax invoice that states GST in SGD.",
    "eligiblePurchaseSgd": "Eligible purchase value (SGD)",
    "claimableGstSgd": "Claimable GST (SGD)",
    "note": "Review note (optional)",
    "notePlaceholder": "Reason for a partial or non-claimable treatment",
    "preview": {
      "expense": "Expense debit",
      "inputGst": "Input GST debit",
      "payable": "Accounts Payable credit"
    },
    "saveHint": "Saving the review does not post the invoice.",
    "save": "Confirm GST treatment",
    "saved": "GST treatment confirmed",
    "saveError": "Couldn’t save the GST treatment."
  },
  "gstSettings": {
    "title": "Singapore GST",
    "subtitle": "Review supplier-invoice GST separately from OCR, post claimable tax to the Input GST account, and prepare purchase figures for GST reporting.",
    "loading": "Loading GST settings",
    "enabled": "GST registered",
    "disabled": "Not registered",
    "singaporeOnly": "Set the business country to Singapore in Business Profile before enabling Singapore GST.",
    "registrationNumber": "GST registration number (optional)",
    "registrationPlaceholder": "e.g. M12345678X",
    "registrationHint": "Used as reference information only for now; leaving this blank does not prevent GST review or reporting.",
    "inputTaxAccount": "Input GST posting account",
    "accountReady": "Ready for claimable GST postings.",
    "accountNotReady": "Configure an active Asset account for Input Tax on Accounting → Chart of Accounts.",
    "save": "Save GST settings",
    "saved": "GST settings saved",
    "saveError": "Couldn’t save GST settings. Please try again.",
    "registrationNotSet": "Not set",
    "registrationMovedHint": "Edited with your other tax identifiers in",
    "registrationMovedLink": "Business Profile"
  },
  "sstSettings": {
    "title": "Malaysian SST",
    "subtitle": "Switch this on only if your business is SST registered. Registration depends on your taxable turnover, so Groot never assumes it. Turning it on adds an SST input-tax account to your chart for you to post to.",
    "loading": "Loading SST settings",
    "enabled": "SST registered",
    "disabled": "Not registered",
    "registrationNumber": "SST registration number",
    "registrationNotSet": "Not set",
    "registrationMovedHint": "Edited with your other tax identifiers in",
    "registrationMovedLink": "Business Profile",
    "inputTaxAccount": "SST input tax posting account",
    "accountReady": "Ready for SST postings.",
    "accountNotReady": "Configure an active Asset account for Input Tax on Accounting → Chart of Accounts.",
    "notCreditable": "SST is not generally creditable the way GST or VAT input tax is. Post only genuinely recoverable or deductible SST to this account. Everything else belongs in the cost of the purchase.",
    "noAutomaticSplit": "Groot does not split SST out of your supplier invoices automatically. This account is here for you to post to.",
    "save": "Save SST settings",
    "saved": "SST settings saved",
    "saveError": "Couldn’t save SST settings. Please try again."
  },
  "solo": {
    "statement": {
      "trigger": "Upload bank statement",
      "intakeTrigger": "Upload statement",
      "title": "Add from bank statement",
      "subtitle": "Upload a bank or card statement and we sort each line into simple categories.",
      "close": "Close",
      "choose": "Choose a statement file",
      "chooseAnother": "Choose another file",
      "reading": "Reading your statement…",
      "categorizing": "Sorting into categories…",
      "fileHint": "CSV or Excel (.csv, .xlsx, .xls)",
      "foreign": {
        "title": "Foreign-currency statements are coming soon",
        "body": "Upload a {currency} statement for now (we detected {detected}). Multi-currency support is on the way."
      },
      "summary": {
        "in": "In",
        "out": "Out",
        "rows": "{count} rows",
        "confident": "confident",
        "review": "to review",
        "needsReview": "needs review"
      },
      "buckets": {
        "needsReviewTitle": "Needs review",
        "needsReviewHint": "We weren't sure about these. Pick a category so they can be recorded.",
        "itemCount": "{count} items",
        "date": "Date",
        "description": "Description",
        "amount": "Amount",
        "category": "Category",
        "reassignLabel": "Category for {description}",
        "uncategorised": "Uncategorised",
        "emptyTitle": "Nothing to review",
        "emptyDescription": "This statement had no transactions to sort."
      },
      "confidenceBand": {
        "confident": "Confident",
        "review": "Worth a look",
        "uncertain": "Unsure"
      },
      "commit": {
        "button": "Record to my books",
        "committing": "Recording…",
        "excludedNote": "{count} uncategorised rows won't be recorded until you assign a category.",
        "readyNote": "Everything is categorised and ready to record.",
        "nothing": "Nothing to record yet. Assign a category to at least one row.",
        "noEligibleRows": "None of these lines can be recorded yet. Give each one a category before committing.",
        "noNetMovement": "These lines cancel out, so there's nothing to record.",
        "retryHint": "Nothing was saved. Once you have sorted that out, record this settlement again.",
        "terminalHint": "This file will not be recorded. Choose another file when you are ready.",
        "fileRetryHint": "Nothing was saved. Once you have sorted that out, record this file again."
      },
      "errors": {
        "parse": "We couldn't read that statement. Check it's a CSV or Excel export and try again.",
        "categorize": "We couldn't sort those rows just now. Please try again.",
        "commit": "We couldn't record that statement. Please try again.",
        "empty": "That statement had no transactions we could read.",
        "recognise": "We couldn't check that file just now. Please try again.",
        "ambiguousPlatforms": "This file matches more than one platform format ({platforms}). Groot will not pick one, because the wrong reader puts real money in the wrong place. Upload the file exactly as the platform exported it.",
        "notSettlement": "This file isn't a marketplace statement Groot recognises. Import it as a bank statement instead.",
        "sellerUnknown": "This statement does not name the seller, so Groot cannot tell which shop it belongs to. Nothing was imported. Download the file from the platform again, with its summary page included.",
        "notEntitled": "Groot recognised a marketplace settlement in this file, but importing settlements is not part of your plan yet. Nothing was imported.",
        "notAuthorized": "Only the owner or a finance admin can import a marketplace settlement.",
        "shopConflict": "This statement points at two different shops, and Groot will not merge them on its own. Nothing was imported.",
        "shopFailed": "We couldn't match this statement to your shop just now. Nothing was imported. Please try again.",
        "tooManyRows": "That file is too big to read in one go. Split it and upload it in parts.",
        "currencyRequired": "Set your business currency in settings before importing a statement.",
        "foreignSettlement": "This settlement is in a different currency from your books, and foreign-currency settlements are not supported yet.",
        "tooManyOrders": "This statement carries more orders than Groot records in one pass. Nothing was recorded, so split it by payout date and import each part.",
        "settlementHeld": "Groot's total for this statement does not agree with the payout the platform states, so nothing was recorded. Check this is the whole statement as the platform exported it, then import it again.",
        "adjustmentsHeld": "The adjustment page of this statement does not add up, so Groot will not guess which figure is right. Nothing was recorded. Check the adjustment total, then import it again.",
        "taxUnreadable": "Groot could not read the tax on some orders in this file, so the sales and tax split is unknown for {count} day(s). Nothing was recorded. Fill in the tax those orders were charged in the file's tax column (type 0 where none was charged, and use a dot for the decimal point), then upload the corrected file. If you cannot tell what the tax was, contact support.",
        "taxUnreadableDated": "Groot could not read the tax on some orders in this file, so the sales and tax split is unknown for {count} day(s): {dates}. Nothing was recorded. Fill in the tax those orders were charged in the file's tax column (type 0 where none was charged, and use a dot for the decimal point), then upload the corrected file. If you cannot tell what the tax was, contact support and give them those dates.",
        "taxUnreadableUncounted": "Groot could not read the tax on some orders in this file, so the sales and tax split is unknown. Nothing was recorded. Fill in the tax those orders were charged in the file's tax column (type 0 where none was charged, and use a dot for the decimal point), then upload the corrected file. If you cannot tell what the tax was, contact support.",
        "alreadyImported": "You imported this statement already, so nothing was recorded again.",
        "alreadyClaimed": "Some orders in this statement were recorded by an earlier import, so nothing was recorded again. Recording them twice would count the same income twice.",
        "noMovement": "This statement has no money movement to record.",
        "postingAccount": "Nothing was imported. One of the accounts this settlement records to is not set up yet. Please contact Groot support, then import again.",
        "settlementCommit": "We couldn't record that settlement. Nothing was saved. Please try again.",
        "platformUnsupported": "Groot recognised a {platform} payout report, but Groot cannot record one on Solo. A {platform} report never names the shop it belongs to, so there is nothing to attach these sales to. Nothing was imported, and downloading the file again will not change that. To get this money into your books now, use Add income on this page and enter the payout total.",
        "postingAccountRole": "Nothing was imported. This settlement needs an account for {account}, and yours is not set up yet. Please contact Groot support, then import again.",
        "filePostingAccount": "Nothing was imported. One of the accounts this file records to is not set up yet. Please contact Groot support, then import again.",
        "filePostingAccountRole": "Nothing was imported. This file needs an account for {account}, and yours is not set up yet. Please contact Groot support, then import again."
      },
      "success": {
        "title": "Recorded to your books",
        "body": "Earned {earned} · Spent {spent}",
        "again": "Import another statement",
        "done": "Done",
        "settlementBody": "Saved as entry {entryNumber}. Orders recorded: {orders}",
        "settlementAlready": "Orders an earlier import had already recorded: {count}"
      },
      "info": {
        "trigger": "How it works",
        "title": "Bank statement to categories",
        "description": "Upload a statement and Groot sorts each line into simple category buckets you can correct before recording.",
        "step1Title": "Upload a statement",
        "step1Desc": "Export a CSV or Excel statement from your bank and choose it here.",
        "step2Title": "Review the buckets",
        "step2Desc": "Each line is sorted into a friendly category with a confidence dot. Fix anything that looks off.",
        "step3Title": "Record once",
        "step3Desc": "Commit and your simple P&L updates. Corrections are remembered for next time.",
        "tip1": "Foreign-currency statements are coming soon. Use a home-currency statement for now.",
        "tip2": "Correct a category once and Groot learns it for the next upload.",
        "tip3": "Uncategorised rows stay out of your books until you assign them a category."
      },
      "settlement": {
        "recognised": "Recognised as a {platform} settlement",
        "period": "{from} to {to}",
        "orders": "{count} orders",
        "income": "Sales income",
        "platformFees": "Platform fees",
        "adjustments": "Adjustments",
        "expectedBankCredit": "Expected bank credit",
        "refunds": "Refunds",
        "discounts": "Discounts",
        "adjustmentsHint": "Adjustments are money that moved outside the payout total the platform states, so your bank credit adds up.",
        "alreadyImportedTitle": "Already imported",
        "alreadyImportedBody": "You imported this statement on {date} as entry {entryNumber}. Importing it again would record the same income twice, so nothing was saved.",
        "holdsBody": "{count} adjustment lines need a look against your statement before they can be recorded.",
        "unlinked": "Some adjustments name an order this statement does not contain. They are still recorded, so your bank credit adds up.",
        "panelSubtitle": "Groot read every figure below straight from the report. Check them, then record them to your books.",
        "panelTitle": "Add from your {platform} payout report"
      },
      "refused": {
        "title": "Nothing was imported"
      },
      "marketplaceHint": "Selling on a marketplace? Upload the payout report the platform gives you here too, and Groot will recognise it."
    },
    "projects": {
      "filterLabel": "Project",
      "allProjects": "All projects",
      "assignToProject": "Assign to project",
      "bulkAssign": "Assign selected lines to a project",
      "noProject": "No project",
      "newProject": "+ New project",
      "newProjectPrompt": "Name your new project",
      "createFailed": "Couldn't create the project. Please try again.",
      "selected": "{count} selected",
      "selectAll": "Select all",
      "selectRow": "Select {description}",
      "rowLabel": "Project for {description}",
      "column": "Project",
      "selectColumn": "Select",
      "defaultForUpload": "Default project for this statement",
      "defaultForUploadHint": "Every line starts tagged to this project. Change any line after."
    },
    "cancel": {
      "button": "Cancel statement",
      "dialogTitle": "Cancel this statement posting?",
      "dialogBody": "This will reverse the journal entry without replacement. You can re-upload the same statement later if needed.",
      "reasonLabel": "Reason for cancellation",
      "reasonPlaceholder": "e.g., Uploaded wrong file, duplicate entry",
      "confirmButton": "Cancel statement",
      "cancelButton": "Keep statement",
      "success": "Statement cancelled successfully",
      "errors": {
        "notPosted": "Only posted statements can be cancelled",
        "alreadyReversed": "This statement has already been reversed",
        "periodLocked": "Cannot cancel - the period is locked",
        "reconciled": "Cannot cancel - the entry has been reconciled",
        "settlementLane": "Settlement postings cannot be cancelled. Please contact support.",
        "generic": "Failed to cancel statement. Please try again."
      }
    }
  },
  "lhdnReadiness": {
    "title": "LHDN e-invoice readiness",
    "issuerLabel": "Issuer: {country}",
    "status": {
      "ready": "Ready for LHDN submission",
      "missingBuyerData": "Customer details incomplete",
      "buyerUnresolved": "No customer selected",
      "notApplicable": "LHDN e-invoicing not applicable"
    },
    "reason": {
      "ready": "All required buyer details are on file.",
      "missingBuyerData": "Collect the missing details before submitting to LHDN.",
      "buyerUnresolved": "Select an existing customer to check readiness.",
      "notApplicable": "LHDN MyInvois applies only to Malaysia e-invoice issuers."
    },
    "missingHeading": "Missing customer details",
    "field": {
      "tin": "Tax Identification Number (TIN)",
      "brn": "Business Registration Number (BRN)",
      "addressLine1": "Address",
      "city": "City",
      "stateCode": "State",
      "postalCode": "Postal code",
      "countryCode": "Country"
    },
    "generalPublic": {
      "label": "Or issue to the general public",
      "hint": "For a consumer buyer with no TIN, you can issue using the LHDN general public TIN instead of collecting these details."
    },
    "actions": {
      "requestDetails": "Request details from customer"
    },
    "requestPrompt": "Request e-invoice details from {customer}",
    "requestPromptNoName": "Request e-invoice details from this customer",
    "historicalHint": "Re-ask to get an up-to-date readiness card you can act on."
  },
  "regLabel": {
    "my": "SSM/BRN (Business Registration Number)",
    "sg": "Unique Entity Number (UEN)",
    "tw": "Uniform Business Number (統一編號)",
    "default": "Business Registration Number"
  },
  "common": {
    "loading": "Loading...",
    "error": "Error",
    "retry": "Try again",
    "save": "Save",
    "cancel": "Cancel",
    "delete": "Delete",
    "edit": "Edit",
    "add": "Add",
    "confirm": "Confirm",
    "yes": "Yes",
    "no": "No",
    "close": "Close",
    "back": "Back",
    "next": "Next",
    "previous": "Previous",
    "search": "Search",
    "filter": "Filter",
    "export": "Export",
    "import": "Import",
    "refresh": "Refresh",
    "lineItems": "Line Items",
    "description": "Description",
    "qty": "Qty",
    "unitPrice": "Unit Price",
    "total": "Total",
    "totalAmount": "Total Amount",
    "item": "Item",
    "featureInterest": {
      "wantThis": "I want this!",
      "thanks": "Thanks! We'll notify you"
    }
  },
  "destructiveActionConfirm": {
    "title": "Are you sure?",
    "message": "This action changes or removes saved data and may affect related records. Please confirm before continuing.",
    "confirm": "Yes, continue",
    "cancel": "Cancel"
  },
  "navigation": {
    "solo": "Money in & out",
    "dashboard": "Dashboard",
    "invoices": "Invoices",
    "salesInvoices": "Sales Invoices",
    "transactions": "Accounting",
    "applications": "Applications",
    "expenseClaims": "Expense Claims",
    "managerApprovals": "Manager Approvals",
    "aiAssistant": "AI Assistant",
    "chat": "Chat",
    "more": "More",
    "settings": "Settings",
    "businessSettings": "Business Settings",
    "billing": "Billing",
    "profile": "Profile",
    "logout": "Logout",
    "manager": "Manager",
    "approvals": "Approvals",
    "team": "Team",
    "categories": "Categories",
    "admin": "Admin",
    "leave": "Leave",
    "teamCalendar": "Team Calendar",
    "leaveManagement": "Leave & Timesheet",
    "personalSettings": "Personal Settings",
    "reporting": "Import & Export",
    "documentsInbox": "Documents Inbox",
    "documentsInboxToReview": "{count} to review",
    "inventory": "Inventory",
    "products": "Products",
    "aiInsights": "AI Insights",
    "financialStatements": "Financial Statements",
    "reports": "Reports",
    "featureAccess": "Feature Access",
    "integrations": "Integrations",
    "aiDisclaimer": "AI models may make mistakes, double-check outputs.",
    "businessExpenses": "Other Expenses",
    "accounting": "Accounting",
    "sales": "Sales",
    "quotations": "Quotations",
    "salesOrders": "Sales Orders",
    "purchases": "Purchases",
    "expenses": "Expenses",
    "accountInquiry": "Account Inquiry",
    "journalEntries": "Journal Entries",
    "bankCash": "Bank / Cash",
    "banksReconciliation": "Banks & Reconciliation",
    "chartOfAccounts": "Chart of Accounts",
    "periods": "Periods",
    "customers": "Customers",
    "recurringInvoices": "Recurring Invoices",
    "agingStatements": "Aging & Statements",
    "purchaseInvoices": "Purchase Invoices",
    "payablesAging": "Payables Aging",
    "payroll": "Payroll",
    "creditNotes": "Credit Notes",
    "deliveries": "Deliveries",
    "myCustomers": "My customers"
  },
  "dashboard": {
    "title": "Dashboard",
    "subtitle": "Your financial overview",
    "managerSubtitle": "Your team's approvals and activity",
    "employeeSubtitle": "Your expenses and reminders"
  },
  "documents": {
    "title": "Documents",
    "subtitle": "Manage your financial documents",
    "yourDocuments": "Your Documents",
    "uploadNew": "Upload New Document",
    "processing": "Processing...",
    "processed": "Processed",
    "failed": "Failed",
    "noDocuments": "No documents found",
    "noDocumentsYet": "No documents uploaded yet",
    "uploadFirstDocument": "Upload your first document above to get started",
    "dropFiles": "Drop files here or click to select",
    "supportedFormats": "Supported formats: PDF, PNG, JPG",
    "maxFileSize": "Max file size: 10MB",
    "upload": {
      "clickToUpload": "Click to upload",
      "dropFilesHere": "Drop files here",
      "dropFileHere": "Drop file here",
      "uploadingFiles": "Uploading files",
      "uploadingFile": "Uploading file",
      "processingFiles": "Processing files {current} of {total}",
      "pleaseWait": "Please wait",
      "jpgPngPdfFiles": "JPG, PNG, PDF files",
      "multipleSupported": "Multiple files supported",
      "successfullyUploaded": "Successfully uploaded",
      "someUploadsFailed": "Some uploads failed",
      "allUploadsFailed": "All uploads failed",
      "supportedFileTypes": "Supported file types",
      "images": "Images",
      "documents": "Documents",
      "sizeLimit": "Size limit",
      "maximum10MB": "Maximum 10MB",
      "pdfConvertedOcr": "PDF converted with OCR",
      "validation": {
        "invalidFileType": "Invalid file type. Only JPG, PNG and PDF files are allowed.",
        "fileTooLarge": "File too large. Maximum size is 10MB.",
        "invalidFileExtension": "Invalid file extension. Only .jpg, .png and .pdf files are allowed."
      },
      "clickToUploadOrDrag": "Click to upload or drag and drop",
      "fileTypesHint": "JPG, PNG, HEIC, or PDF files up to 10MB",
      "fileTypesHintMultiple": "JPG, PNG, HEIC, or PDF files up to 10MB (multiple files supported)",
      "rateLimitWaiting": "Upload limit reached. Waiting {seconds, plural, one {# second} other {# seconds}} before trying {fileName} again.",
      "rateLimitFailed": "Upload limit reached. Please try again in about {minutes, plural, one {# minute} other {# minutes}}."
    },
    "status": {
      "uploading": "Uploading",
      "pending": "Pending",
      "processing": "Processing",
      "ocrProcessing": "OCR Processing (5-8 min)",
      "completed": "Completed",
      "failed": "Failed",
      "unknown": "Unknown"
    },
    "fields": {
      "vendor": "Vendor",
      "amount": "Amount",
      "invoice": "Invoice",
      "items": "Items",
      "terms": "Terms",
      "date": "Date"
    },
    "analysis": {
      "title": "Document Analysis",
      "documentPreview": "Document Preview",
      "documentSummary": "Document Summary",
      "vendorInformation": "Vendor Information",
      "customerInformation": "Customer Information",
      "address": "Address",
      "contact": "Contact",
      "customerName": "Customer Name",
      "customerAddress": "Customer Address",
      "customerContact": "Customer Contact",
      "taxIdRegistration": "Tax ID / Registration",
      "english": "English",
      "processingInformation": "Processing Information",
      "documentInformation": "Document Information",
      "documentNumber": "Document Number",
      "dueDate": "Due Date",
      "paymentInformation": "Payment Information",
      "paymentTerms": "Payment Terms",
      "paymentMethod": "Payment Method",
      "bankDetails": "Bank Details",
      "taxFinancialBreakdown": "Tax & Financial Breakdown",
      "subtotal": "Subtotal",
      "taxAmount": "Tax Amount",
      "discount": "Discount",
      "notExtracted": "Not extracted",
      "documentSpecificInformation": "Document-Specific Information",
      "invoiceDetails": "Invoice Details",
      "invoiceNumber": "Invoice Number",
      "customer": "Customer",
      "receiptDetails": "Receipt Details",
      "receiptNumber": "Receipt Number",
      "cashierId": "Cashier ID",
      "transportDetails": "Transport Details",
      "tripId": "Trip ID",
      "pickup": "Pickup",
      "dropoff": "Dropoff",
      "financialEntities": "Financial Entities",
      "lineItems": "Line Items",
      "itemCode": "Item Code",
      "quantity": "Qty",
      "unit": "Unit",
      "unitPrice": "Unit Price",
      "total": "Total",
      "completeExtractedText": "Complete Extracted Text",
      "cleanOcrOutput": "Clean OCR Output",
      "showRawJsonData": "Show Raw JSON Data",
      "hideRawJsonData": "Hide Raw JSON Data",
      "status": "Status",
      "aiConfidence": "AI Confidence"
    },
    "actions": {
      "process": "Process",
      "analyze": "Analyze",
      "updateTransaction": "Update Transaction",
      "viewTransaction": "View Transaction",
      "addTransaction": "Add Transaction",
      "reprocess": "Reprocess",
      "processing": "Processing...",
      "retry": "Retry",
      "delete": "Delete",
      "uploaded": "Uploaded",
      "processed": "Processed",
      "transactionCreated": "Transaction Created",
      "reprocessed": "Reprocessed",
      "extractedInformation": "Extracted Information",
      "reprocessDocument": "Reprocess Document",
      "deleteDocument": "Delete Document",
      "confirmDelete": "Are you sure you want to delete this document?",
      "deleteSuccess": "Document deleted successfully",
      "deleteError": "Failed to delete document",
      "reprocessSuccess": "Document reprocessing started",
      "reprocessError": "Failed to start reprocessing"
    }
  },
  "documentShelf": {
    "tabsAriaLabel": "Documents",
    "replace": "Replace",
    "upload": "Upload",
    "add": "Add document",
    "remove": "Remove document",
    "supportingOrdinal": "Document {number}",
    "addedBy": "Added by {name} on {date}",
    "replaced": "Document replaced",
    "added": "Document added",
    "removed": "Document removed",
    "lockedClaimApproved": "This claim is approved, so its documents are locked.",
    "lockedClaimApprovedCanAdd": "This claim is approved. You can add a supporting document, but the receipt can't be replaced or removed.",
    "lockedClaimResubmitted": "This claim was resubmitted, so its documents now belong to the new claim. Open the new claim to change them.",
    "lockedPosted": "This is posted to the ledger. You can add a supporting document, but the original can't be replaced.",
    "errorReplaceFailed": "We couldn't replace the document. Please try again.",
    "errorAddFailed": "We couldn't add that document. Please try again.",
    "errorRemoveFailed": "We couldn't remove that document. Please try again.",
    "errorLocked": "This record is locked, so its documents can't be changed.",
    "errorResubmitted": "This claim was resubmitted, so its documents can't be changed here. Open the new claim instead.",
    "errorPosted": "This is posted to the ledger, so the original document can't be replaced. Add a supporting document instead.",
    "errorLimit": "This record already has the maximum number of supporting documents.",
    "errorFileType": "That file type isn't supported. Upload a PDF, PNG, JPG, WebP, or HEIC.",
    "errorFileTooLarge": "That file is too large. The maximum is 10 MB.",
    "errorNotAllowed": "You don't have permission to change this record's documents.",
    "errorNotFound": "We couldn't find that record."
  },
  "transactions": {
    "title": "Transactions",
    "subtitle": "View and manage your financial transactions across multiple currencies",
    "amount": "Amount",
    "date": "Date",
    "category": "Category",
    "description": "Description",
    "vendor": "Vendor",
    "status": "Status",
    "approved": "Approved",
    "pending": "Pending",
    "rejected": "Rejected",
    "paid": "Paid",
    "overdue": "Overdue",
    "cancelled": "Cancelled",
    "disputed": "Disputed",
    "awaitingPayment": "Awaiting Payment",
    "noTransactions": "No transactions found",
    "searchPlaceholder": "Search transactions, vendors, line items...",
    "allCategories": "All Categories",
    "allTypes": "All Types",
    "dateRange": "Date Range:",
    "to": "to",
    "refresh": "Refresh",
    "activeFilters": "Active filters:",
    "clearAllFilters": "Clear all filters",
    "clearFilters": "Clear filters",
    "displaying": "Displaying",
    "of": "of",
    "totalTransactions": "total transactions",
    "matchingTransactions": "matching transactions",
    "filteredFrom": "filtered from",
    "total": "total",
    "show": "Show:",
    "perPage": "per page",
    "page": "Page",
    "errorLoadingTransactions": "Error Loading Transactions",
    "retry": "Retry",
    "noTransactionsYet": "No Transactions Yet",
    "noResultsFound": "No Results Found",
    "noTransactionsMessage": "Start by creating your first transaction or uploading financial documents.",
    "noResultsMessage": "Try adjusting your search criteria or clearing filters.",
    "viewDetails": "View Details",
    "editTransaction": "Edit Transaction",
    "deleteTransaction": "Delete Transaction",
    "previousPage": "Previous Page",
    "nextPage": "Next Page",
    "deleteConfirmTitle": "Delete Transaction",
    "deleteConfirmMessage": "Are you sure you want to delete this {type}? This action cannot be undone.",
    "delete": "Delete",
    "cancel": "Cancel",
    "search": "Search",
    "type": "Type",
    "from": "From",
    "removeFilter": "Remove {label} filter",
    "enterAmount": "Enter amount",
    "selectCategory": "Select category",
    "transactionInformation": "Transaction Information",
    "subcategory": "Subcategory",
    "reference": "Reference Number",
    "exchangeRate": "Exchange Rate",
    "rateDate": "Rate Date",
    "systemInformation": "System Information",
    "created": "Created",
    "lastUpdated": "Last Updated",
    "creationMethod": "Creation Method",
    "sourceDocument": "Source Document",
    "viewDocument": "View Document",
    "itemsCount": "Items Count",
    "subtotal": "Subtotal",
    "lineItemsDifferNote": "Note: Line items total differs from transaction amount. This may be due to additional fees, discounts, or rounding differences.",
    "amountAndCurrency": "Amount and Currency",
    "originalAmount": "Original Amount",
    "transactionSummary": "Transaction Summary",
    "createFromDocument": "Create Transaction from Document",
    "createNew": "Create New Transaction",
    "prefilledFromDocument": "Pre-filled from document extraction",
    "manualEntry": "Manual entry",
    "updateTransaction": "Update Transaction",
    "createTransaction": "Create Transaction",
    "transactionType": "Transaction Type",
    "enterDescription": "Enter transaction description",
    "optionalSubcategory": "Optional subcategory",
    "transactionDate": "Transaction Date",
    "homeCurrency": "Home Currency",
    "currencyConversionPreview": "Currency Conversion Preview",
    "exchangeRateLabel": "Exchange Rate",
    "vendorName": "Vendor Name",
    "vendorPlaceholder": "Company or vendor name",
    "documentNumber": "Document Number",
    "documentNumberPlaceholder": "Document number, reference ID, etc.",
    "transactionStatus": "Transaction Status",
    "dueDate": "Due Date",
    "paymentDate": "Payment Date",
    "paymentMethod": "Payment Method",
    "paymentMethodPlaceholder": "Cash, card, transfer, etc.",
    "notes": "Notes",
    "notesPlaceholder": "Additional notes or details...",
    "documentType": "Document Type",
    "fromOCR": "From OCR",
    "itemCode": "Item Code",
    "unit": "Unit",
    "actions": "Actions",
    "itemDescriptionPlaceholder": "Item description",
    "skuPlaceholder": "SKU",
    "unitPlaceholder": "kg, pack, etc.",
    "removeItem": "Remove Item",
    "noLineItemsYet": "No line items added yet",
    "clickAddItemToStart": "Click \"Add Item\" to start adding line items"
  },
  "settings": {
    "title": "Settings",
    "subtitle": "Manage your account preferences",
    "profile": "Profile",
    "language": "Language",
    "currency": {
      "preferences": "Currency Preferences",
      "homeCurrency": "Home Currency",
      "description": "This currency will be used for dashboard summaries and conversions throughout the app.",
      "conversion": "Currency Conversion",
      "conversionDescription": "Transactions in other currencies will be converted to {currency} for dashboard summaries. Original amounts and currencies are always preserved.",
      "saved": "Saved {time}",
      "savingPreferences": "Saving preferences..."
    },
    "notifications": "Notifications",
    "privacy": "Privacy",
    "security": "Security",
    "selectLanguage": "Select Language",
    "homeCurrency": "Home Currency",
    "timezone": "Timezone",
    "languagePreferences": "Language Preferences",
    "interfaceLanguage": "Interface Language",
    "aiAssistantLanguage": "AI Assistant Language",
    "account": "Account",
    "moreSettingsComingSoon": "More Settings Coming Soon",
    "additionalSettingsDescription": "Additional settings and preferences will be available in future updates.",
    "saveChangesComingSoon": "Save Changes (Coming Soon)",
    "admin": {
      "businessAdminAssignment": "Business Admin Assignment",
      "contactSupportToBecome": "Contact support to become a business administrator",
      "pleaseSignInFirst": "Please sign in first",
      "currentUser": "Current User",
      "adminSetupKey": "Admin Setup Key",
      "enterYourAdminKey": "Enter your admin setup key",
      "keyProvidedBy": "This key should be provided by your system administrator",
      "adminPrivilegesAssignedSuccess": "Admin privileges assigned successfully! Please refresh the page to see manager features.",
      "failedToAssignAdmin": "Failed to assign admin privileges",
      "networkErrorTryAgain": "Network error. Please try again.",
      "settingUp": "Setting up...",
      "assignAdminPrivileges": "Assign Admin Privileges",
      "afterSetup": "After Setup:",
      "fullFinancePermissions": "You'll have full finance permissions",
      "accessManagerDashboard": "Access to manager approval dashboard",
      "abilityToAssignRoles": "Ability to assign roles to other users",
      "teamManagementCapabilities": "Team management capabilities"
    },
    "businessProfile": {
      "title": "Business Profile",
      "businessLogoLabel": "Business Logo",
      "businessNameLabel": "Business Name",
      "updateButton": "Update",
      "businessNameDescription": "This name will appear in the sidebar and throughout the application.",
      "logoAlt": "Business Logo",
      "uploading": "Uploading...",
      "changeLogo": "Change Logo",
      "uploadLogo": "Upload Logo",
      "fileFormatDescription": "JPG, PNG or WebP. Max 5MB.",
      "businessNamePlaceholder": "Enter your business name",
      "toast": {
        "nameUpdatedTitle": "Business name updated",
        "nameUpdatedDescription": "Your business name has been updated successfully",
        "nameUpdateFailedTitle": "Failed to update name",
        "nameUpdateErrorTitle": "Error updating name",
        "nameUpdateErrorDescription": "Unable to connect to server",
        "logoUploadedTitle": "Logo uploaded",
        "logoUploadedDescription": "Your business logo has been updated successfully",
        "logoUploadFailedTitle": "Upload failed",
        "logoUploadErrorTitle": "Error uploading logo",
        "logoUploadErrorDescription": "Unable to connect to server",
        "logoRemovedTitle": "Logo removed",
        "logoRemovedDescription": "Your business logo has been removed successfully",
        "logoRemoveFailedTitle": "Remove failed",
        "logoRemoveErrorTitle": "Error removing logo",
        "logoRemoveErrorDescription": "Unable to connect to server",
        "invalidFileTypeTitle": "Invalid file type",
        "invalidFileTypeDescription": "Please upload a JPG, PNG, or WebP image.",
        "fileTooLargeTitle": "File too large",
        "fileTooLargeDescription": "Please upload an image under 5MB."
      }
    }
  },
  "forms": {
    "required": "This field is required",
    "invalid": "Invalid format",
    "tooShort": "Too short",
    "tooLong": "Too long",
    "invalidEmail": "Invalid email address",
    "passwordMismatch": "Passwords do not match",
    "selectOption": "Select an option",
    "enterAmount": "Enter amount",
    "selectDate": "Select date",
    "enterDescription": "Enter description",
    "selectCategory": "Select category",
    "enterVendorName": "Vendor or merchant name",
    "enterBusinessPurpose": "Explain the business reason for this expense",
    "enterReferenceNumber": "Receipt or reference number",
    "enterAdditionalInfo": "Any additional information",
    "briefDescription": "Brief description of expense"
  },
  "disclaimers": {
    "chat": "AI Assistant provides general guidance based on your data. Not professional financial advice. Consult advisors for investment decisions.",
    "ocrDocument": "AI extracted this data from your document. Please verify accuracy before proceeding with financial decisions.",
    "ocrReceipt": "AI extracted this data from your receipt. Please verify all amounts and details before submission.",
    "general": "Groot Finance is a financial management tool. For professional advice, consult qualified advisors."
  },
  "notifications": {
    "success": "Success",
    "warning": "Warning",
    "info": "Information",
    "documentUploaded": "Document uploaded successfully",
    "documentProcessing": "Document is being processed",
    "transactionCreated": "Transaction created successfully",
    "expenseSubmitted": "Expense claim submitted successfully",
    "approved": "Approved successfully",
    "rejected": "Rejected",
    "errorOccurred": "An error occurred",
    "tryAgain": "Please try again"
  },
  "categories": {
    "title": "Expense Categories",
    "subtitle": "Manage expense categories for your organization",
    "addCategory": "Add Category",
    "searchCategories": "Search categories...",
    "loadingCategories": "Loading categories...",
    "noCategoriesFound": "No categories found",
    "noMatchingCategories": "No categories match your search",
    "categoryName": "Category Name",
    "categoryCode": "Category Code",
    "description": "Description",
    "taxTreatment": "Tax Treatment",
    "deductible": "Deductible",
    "nonDeductible": "Non-deductible",
    "partial": "Partial",
    "receiptRequired": "Receipt required",
    "receiptNotRequired": "Receipt not required",
    "managerApprovalRequired": "Manager approval required",
    "managerApprovalNotRequired": "Manager approval not required",
    "policyLimit": "Policy limit",
    "keywords": "Keywords",
    "inactive": "Inactive",
    "default": "Default",
    "edit": "Edit",
    "delete": "Delete",
    "cancel": "Cancel",
    "deleteCategory": "Delete Category",
    "deleteCategoryConfirm": "Are you sure you want to delete the category \"{categoryName}\"? This action cannot be undone and may affect existing expense claims.",
    "categoryCreated": "Category created successfully",
    "categoryUpdated": "Category updated successfully",
    "categoryDeleted": "Category deleted successfully",
    "createCategoryFailed": "Failed to save category",
    "deleteCategoryFailed": "Failed to delete category",
    "networkError": "Network error while saving category",
    "accessDenied": "Category management is available for managers and finance users only.",
    "form": {
      "editCategory": "Edit Category",
      "addNewCategory": "Add New Category",
      "configureSettings": "Configure expense category settings and auto-categorization rules",
      "basicInformation": "Basic Information",
      "categoryNameLabel": "Category Name *",
      "categoryNamePlaceholder": "e.g., Travel & Accommodation",
      "categoryCodeLabel": "Category Code *",
      "categoryCodePlaceholder": "e.g., TRAVEL",
      "descriptionLabel": "Description",
      "descriptionPlaceholder": "Brief description of this category",
      "autoCategorizationRules": "Auto-Categorization Rules",
      "keywordsLabel": "Keywords (comma separated)",
      "keywordsPlaceholder": "travel, hotel, flight, accommodation",
      "keywordsHelp": "Keywords found in receipt descriptions will automatically categorize to this category",
      "vendorPatternsLabel": "Vendor Patterns (comma separated)",
      "vendorPatternsPlaceholder": "*airline*, *hotel*, booking.com",
      "vendorPatternsHelp": "Use * as wildcards. Vendor names matching these patterns will auto-categorize",
      "policySettings": "Policy Settings",
      "taxTreatmentLabel": "Tax Treatment",
      "fullyDeductible": "Fully Deductible",
      "partiallyDeductible": "Partially Deductible",
      "nonDeductible": "Non-deductible",
      "requiresReceiptAttachment": "Requires receipt attachment",
      "requiresManagerApproval": "Requires manager approval",
      "categoryStatus": "Category Status",
      "enabled": "Enabled",
      "disabled": "Disabled",
      "enabledHelp": "Category is available for expense submission",
      "disabledHelp": "Category is hidden from expense forms",
      "receiptThresholdLabel": "Receipt Required Above Amount",
      "receiptThresholdPlaceholder": "0.00",
      "policyLimitLabel": "Policy Limit (SGD)",
      "policyLimitPlaceholder": "0.00 (0 = no limit)",
      "cancel": "Cancel",
      "saving": "Saving...",
      "createCategory": "Create Category",
      "updateCategory": "Update Category",
      "validation": {
        "categoryNameRequired": "Category name is required",
        "categoryCodeRequired": "Category code is required",
        "receiptThresholdInvalid": "Receipt threshold must be 0 or greater",
        "policyLimitInvalid": "Policy limit must be 0 or greater"
      }
    }
  },
  "teams": {
    "title": "Teams Management",
    "subtitle": "Manage team members, roles, and permissions",
    "loading": "Loading teams management...",
    "accessDenied": "Access Denied",
    "accessDeniedDescription": "Teams management requires administrator permissions.",
    "rolePermissions": "Role Permissions",
    "rolePermissionsDescription": "Understanding role permissions and capabilities",
    "inviteTeamMember": "Invite Team Member",
    "activeTeamMembers": "Active Team Members",
    "activeTeamMembersDescription": "Manage role assignments for current team members",
    "pendingInvitations": "Pending Invitations",
    "pendingInvitationsDescription": "Track and manage sent invitations",
    "teamMembers": "Team Members",
    "pendingInvitationsTab": "Pending Invitations",
    "noTeamMembers": "No team members found",
    "noPendingInvitations": "No pending invitations",
    "sendFirstInvitation": "Send your first invitation to grow your team",
    "roles": {
      "employee": "Employee",
      "manager": "Manager",
      "admin": "Admin"
    },
    "permissions": {
      "submitExpenseClaims": "Submit expense claims",
      "uploadReceipts": "Upload receipts",
      "viewOwnTransactions": "View own transactions",
      "allEmployeePermissions": "All employee permissions",
      "approveRejectExpenses": "Approve/reject expenses",
      "manageCategories": "Manage categories",
      "viewTeamExpenses": "View team expenses",
      "allManagerPermissions": "All manager permissions",
      "manageUserRoles": "Manage user roles",
      "sendInvitations": "Send invitations",
      "fullSystemAccess": "Full system access"
    },
    "form": {
      "role": "Role",
      "manager": "Manager",
      "assignManager": "Assign manager",
      "noManager": "No Manager",
      "enterFullName": "Enter full name",
      "joined": "Joined"
    },
    "invitation": {
      "emailAddress": "Email Address",
      "employeeId": "Employee ID",
      "department": "Department",
      "jobTitle": "Job Title",
      "optional": "Optional",
      "sendInvitation": "Send Invitation",
      "resend": "Resend",
      "sent": "Sent",
      "pending": "pending",
      "accepted": "accepted"
    },
    "messages": {
      "userRoleUpdated": "User role updated successfully",
      "managerAssignmentUpdated": "Manager assignment updated successfully",
      "nameUpdated": "Name updated successfully",
      "invitationSent": "Invitation sent to {email}",
      "invitationResent": "Invitation resent successfully",
      "invitationDeleted": "Invitation deleted successfully",
      "enterValidName": "Please enter a valid name",
      "nameMinLength": "Name must be at least 2 characters long",
      "failedToUpdateRole": "Failed to update user role",
      "failedToAssignManager": "Failed to assign manager",
      "failedToUpdateName": "Failed to update name",
      "failedToSendInvitation": "Failed to send invitation",
      "failedToResendInvitation": "Failed to resend invitation",
      "failedToDeleteInvitation": "Failed to delete invitation",
      "networkErrorRole": "Network error while updating role",
      "networkErrorManager": "Network error while assigning manager",
      "networkErrorName": "Network error while updating name",
      "networkErrorInvitation": "Network error while sending invitation",
      "networkErrorResend": "Network error while resending invitation",
      "networkErrorDelete": "Network error while deleting invitation",
      "failedToCheckPermissions": "Failed to check permissions",
      "failedToFetchTeamMembers": "Failed to fetch team members",
      "networkErrorTeamMembers": "Network error while fetching team members",
      "failedToFetchInvitations": "Failed to fetch pending invitations"
    }
  },
  "debtors": {
    "title": "Customers",
    "tabLabel": "Customers",
    "noDebtors": "No outstanding receivables",
    "noDebtorsDescription": "All customers are fully paid.",
    "totalOutstanding": "Total Outstanding",
    "openInvoices": "Open Invoices",
    "oldestOverdue": "Oldest Overdue",
    "days": "days",
    "agingSummary": "Aging Summary",
    "current": "Current",
    "days1to30": "1-30 Days",
    "days31to60": "31-60 Days",
    "days61to90": "61-90 Days",
    "days90plus": "90+ Days",
    "total": "Total",
    "overdueOnly": "Overdue Only",
    "sortBy": "Sort By",
    "outstandingAmount": "Outstanding Amount",
    "daysOverdue": "Days Overdue",
    "customerName": "Customer Name",
    "detail": {
      "title": "Customer Detail",
      "totalInvoiced": "Total Invoiced",
      "totalPaid": "Total Paid",
      "totalOutstanding": "Total Outstanding",
      "overdueInvoices": "Overdue Invoices",
      "invoiceHistory": "Invoice History",
      "paymentHistory": "Payment History",
      "runningBalance": "Running Balance",
      "noInvoices": "No invoices found for this customer.",
      "date": "Date",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "balance": "Balance"
    },
    "statement": {
      "title": "Customer Statement",
      "generateStatement": "Generate Statement",
      "dateRange": "Date Range",
      "from": "From",
      "to": "To",
      "openingBalance": "Opening Balance",
      "closingBalance": "Closing Balance",
      "transactions": "Transactions",
      "noTransactions": "No transactions in this period.",
      "downloadPdf": "Download PDF",
      "emailToCustomer": "Email to Customer",
      "totalDebits": "Total Debits",
      "totalCredits": "Total Credits"
    },
    "agingReport": {
      "title": "AR Aging Report",
      "asOfDate": "As of Date",
      "exportCsv": "Export CSV",
      "grandTotal": "Grand Total",
      "noData": "No outstanding receivables to report."
    },
    "payment": {
      "type": "Type",
      "payment": "Payment",
      "reversal": "Reversal",
      "recordPayment": "Record Payment",
      "recordReversal": "Record Reversal",
      "reversePayment": "Reverse Payment",
      "confirmReversal": "Are you sure you want to reverse this payment? This will restore the invoice balance.",
      "paymentRecorded": "Payment Recorded",
      "reversalRecorded": "Reversal Recorded",
      "allocations": "Allocations",
      "allocateAmount": "Allocate Amount",
      "remainingToAllocate": "Remaining to Allocate"
    }
  },
  "debtorUpdate": {
    "header": {
      "subtitle": "Business Details Update"
    },
    "footer": {
      "poweredBy": "Powered by Groot Finance"
    },
    "loading": "Loading your details...",
    "linkErrors": {
      "expired": {
        "title": "Link Expired",
        "message": "This link has expired. Please contact the business that sent you this link to request a new one."
      },
      "revoked": {
        "title": "Link No Longer Active",
        "message": "This link is no longer active. Please contact the business for an updated link."
      },
      "invalid": {
        "title": "Invalid Link",
        "message": "This link is not valid. Please check the URL or contact the business that sent it to you."
      }
    },
    "success": {
      "title": "Thank You!",
      "message": "Your business details have been updated successfully. The changes are now reflected in {businessName}'s records.",
      "canClose": "You can now safely close this page."
    },
    "rateLimited": {
      "title": "Daily Limit Reached",
      "message": "You've reached the maximum number of updates for today. Please try again tomorrow."
    },
    "sections": {
      "taxRegistration": "Tax & Registration",
      "address": "Address",
      "additionalDetails": "Additional Details",
      "filledCount": "({count} filled)"
    },
    "basicInfo": {
      "heading": "Basic Information"
    },
    "form": {
      "title": "Update Your Business Details",
      "intro": "{businessName} has requested you update your business information for e-invoice compliance.",
      "customerCode": "Customer Code",
      "businessNameLabel": "Business Name *",
      "contactPersonLabel": "Contact Person",
      "emailLabel": "Email *",
      "phoneLabel": "Phone",
      "tinLabel": "TIN (Tax Identification Number)",
      "tinPlaceholder": "e.g. C12345678",
      "brnLabel": "BRN (Business Registration Number)",
      "idTypeLabel": "ID Type",
      "idTypePlaceholder": "Select ID type",
      "sstRegistrationLabel": "SST Registration",
      "addressLine1Label": "Address Line 1",
      "addressLine2Label": "Address Line 2",
      "addressLine3Label": "Address Line 3",
      "cityLabel": "City",
      "postalCodeLabel": "Postal Code",
      "stateLabel": "State",
      "statePlaceholder": "Select state",
      "stateInputPlaceholder": "State / Province",
      "countryLabel": "Region",
      "positionLabel": "Position / Title",
      "phone2Label": "Phone 2",
      "faxLabel": "Fax",
      "websiteLabel": "Website",
      "businessNatureLabel": "Business Nature"
    },
    "idTypes": {
      "brn": "Business Registration Number (BRN)",
      "nric": "National ID (NRIC)",
      "passport": "Passport",
      "army": "Army ID"
    },
    "errors": {
      "businessNameRequired": "Business name is required",
      "emailRequired": "Email is required",
      "emailInvalid": "Invalid email format",
      "tinInvalid": "TIN must start with C or IG followed by digits"
    },
    "submitError": "Something went wrong. Please try again.",
    "submitting": "Updating...",
    "submit": "Update Details",
    "otp": {
      "steps": {
        "verify": "Verify",
        "details": "Details",
        "done": "Done"
      },
      "verifyTitle": "Verify it's you",
      "verifySubtitleOnFile": "For your security, we'll email a 6-digit code to {maskedEmail} to confirm it's really you.",
      "verifySubtitleEnterEmail": "For your security, enter your business email and we'll send a 6-digit code to confirm it's really you.",
      "emailLabel": "Business email",
      "emailPlaceholder": "you@company.com",
      "sendCode": "Send code",
      "sending": "Sending code...",
      "codeTitle": "Enter your code",
      "codeSubtitle": "We sent a 6-digit code to {maskedEmail}. Enter it below to continue.",
      "codeLabel": "6-digit code",
      "codePlaceholder": "123456",
      "verify": "Verify",
      "verifying": "Verifying...",
      "resend": "Resend code",
      "resendCountdown": "Resend code in {seconds}s",
      "changeEmail": "Use a different email",
      "sessionExpired": "Your session has expired. Please verify again to continue.",
      "errors": {
        "invalidCode": "That code isn't right. Please check it and try again.",
        "tooManyAttempts": "Too many attempts. Please request a new code.",
        "expired": "That code has expired. Please request a new one.",
        "rateLimited": "Too many requests. Please wait a moment and try again.",
        "invalidEmail": "Please enter a valid email address.",
        "emailRequired": "Please enter your business email.",
        "generic": "Something went wrong. Please try again."
      }
    },
    "qr": {
      "sectionTitle": "Share via QR code",
      "description": "Print or share this QR code so customers can scan it to securely update their own business details.",
      "downloadPng": "Download PNG",
      "print": "Print",
      "printCardTitle": "Update your business details",
      "printInstructions": "Scan to update your details securely",
      "copyLink": "Copy link",
      "copied": "Copied!",
      "scanToUpdate": "Scan to update your details",
      "poweredBy": "Powered by Groot Finance",
      "downloadFailed": "Couldn't download the QR code. Please try again."
    }
  },
  "vendorUpdate": {
    "header": {
      "subtitle": "Business Details Update"
    },
    "footer": {
      "poweredBy": "Powered by Groot Finance"
    },
    "loading": "Loading your details...",
    "linkErrors": {
      "expired": {
        "title": "Link Expired",
        "message": "This link has expired. Please contact the business that sent you this link to request a new one."
      },
      "revoked": {
        "title": "Link No Longer Active",
        "message": "This link is no longer active. Please contact the business for an updated link."
      },
      "invalid": {
        "title": "Invalid Link",
        "message": "This link is not valid. Please check the URL or contact the business that sent it to you."
      }
    },
    "success": {
      "title": "Thank You!",
      "message": "Your business details have been updated successfully. The changes are now reflected in {businessName}'s records.",
      "bankPending": "Your bank detail changes have been submitted and are pending review by {businessName}. They will take effect once approved.",
      "canClose": "You can now safely close this page."
    },
    "rateLimited": {
      "title": "Daily Limit Reached",
      "message": "You've reached the maximum number of updates for today. Please try again tomorrow."
    },
    "sections": {
      "taxRegistration": "Tax & Registration",
      "address": "Address",
      "additionalDetails": "Additional Details",
      "bankDetails": "Bank Details",
      "filledCount": "({count} filled)"
    },
    "basicInfo": {
      "heading": "Basic Information"
    },
    "bankNotice": "For your security, changes to bank details are reviewed by {businessName} before they take effect.",
    "form": {
      "title": "Update Your Business Details",
      "intro": "{businessName} has requested you update your business information for e-invoice compliance.",
      "vendorCode": "Supplier Code",
      "businessNameLabel": "Business Name *",
      "contactPersonLabel": "Contact Person",
      "emailLabel": "Email *",
      "phoneLabel": "Phone",
      "tinLabel": "TIN (Tax Identification Number)",
      "tinPlaceholder": "e.g. C12345678",
      "sstRegistrationLabel": "SST Registration",
      "addressLine1Label": "Address Line 1",
      "addressLine2Label": "Address Line 2",
      "addressLine3Label": "Address Line 3",
      "cityLabel": "City",
      "postalCodeLabel": "Postal Code",
      "stateLabel": "State",
      "statePlaceholder": "Select state",
      "stateInputPlaceholder": "State / Province",
      "countryLabel": "Region",
      "phone2Label": "Phone 2",
      "faxLabel": "Fax",
      "websiteLabel": "Website",
      "businessNatureLabel": "Business Nature",
      "bankNameLabel": "Bank Name",
      "accountHolderNameLabel": "Account Holder Name",
      "accountNumberLabel": "Account Number",
      "routingCodeLabel": "Routing / SWIFT Code"
    },
    "errors": {
      "businessNameRequired": "Business name is required",
      "emailRequired": "Email is required",
      "emailInvalid": "Invalid email format",
      "tinInvalid": "TIN must start with C or IG followed by digits"
    },
    "submitError": "Something went wrong. Please try again.",
    "submitting": "Updating...",
    "submit": "Update Details",
    "otp": {
      "steps": {
        "verify": "Verify",
        "details": "Details",
        "done": "Done"
      },
      "verifyTitle": "Verify it's you",
      "verifySubtitleOnFile": "For your security, we'll email a 6-digit code to {maskedEmail} to confirm it's really you.",
      "verifySubtitleEnterEmail": "For your security, enter your business email and we'll send a 6-digit code to confirm it's really you.",
      "emailLabel": "Business email",
      "emailPlaceholder": "you@company.com",
      "sendCode": "Send code",
      "sending": "Sending code...",
      "codeTitle": "Enter your code",
      "codeSubtitle": "We sent a 6-digit code to {maskedEmail}. Enter it below to continue.",
      "codeLabel": "6-digit code",
      "codePlaceholder": "123456",
      "verify": "Verify",
      "verifying": "Verifying...",
      "resend": "Resend code",
      "resendCountdown": "Resend code in {seconds}s",
      "changeEmail": "Use a different email",
      "sessionExpired": "Your session has expired. Please verify again to continue.",
      "errors": {
        "invalidCode": "That code isn't right. Please check it and try again.",
        "tooManyAttempts": "Too many attempts. Please request a new code.",
        "expired": "That code has expired. Please request a new one.",
        "rateLimited": "Too many requests. Please wait a moment and try again.",
        "invalidEmail": "Please enter a valid email address.",
        "emailRequired": "Please enter your business email.",
        "generic": "Something went wrong. Please try again."
      }
    },
    "qr": {
      "sectionTitle": "Share via QR code",
      "description": "Print or share this QR code so vendors can scan it to securely update their own business details.",
      "downloadPng": "Download PNG",
      "print": "Print",
      "printInstructions": "Scan to update your details securely",
      "copyLink": "Copy link",
      "copied": "Copied!",
      "scanToUpdate": "Scan to update your details",
      "poweredBy": "Powered by Groot Finance",
      "downloadFailed": "Couldn't download the QR code. Please try again."
    },
    "token": {
      "loading": "Loading token...",
      "linkTitle": "Self-Service Link",
      "active": "Active",
      "expired": "Expired",
      "createdExpires": "Created {created} · Expires {expires}",
      "regenerate": "Regenerate Link",
      "noLink": "No self-service link generated yet.",
      "generate": "Generate Link",
      "regenerateFailed": "Couldn't regenerate the link. Please try again."
    },
    "bankReview": {
      "pendingTitle": "Pending bank-detail changes",
      "requested": "This vendor requested a bank-detail change",
      "submittedAt": "Submitted {date}",
      "empty": "(empty)",
      "approve": "Approve",
      "reject": "Reject",
      "approved": "Bank-detail change approved.",
      "rejected": "Bank-detail change rejected.",
      "actionFailed": "Couldn't complete that action. Please try again.",
      "newNumber": "(new number)",
      "removeButton": "Request removal of account number",
      "removeConfirm": "Ask to remove the saved account number? Your supplier-payment contact will approve this before anything changes.",
      "removeYes": "Yes, request removal",
      "removeKeep": "Keep it",
      "removeQueued": "Removal requested. The saved account number stays until it is approved.",
      "accountSavedEnding": "The saved number ends in {last4}. Leave this blank to keep it, or type the whole new number to change it.",
      "accountSavedNoDigits": "A number is already saved. Leave this blank to keep it, or type the whole new number to change it.",
      "vaultUnavailable": "We could not secure the account number just now. Nothing was submitted. Please try again in a few minutes.",
      "invalidNumber": "That account number cannot be submitted. Check it and try again. It can be up to 64 characters long.",
      "staleForm": "This page is out of date. Refresh it, then submit again.",
      "requestNotSealed": "This request came from an older form and cannot be approved. Reject it and ask the supplier to submit again."
    },
    "delete": {
      "errors": {
        "ownerOnly": "Only an owner can permanently delete a supplier.",
        "hasLinkedRecords": "This supplier has bills or accounting entries against them, so they can't be deleted. Removing them would break your audit trail. Mark them inactive instead.",
        "notFound": "We couldn't find this supplier. They may already be removed. Refresh the page."
      }
    }
  },
  "onboardingPlan": {
    "loading": "Loading plans...",
    "header": {
      "title": "Choose Your Plan",
      "titleExpired": "Upgrade to Continue",
      "subtitle": "Start with a 14-day free trial or select a paid plan",
      "subtitleExpired": "Select a plan to unlock your account and continue using Groot Finance"
    },
    "expired": {
      "heading": "Your Free Trial Has Expired",
      "description": "Your 14-day free trial has ended. To continue using Groot Finance and access your data, please select a paid plan below. Your data is safe and will be available once you upgrade.",
      "switchBusiness": "Switch business",
      "switchBusinessDescription": "Choose another active business to continue without upgrading this one.",
      "loadingBusinesses": "Loading your businesses...",
      "loadBusinessesFailed": "We couldn't load your businesses. Please refresh and try again.",
      "currentBusiness": "Current business is locked",
      "current": "Current",
      "noOtherBusinesses": "No other active businesses are available."
    },
    "divider": {
      "orChoosePaid": "Or choose a paid plan"
    },
    "footer": {
      "allPlansInclude": "All plans include full data access and email support",
      "signOut": "Sign out",
      "signingOut": "Signing out..."
    },
    "toast": {
      "errorTitle": "Error",
      "switchBusinessFailed": "Failed to switch business. Please try again.",
      "startTrialFailed": "Failed to start trial. Please try again.",
      "checkoutFailed": "Failed to start checkout. Please try again."
    },
    "trial": {
      "heading": "Start Your 14-Day Free Trial",
      "subtext": "No credit card required • Full access to Pro features",
      "startButton": "Start Free Trial",
      "startingButton": "Starting Trial...",
      "cancelAnytime": "Cancel anytime during the trial period with no charges",
      "feature": {
        "ocrScans": "100 OCR scans included",
        "teamMembers": "3 team members",
        "allProFeatures": "All Pro features",
        "noCreditCard": "No credit card required"
      }
    },
    "badge": {
      "recommended": "Recommended",
      "mostPopular": "Most Popular",
      "currentPlan": "Current Plan",
      "trialActive": "Trial Active"
    },
    "price": {
      "custom": "Custom pricing",
      "free": "Free",
      "perMonth": "{price}/mo",
      "perMonthSuffix": "/mo",
      "launchSpecial": "Launch Special: save {amount}"
    },
    "billing": {
      "monthly": "Monthly",
      "annual": "Annual",
      "twoMonthsFree": "2 months free",
      "perYearSuffix": "/yr",
      "billedAnnually": "Billed {price}/year"
    },
    "planDescription": {
      "starter": "Perfect for small businesses",
      "pro": "Best for growing companies",
      "enterprise": "For large organizations"
    },
    "limits": {
      "teamMembers": "{count, plural, one {# team member} other {# team members}}",
      "teamUnlimited": "Unlimited team members",
      "ocrScans": "{count, plural, one {# OCR scan} other {# OCR scans}}/month",
      "ocrUnlimited": "Unlimited OCR scans/month"
    },
    "features": {
      "heading": "Features",
      "showLess": "Show less",
      "seeAll": "See all features",
      "items": {
        "customCategories": "Custom business categories",
        "aiCategorization": "AI auto categorization",
        "approvalWorkflow": "Approval workflow",
        "multiCurrencyAddon": "Multi-currency (paid add-on)",
        "stockManagementAddon": "Stock management (paid add-on)",
        "rbac": "Role-based access control",
        "aiChat": "AI chat assistant",
        "basicInvoicing": "Basic invoicing",
        "batchSubmission": "Batch receipt submission",
        "leaveManagement": "Leave management",
        "sstRegistrationDetails": "SST registration details on documents",
        "einvoice": "LHDN e-Invoice: submit & receive",
        "multilangChat": "Multi-language chat",
        "ragCompliance": "RAG regulatory compliance",
        "duplicateDetection": "Duplicate expense detection",
        "fullAr": "Full AR management",
        "fullAp": "Full AP management",
        "actionCards": "Chat action cards",
        "exportTemplates": "Export templates",
        "scheduledExports": "Scheduled exports",
        "auditTrail": "Audit trail",
        "advancedAnalytics": "Advanced analytics",
        "aiReceiptScanning": "AI receipt scanning",
        "simpleProfitLoss": "Simple profit & loss",
        "financialStatements": "Financial statements",
        "everythingStarter": "Everything in Starter, plus:",
        "everythingPro": "Everything in Pro, plus:",
        "fullArAp": "Full AR & AP management",
        "aiProactiveInsights": "AI proactive insights",
        "unlimitedEverything": "Unlimited everything",
        "cashFlowForecasting": "Cash flow forecasting",
        "financialIntelligence": "Financial intelligence",
        "mcpApiAccess": "MCP Server / API access",
        "customIntegrations": "Custom integrations",
        "dedicatedManager": "Dedicated account manager",
        "slaGuarantee": "SLA guarantee",
        "ocrScansUnlimited": "Unlimited OCR scans",
        "aiMessagesUnlimited": "Unlimited AI chat messages",
        "salesInvoicesUnlimited": "Unlimited sales invoices",
        "einvoicesUnlimited": "Unlimited e-invoices",
        "proactiveInsightsUnlimited": "Unlimited proactive insights",
        "teamMembersUnlimited": "Unlimited team members",
        "ocrScans": "{count} OCR scans/month",
        "aiMessages": "{count} AI chat messages/month",
        "salesInvoices": "{count} sales invoices/month",
        "einvoices": "{count} e-invoices/month",
        "proactiveInsights": "{count} proactive insights/month",
        "teamMembers": "Up to {count} team members"
      }
    },
    "button": {
      "currentPlan": "Current Plan",
      "processing": "Processing...",
      "activatePlan": "Activate Plan",
      "contactUs": "Contact Us",
      "downgradeViaPortal": "Downgrade via Portal",
      "selectPlan": "Select {plan}"
    },
    "enterprise": {
      "emailSubject": "Enterprise Plan Inquiry",
      "emailBody": "Hi Groot Finance team,\n\nI would like to inquire about the Enterprise plan pricing for my organization.\n\nCompany name:\nNumber of users:\nSpecific requirements:\n\nLooking forward to hearing from you.\n\nBest regards"
    },
    "solo": {
      "heading": "I'm a gig worker or solo owner",
      "subtext": "Grab driver, freelancer or one-person business? Get a simple profit & loss and tax estimate for less."
    },
    "soloUpgrade": {
      "heading": "Grow into a full business",
      "description": "Upgrade to unlock invoicing, a balance sheet, fixed assets and your full team. Your data stays exactly where it is. There is nothing to migrate.",
      "cta": "Upgrade to Business"
    }
  },
  "onboardingBusiness": {
    "loading": {
      "checkingAccount": "Checking account...",
      "loading": "Loading..."
    },
    "header": {
      "title": "Create New Business",
      "stepIndicator": "Step {current} of {total}",
      "signOut": "Sign out",
      "closeAriaLabel": "Close"
    },
    "steps": {
      "details": {
        "label": "Details",
        "description": "Business info"
      },
      "type": {
        "label": "Type",
        "description": "Industry"
      },
      "cogs": {
        "label": "COGS",
        "description": "Cost categories"
      },
      "expenses": {
        "label": "Expenses",
        "description": "Expense categories"
      },
      "review": {
        "label": "Review",
        "description": "Confirm setup"
      },
      "chart": {
        "label": "Chart",
        "description": "Accounts source"
      }
    },
    "brewing": {
      "workspace": "Brewing your workspace magic...",
      "commandCenter": "Setting up your financial command center...",
      "aiFeatures": "Configuring AI-powered features...",
      "dashboard": "Almost there! Preparing your dashboard..."
    },
    "provisioning": {
      "title": "Setting up your chart of accounts",
      "description": "This takes a few seconds. Please keep this window open.",
      "failedTitle": "We couldn't finish setting up your chart of accounts",
      "failedDescription": "Your business was created, but its chart of accounts didn't finish importing. Try again, or import it later from the Chart of Accounts page.",
      "retry": "Try again"
    },
    "magic": {
      "title": {
        "creating": "Creating your business",
        "finishing": "Taking you to your workspace"
      },
      "subtitle": {
        "creating": "Getting your workspace ready. Please keep this window open.",
        "finishing": "Almost there."
      },
      "lines": {
        "paperwork": "Filing the paperwork so you never have to...",
        "drawers": "Sorting your accounts into tidy little drawers...",
        "beans": "Teaching your ledger to count beans so you don't have to...",
        "debits": "Making sure every debit meets its credit..."
      },
      "steps": {
        "business": "Create your business",
        "chart": "Build your chart of accounts",
        "workspace": "Open your workspace"
      },
      "hints": {
        "longer": "Bigger charts take a little longer. Hang tight.",
        "stillGoing": "Still on it. Keep this window open and we'll take you in the moment it's ready."
      },
      "tap": {
        "label": "Sprinkle some sparkles",
        "hint": "Tap the wand for a little sparkle",
        "quips": {
          "one": "Sparkle delivered.",
          "two": "Ooh, shiny. The chart is still cooking.",
          "three": "Don't tell the accountants this helps.",
          "four": "Okay, you've got the touch."
        }
      }
    },
    "details": {
      "title": "Business Details",
      "subtitle": "Tell us about your business",
      "businessNameLabel": "Business Name",
      "businessNamePlaceholder": "e.g. Acme Trading Pte Ltd",
      "countryLabel": "Region",
      "countryPlaceholder": "Select region",
      "currencyLabel": "Home Currency",
      "currencyPlaceholder": "Select currency",
      "consentText": "I agree to the <link>Privacy Policy</link> and consent to processing of my personal data as described",
      "consentError": "You must accept the Privacy Policy to continue",
      "continue": "Continue",
      "consentSaveFailed": "We could not save your consent. Check your connection and try again."
    },
    "review": {
      "title": "Review Your Setup",
      "subtitle": "Confirm your business details",
      "businessDetailsHeading": "Business Details",
      "nameLabel": "Name:",
      "typeLabel": "Type:",
      "countryLabel": "Region:",
      "currencyLabel": "Currency:",
      "registrationLabel": "Registration No:",
      "cogsHeading": "COGS Categories ({count})",
      "expensesHeading": "Expense Categories ({count})",
      "aiDefaults": "AI will generate defaults",
      "back": "Back",
      "settingUp": "Setting up...",
      "createBusiness": "Create Business",
      "planLabel": "Plan:",
      "accountsLabel": "Accounts:",
      "planSolo": "Groot Solo",
      "planProTrial": "Pro · 14-day trial",
      "provisioning": {
        "title": "Finishing your chart",
        "description": "Your business is created. We are adding the accounts your work needs before taking you to your workspace.",
        "failedTitle": "Your chart needs one more step",
        "failedDescription": "The business was created, but the starter accounts did not finish. Retry setup to continue safely.",
        "retry": "Retry setup",
        "viewChart": "View chart setup",
        "retryQueued": "Setup restarted",
        "retryFailed": "We couldn't restart setup. Please try again."
      }
    },
    "errors": {
      "createFailed": "Failed to create business",
      "coaImportFailed": "We created your business, but couldn't import your chart of accounts. You can import it later from the Chart of Accounts page.",
      "trialStartUnconfirmed": "Your business is ready, but we couldn't confirm the trial started. Check Billing before using paid features.",
      "chartSourceIncomplete": "Please choose where your chart of accounts comes from before finishing.",
      "duplicateRegNumber": "That business registration number is already used by another account. Check the number, or sign in to the account that already has it."
    }
  },
  "onboardingCoaImport": {
    "titleCogs": "Import your COGS accounts",
    "titleExpense": "Import your expense accounts",
    "description": "Paste the COGS (or expense) accounts you want to track, not your full chart. Add the code and name, or upload a CSV/XLSX export from SQL Accounting, AutoCount, Xero, or a spreadsheet. Other account types (assets, liabilities, revenue) can be added later from the Chart of Accounts page.",
    "pasteLabel": "Paste accounts",
    "pastePlaceholder": "Code,Name\n5100,Food Ingredients\n5110,Beverages",
    "pasteHint": "Tab or comma separated. One account per line. A header row (Code, Name) is auto-detected.",
    "uploadLabel": "Upload CSV or XLSX",
    "formatsNote": "Works with SQL Accounting, AutoCount, Xero and spreadsheet exports.",
    "noRows": "No accounts found in that input.",
    "parseFailed": "Couldn't read that file. Check the format and try again.",
    "duplicatesWarning": "Duplicate codes were skipped: {codes}",
    "previewHeading": "Preview ({count, plural, one {# account} other {# accounts}})",
    "colCode": "Code",
    "colName": "Name",
    "addCta": "{count, plural, one {Add # account} other {Add # accounts}}",
    "adding": "Adding...",
    "allAlreadyAdded": "All already added",
    "atCapacity": "Category limit reached",
    "alreadyAddedNote": "{added} of {total} are new; the rest are already in your list.",
    "cancel": "Cancel",
    "importButtonCogs": "Import my COGS accounts",
    "importButtonExpense": "Import my expense accounts"
  },
  "invitations": {
    "loading": {
      "title": "Loading Invitation",
      "description": "Please wait while we load your invitation..."
    },
    "validating": {
      "title": "Validating Invitation",
      "description": "Please wait while we verify your invitation..."
    },
    "errorCard": {
      "title": "Invitation Error",
      "returnHome": "Return to Home",
      "expired": {
        "title": "This invitation has expired",
        "description": "Invitations are valid for a limited time. Please ask your administrator to send you a new one."
      },
      "notFound": {
        "title": "Invitation not found",
        "description": "We couldn’t find this invitation. It may have been removed. Please ask your administrator to send you a new one."
      },
      "alreadyAccepted": {
        "title": "This invitation was already accepted",
        "description": "This invitation has already been used. If that was you, simply sign in to your account. Otherwise, please ask your administrator to send you a new invitation."
      },
      "invalid": {
        "title": "This invitation link is not valid",
        "description": "The link may be incomplete or out of date. Please open the most recent invitation email and use the full link, or ask your administrator to send you a new one."
      },
      "unavailable": {
        "title": "We couldn't check this invitation",
        "description": "Something went wrong on our side. Please try again in a moment. Your invitation link may still be valid."
      }
    },
    "success": {
      "welcome": "Welcome to {businessName}!",
      "description": "Your invitation has been accepted successfully. You now have {role} access to the organization.",
      "redirecting": "Redirecting to dashboard..."
    },
    "nameForm": {
      "title": "Complete Your Profile",
      "welcome": "Welcome to <strong>{businessName}</strong>!",
      "description": "Please enter your full name to complete your profile setup.",
      "completing": "Completing Setup...",
      "submit": "Complete Profile & Join Team"
    },
    "form": {
      "fullNameLabel": "Full Name",
      "fullNamePlaceholder": "Enter your full name"
    },
    "join": {
      "title": "Join {businessName}",
      "invitedMessage": "You've been invited to join <strong>{businessName}</strong> as a <strong>{role}</strong>.",
      "email": "Email: {email}",
      "signUpToAccept": "Sign Up to Accept Invitation",
      "alreadyHaveAccount": "Already have an account? <signInLink>Sign in</signInLink> with the invited email address.",
      "accepting": "Accepting Invitation...",
      "accept": "Accept Invitation",
      "signingYouIn": "Signing you in..."
    },
    "consent": {
      "agreement": "I agree to the <privacyLink>Privacy Policy</privacyLink> and consent to processing of my personal data as described",
      "error": "You must accept the Privacy Policy to continue"
    },
    "actions": {
      "signOutUseDifferent": "Sign Out & Use Different Account"
    },
    "errors": {
      "recordConsentFailed": "Failed to record consent. Please try again.",
      "authRequired": "Authentication required. Please sign in to continue.",
      "invalidServerResponse": "Invalid response from server. Please try again later.",
      "invalidJsonResponse": "Server returned an invalid response. This might happen if you need to sign in first.",
      "acceptFailed": "Failed to accept invitation",
      "validateFailed": "Failed to validate invitation",
      "missingToken": "Invalid invitation link - missing token",
      "emailMismatch": "This invitation is for {invitedEmail}, but you are signed in as {signedInEmail}.\n\nPlease sign out and create an account with the invited email.",
      "nameRequired": "Please enter your full name",
      "nameTooShort": "Name must be at least 2 characters long"
    },
    "setPassword": {
      "title": "Choose a password",
      "description": "Your account for {businessName} is ready. Set a password so you can sign back in later.",
      "newLabel": "Password",
      "confirmLabel": "Confirm password",
      "submit": "Save and continue",
      "saving": "Saving...",
      "mismatch": "Those two passwords do not match.",
      "failed": "That password could not be saved. Please try a different one."
    }
  },
  "accessDenied": {
    "title": "Access Denied",
    "noAccessMessage": "You don't have access to Groot Finance.",
    "authenticatedNotRegistered": "Your account is authenticated, but you're not registered for the Groot Finance application.",
    "possibleReasons": {
      "heading": "Possible reasons:",
      "differentApp": "You signed up for a different application (e.g., Staff Portal)",
      "deactivated": "Your Groot Finance account has been deactivated",
      "incompleteSignUp": "You haven't completed the sign-up process"
    },
    "actions": {
      "createAccount": "Create Groot Finance Account",
      "contactSupport": "Contact Support",
      "backToSignIn": "Back to Sign In"
    },
    "errorFooter": "If you believe this is an error, please contact our support team."
  },
  "dashboardMain": {
    "componentLoader": {
      "loading": "Loading {title}..."
    },
    "widgets": {
      "aiPerformance": "AI Performance",
      "agedReceivables": "Aged Receivables",
      "agedPayables": "Aged Payables",
      "currencyAnalysis": "Currency Analysis",
      "categoryAnalysis": "Category Analysis"
    },
    "period": {
      "last60Days": "Last 60 Days",
      "currentQuarter": "Current Quarter",
      "currentYear": "Current Year"
    },
    "trend": {
      "noChange": "No change",
      "up": "{value}% up",
      "down": "{value}% down",
      "noTrend": "No trend",
      "vsPrevPeriod": "vs. prev period"
    },
    "error": {
      "title": "Error Loading Financial Data",
      "retry": "Retry"
    },
    "header": {
      "title": "Financial Dashboard",
      "convertedTo": "{period} • Converted to {currency}",
      "notConverted": "{period} • Shown in {currency}, NOT converted to {requested}",
      "currencyUnknown": "{period} • Reporting currency could not be confirmed",
      "updated": "• Updated {time}"
    },
    "controls": {
      "displayCurrency": "Display currency",
      "refreshData": "Refresh data"
    },
    "kpi": {
      "totalIncome": "Total Income",
      "totalExpenses": "Total Expenses",
      "netProfit": "Net Profit",
      "transactions": "Transactions",
      "profitMargin": "Profit Margin",
      "totalCount": "Total count"
    },
    "currencyNotice": {
      "homeCurrencyUnavailable": "We could not read this business's reporting currency, so these figures are shown exactly as recorded and have NOT been converted to {requested}. Set the reporting currency in Settings, then refresh.",
      "rateUnavailable": "No exchange rate was available, so these figures are shown in {currency} and have NOT been converted to {requested}."
    }
  },
  "expenseClaimsUI": {
    "stockIntake": {
      "cardTitle": "Stock & supplier",
      "statusPlanned": "{count} stock lines planned",
      "statusReceived": "Received ({count} movements)",
      "statusFailed": "Stock not received",
      "notEnabled": "This claim does not track stock.",
      "supplier": "Supplier: {name}",
      "supplierNone": "No supplier confirmed",
      "lineUnmatched": "not matched to a catalog item",
      "failedReason": "The stock could not be received: {reason}",
      "retry": "Retry",
      "retrySucceeded": "Stock received.",
      "retryFailed": "Stock could not be received. See the reason on the claim.",
      "postedAs": "Posted as"
    },
    "page": {
      "title": "Expense Claims"
    },
    "loadError": "Failed to load dashboard data",
    "summary": {
      "totalClaims": "Total Claims",
      "pendingApproval": "Pending Approval",
      "approvedAmount": "Approved Amount",
      "rejected": "Rejected"
    },
    "tabs": {
      "overview": "Overview",
      "history": "History",
      "myReports": "My Reports"
    },
    "deleteDialog": {
      "title": "Delete Expense Claim",
      "message": "Are you sure you want to delete this draft expense claim? This action cannot be undone.",
      "confirm": "Delete",
      "cancel": "Cancel"
    },
    "submitDialog": {
      "title": "Submit Expense Claim",
      "message": "Submit this expense claim for approval? You won't be able to edit it after submission.",
      "confirm": "Submit",
      "cancel": "Cancel",
      "messageNoApproval": "File this expense claim? It posts straight away as an expense you are owed, and you will not be able to edit it after that."
    },
    "toast": {
      "deleteSuccess": "Expense claim deleted successfully",
      "deleteError": "An error occurred while deleting the claim",
      "submitSuccess": "Expense claim submitted for approval",
      "submitError": "Failed to submit expense claim",
      "submitReceiptRequired": "Attach a receipt before submitting this claim",
      "reprocessStarting": "Starting AI reprocessing...",
      "reprocessStarted": "AI reprocessing started successfully! Results will appear automatically.",
      "reprocessStartFailed": "Failed to start reprocessing",
      "reprocessError": "Failed to reprocess expense claim",
      "fileIncompleteFinancials": "Add an amount, a currency and a date before filing this claim.",
      "fileOverCategoryCap": "This claim is over its category cap. Raise the cap in Expense approval settings, or lower the amount.",
      "submitSuccessNoApproval": "Expense claim filed and posted"
    },
    "card": {
      "defaultName": "Expense Claim",
      "einvoiceRejectedBadge": "E-Invoice Rejected",
      "einvoiceRejectedTooltip": "The linked e-invoice was rejected. Finance review required before reimbursement.",
      "withApprover": "With: {approver}",
      "processingFailed": "Processing failed",
      "suggestions": "Suggestions:"
    },
    "statusDescription": {
      "draft": "Ready for editing - click Edit to modify or Submit to proceed",
      "reimbursed": "Payment completed",
      "approved": "Approved, awaiting reimbursement",
      "submitted": "Pending manager approval",
      "rejected": "Rejected by manager"
    },
    "actions": {
      "edit": "Edit",
      "submit": "Submit",
      "delete": "Delete",
      "reExtract": "Re-extract",
      "reprocess": "Reprocess",
      "aiAnalyzing": "AI Analyzing...",
      "viewDetails": "View Details"
    },
    "statusFilter": {
      "all": "All Statuses",
      "draft": "Draft",
      "submitted": "Submitted",
      "approved": "Approved",
      "rejected": "Rejected",
      "reimbursed": "Reimbursed",
      "failed": "Failed"
    },
    "history": {
      "title": "Expense History",
      "description": "All your expense claims over time",
      "searchPlaceholder": "Search by vendor, description, amount, or category...",
      "dateFrom": "From",
      "dateTo": "To",
      "clearFilters": "Clear Filters",
      "resultCount": "Showing {shown} of {total, plural, one {# claim} other {# claims}}",
      "emptyTitle": "No expense history yet",
      "emptyDescription": "Your submitted claims will appear here",
      "noMatchTitle": "No matching claims found",
      "noMatchDescription": "Try adjusting your search or filters"
    },
    "reports": {
      "title": "My Reports",
      "description": "Generate personal expense reports",
      "teamTitle": "Team Expense Report",
      "teamDescription": "Generate expense reports across your whole team"
    },
    "pendingApprovalsBanner": {
      "message": "{count, plural, =1 {1 claim is waiting for your review} other {{displayCount} claims are waiting for your review}}",
      "cta": "Review approvals"
    }
  },
  "managerApprovals": {
    "page": {
      "title": "Expense Approvals"
    },
    "metadata": {
      "title": "Approvals Dashboard | Groot Finance",
      "description": "Comprehensive expense management and approval workflows for managers and administrators"
    },
    "dashboardUnavailable": {
      "title": "Approvals could not load",
      "description": "We could not load your approvals queue, so we cannot tell you what is waiting for review. This does not mean there is nothing to approve.",
      "retry": "Try again"
    },
    "tabs": {
      "overview": "Overview",
      "expenses": "Expenses",
      "reimburse": "Reimburse",
      "leave": "Leave",
      "timesheets": "Timesheets",
      "pendingBadge": "{count} pending"
    },
    "riskTags": {
      "duplicate": "Duplicate",
      "policy": "Policy",
      "needsReview": "Needs review",
      "amountEdited": "Amount edited"
    },
    "claimsCount": "{count, plural, one {# claim} other {# claims}}",
    "bySubmitter": "by {name}",
    "pendingSubmissions": {
      "title": "Pending Submissions ({count})",
      "description": "Batch expense submissions awaiting your approval",
      "allCaughtUpTitle": "All Caught Up!",
      "allCaughtUpDescription": "No expense submissions pending your approval."
    },
    "overview": {
      "companyAnalytics": "Company Analytics",
      "teamAnalytics": "Team Analytics",
      "analyticsDescription": "Real-time expense insights"
    },
    "priorityApprovals": {
      "title": "Priority Approvals",
      "description": "Claims requiring immediate attention",
      "noPending": "No pending approvals",
      "allReviewed": "All submissions reviewed",
      "reviewAll": "Review all {count}"
    },
    "history": {
      "title": "Submission History ({count})",
      "description": "Previously reviewed submissions",
      "noMatches": "No submissions match the selected filters.",
      "filters": {
        "allStatuses": "All statuses",
        "allEmployees": "All employees"
      }
    },
    "status": {
      "approved": "Approved",
      "rejected": "Rejected",
      "reimbursed": "Reimbursed",
      "draft": "Draft"
    },
    "reimbursement": {
      "title": "Reimbursement Processing",
      "description": "Approved claims ready for payment processing",
      "emptyTitle": "No pending reimbursements",
      "emptyDescription": "All approved claims have been processed",
      "selectAll": "Select All ({count, plural, one {# claim} other {# claims}})",
      "selectedCount": "{selected} of {total} selected",
      "processSelected": "Process Selected ({count})",
      "exportList": "Export List",
      "process": "Process",
      "approvedOn": "Approved {date}",
      "noDepartment": "No Department",
      "expenseClaimFallback": "Expense Claim",
      "employeeIdFallback": "Employee ID: {id}",
      "selectAtLeastOne": "Please select at least one claim to process",
      "processFailed": "Failed to process reimbursement: {error}",
      "networkError": "Network error while processing reimbursement",
      "bulkSuccess": "Successfully processed {count} claim(s)",
      "bulkPartial": "Processed {successCount} claim(s). Failed: {failCount}",
      "noClaimsToExport": "No claims to export",
      "csv": {
        "employeeName": "Employee Name",
        "department": "Department",
        "description": "Description",
        "amount": "Amount",
        "currency": "Currency",
        "approvedDate": "Approved Date",
        "claimId": "Claim ID"
      }
    },
    "convertedTotal": "Total in {currency}",
    "unconvertedClaims": "{count} not converted"
  },
  "managerDashboard": {
    "kpis": {
      "pendingApprovals": "Pending approvals",
      "teamSubmissions": "Team submissions",
      "pendingLeave": "Pending leave"
    },
    "priorityApprovals": {
      "title": "Priority Approvals",
      "description": "Claims requiring your attention",
      "noPending": "No pending approvals",
      "allReviewed": "All submissions reviewed",
      "reviewAll": "Review all {count}"
    },
    "teamAnalytics": {
      "title": "Team Analytics",
      "description": "Real-time expense insights for your team"
    },
    "riskTags": {
      "duplicate": "Duplicate",
      "policy": "Policy",
      "needsReview": "Needs review",
      "amountEdited": "Amount edited"
    },
    "claimsCount": "{count, plural, one {# claim} other {# claims}}",
    "bySubmitter": "by {name}"
  },
  "submissionDetail": {
    "employeePageTitle": "Expense Submission",
    "managerPageTitle": "Review Submission",
    "backToApprovals": "Back to Approvals",
    "backToExpenseClaims": "Back to Expense Claims",
    "claimsCount": "{count, plural, one {# claim} other {# claims}}",
    "bySubmitter": "by {name}",
    "errors": {
      "submissionNotFound": "Submission not found",
      "homeAmountUnavailable": "One claim is in a different currency and has no converted amount. Open that claim, enter the amount in your business currency, then approve the report.",
      "homeAmountUnavailableNamed": "Cannot approve this report yet. The claim {claim} is in {claimCurrency} and your books are in {homeCurrency}. Add the {homeCurrency} amount to that claim, or enter a {claimCurrency} to {homeCurrency} rate for {date} on Accounting → Chart of Accounts, then approve again.",
      "submitHomeAmountUnavailable": "Cannot submit yet. One claim is in a different currency and has no converted amount. Open that claim, enter the amount in your business currency, then submit again.",
      "submitHomeAmountUnavailableNamed": "Cannot submit this report yet. The claim {claim} is in {claimCurrency} and your books are in {homeCurrency}. Add the {homeCurrency} amount to that claim, or enter a {claimCurrency} to {homeCurrency} rate for {date} on Accounting → Chart of Accounts, then submit again.",
      "fxRateMissing": "Cannot approve this claim: it is in {claimCurrency} but your books are in {homeCurrency}, and there is no {claimCurrency} to {homeCurrency} exchange rate on file for {date}. Add that rate on Accounting → Chart of Accounts, then approve again.",
      "notAuthenticated": "Please sign in before updating this approval.",
      "notAuthorized": "You are not authorized to decide this submission.",
      "notPending": "This submission was already decided. Refresh to see the latest status.",
      "overrideReasonRequired": "Add an override reason before approving the flagged claims.",
      "actionFailed": "We couldn't complete this action. Please try again.",
      "accrualAccountNotConfigured": "This approval can't be posted because the Accruals account isn't usable. Review the Accruals designation on Accounting → Chart of Accounts, then approve again.",
      "accrualAccountIsHeading": "The Accruals account has sub-accounts, so it's a heading and can't take postings. Designate one of its sub-accounts on Accounting → Chart of Accounts, then approve again.",
      "accrualSharesNotAllocatable": "Nothing was approved. These claims can't be posted together because their amounts in your business currency can't be shared out to the cent. Approve the claims one at a time, or contact support.",
      "beforeConversionDate": "This date is before your opening-balance go-live date. Use a date on or after go-live, or review the opening balance in Accounting → Opening balance.",
      "receiptRequired": "Cannot submit yet. Every claim needs a receipt attached before it can be submitted.",
      "duplicateReviewRequired": "Some claims in this report may be duplicates. Review them and add a reason before submitting.",
      "receiptRequiredNamed": "Cannot submit this report yet. The claim {claim} has no receipt attached. Attach a receipt to that claim, then submit again.",
      "fileIncompleteFinancials": "A claim needs an amount, a currency and a date before it can be filed.",
      "fileOverCategoryCap": "A claim in this report is over its category cap. Raise the cap in Expense approval settings, or lower the amount."
    },
    "status": {
      "draft": "Draft",
      "pending": "Pending",
      "pendingApproval": "Pending Approval",
      "approved": "Approved",
      "rejected": "Rejected",
      "reimbursed": "Reimbursed"
    },
    "claimStatus": {
      "draft": "Draft",
      "uploading": "Uploading",
      "classifying": "Classifying",
      "analyzing": "Analyzing",
      "processing": "Processing",
      "submitted": "Submitted",
      "approved": "Approved",
      "rejected": "Rejected",
      "reimbursed": "Reimbursed",
      "failed": "Failed",
      "classificationFailed": "Processing Failed"
    },
    "actions": {
      "save": "Save",
      "cancel": "Cancel",
      "delete": "Delete",
      "remove": "Remove",
      "reject": "Reject",
      "approveAll": "Approve All",
      "submitForApproval": "Submit for Approval",
      "deleteDraft": "Delete Draft",
      "enterManually": "Enter Manually",
      "nextPending": "Next pending",
      "submitAndFile": "Submit and File"
    },
    "tooltips": {
      "addAtLeastOneClaim": "Add at least one claim",
      "waitForProcessing": "Wait for claims to finish processing",
      "receiptRequired": "Attach a receipt to every claim before submitting",
      "purposeRequired": "Add a business purpose to every claim before submitting"
    },
    "rejectionBanner": {
      "title": "Submission was rejected",
      "perClaimNotes": "Per-claim notes:"
    },
    "emptyDraft": {
      "title": "Empty draft",
      "description": "Upload receipts to get started. Empty drafts are automatically deleted after 24 hours."
    },
    "bulkBar": {
      "claimsSelected": "{total, plural, one {{selected} of # claim selected} other {{selected} of # claims selected}}",
      "clearSelection": "Clear Selection",
      "rejectSelected": "Reject Selected ({count})",
      "approveSelected": "Approve Selected ({count})"
    },
    "claimsCard": {
      "heading": "Claims"
    },
    "table": {
      "vendor": "Vendor",
      "amount": "Amount",
      "category": "Category",
      "date": "Date",
      "status": "Status",
      "actions": "Actions",
      "pendingExtraction": "Pending extraction",
      "failedTooltip": "Processing failed. Our team has been notified. Tap retry to try again.",
      "failedTooltipWithError": "{error}. Tap retry to reprocess.",
      "retryProcessing": "Retry processing",
      "cappedFrom": "capped from {claimed}",
      "convertedAmount": "In {currency}",
      "notConverted": "not converted to {currency}",
      "readingReceipt": "Reading receipt"
    },
    "totals": {
      "totalLabel": "Total ({currency})",
      "reimbursementProgress": "Reimbursement: {reimbursed} of {total, plural, one {# claim} other {# claims}} reimbursed",
      "pendingApprovalFrom": "Pending approval from",
      "approvedBy": "Approved by",
      "unconvertedNote": "Includes {converted, plural, one {# claim} other {# claims}}; {unconverted, plural, one {# claim is} other {# claims are}} not converted to {currency}",
      "nativeBreakdown": "Claim currency: {amounts}"
    },
    "emptyClaims": {
      "title": "No claims yet",
      "draftHint": "Click \"Upload Receipts\" above to add expense claims",
      "noClaims": "This submission has no claims"
    },
    "deleteDialog": {
      "title": "Delete Submission",
      "message": "Are you sure you want to delete this submission and all its claims? This action cannot be undone."
    },
    "removeClaimDialog": {
      "title": "Remove Claim",
      "message": "Remove this claim from the submission? It will be taken off the submission and no longer listed in your claims."
    },
    "approveDialog": {
      "title": "Approve Submission",
      "message": "{count, plural, one {Approve the only claim in \"{title}\"?} other {Approve all # claims in \"{title}\"?}} This will mark the entire submission as approved.",
      "approving": "Approving...",
      "overrideReasonLabel": "Approval override reason",
      "overrideReasonPlaceholder": "Explain why these flagged claims should still be approved...",
      "overrideReasonRequiredHint": "Required when approving claims with duplicate or policy flags.",
      "overrideReasonOptionalHint": "Optional unless a duplicate or policy flag requires an override.",
      "forwardedToNextApprover": "Forwarded to the next approver"
    },
    "partialApproveDialog": {
      "title": "Partial Approval",
      "message": "Approving {selected} of {total, plural, one {# claim} other {# claims}}. The remaining {remaining, plural, one {# claim} other {# claims}} will be returned to the employee as a new draft.",
      "reasonLabel": "Reason for returning claims (optional)",
      "reasonPlaceholder": "Explain why some claims are being returned...",
      "approving": "Approving...",
      "approveButton": "{count, plural, one {Approve # Claim} other {Approve # Claims}}"
    },
    "partialRejectDialog": {
      "title": "Reject Selected Claims",
      "message": "Rejecting {selected} of {total, plural, one {# claim} other {# claims}}. These will be returned to the employee as a new draft submission. The remaining {remaining, plural, one {# claim} other {# claims}} will stay pending for your review.",
      "reasonLabel": "Reason for rejection",
      "reasonPlaceholder": "Explain why these claims are being rejected...",
      "rejecting": "Rejecting...",
      "rejectButton": "{count, plural, one {Reject # Claim} other {Reject # Claims}}"
    },
    "rejectDialog": {
      "title": "Reject Submission",
      "reasonLabel": "Reason for rejection",
      "reasonPlaceholder": "Explain why this submission is being rejected...",
      "rejecting": "Rejecting..."
    },
    "duplicateDialog": {
      "title": "Duplicate Claims Detected ({count})",
      "description": "Provide justification for each flagged claim before submitting.",
      "matchCount": "{count, plural, one {# match} other {# matches}}",
      "badge": "Duplicate",
      "splitExpenseLabel": "This is a split expense (shared bill)",
      "justificationLabel": "Justification *",
      "justificationPlaceholder": "Explain why this is not a duplicate (min 10 characters)...",
      "moreCharactersNeeded": "{count, plural, one {# more character needed} other {# more characters needed}}",
      "submitWithJustification": "Submit with Justification",
      "matchSameReport": "May be the same receipt as another claim in this report: {vendor}, {amount}, {date}.",
      "matchFiled": "May match a claim that is already filed: {vendor}, {amount}, {date}.",
      "titleSingle": "This claim may be a duplicate",
      "descriptionSingle": "Give a reason before submitting this claim."
    },
    "sidebar": {
      "mySubmissions": "My Submissions",
      "pendingSubmissions": "Pending Submissions",
      "loading": "Loading...",
      "totalCount": "{count} total",
      "awaitingReview": "{count} awaiting review",
      "noSubmissions": "No submissions yet",
      "noPendingSubmissions": "No pending submissions",
      "claimsCount": "{count, plural, one {# claim} other {# claims}}",
      "bySubmitter": "by {name}",
      "approvedSubmissions": "Approved Submissions",
      "noApprovedSubmissions": "No approved submissions yet",
      "convertedTotal": "Total in {currency}",
      "unconvertedClaims": "{count} not converted"
    },
    "defaultTitle": "Submission - {monthName} {year}",
    "returnedTitle": "Returned: {title}",
    "months": {
      "1": "Jan",
      "2": "Feb",
      "3": "Mar",
      "4": "Apr",
      "5": "May",
      "6": "Jun",
      "7": "Jul",
      "8": "Aug",
      "9": "Sep",
      "10": "Oct",
      "11": "Nov",
      "12": "Dec"
    },
    "routing": {
      "label": "Approval route",
      "levelXOfY": "Level {level} of {total}"
    },
    "reportCode": {
      "absentDraft": "No code yet",
      "copy": "Copy report code",
      "copyFailed": "Could not copy the code. Select it and copy manually."
    },
    "duplicateHint": {
      "alsoIn": "Also in {report} ({status})",
      "alsoInNoStatus": "Also in {report}",
      "possiblyIn": "Possibly also in {report} ({status}). {differences}",
      "possiblyInNoStatus": "Possibly also in {report}. {differences}",
      "statusDraft": "Draft",
      "statusSubmitted": "Submitted",
      "statusApproved": "Approved",
      "statusReimbursed": "Reimbursed"
    },
    "paymentTrail": {
      "truncated": "This report has more expenses than we can check at once, so another payment may also have settled part of it."
    },
    "readingProgress": "{total, plural, =1 {Reading your receipt} other {{done} of {total} receipts read}}",
    "autoApprovalRoute": "Automatic approval",
    "autoApprovedBy": "Approved automatically ({rules})",
    "autoApprovedByNoRule": "Approved automatically",
    "autoApprovalRule": "{category} up to {amount}"
  },
  "documentsInbox": {
    "header": {
      "title": "Documents Inbox",
      "subtitle": "Forward invoices and receipts from your email inbox. Groot sorts them automatically and holds anything unclear here for review."
    },
    "address": {
      "eyebrow": "Private forwarding",
      "title": "Your forwarding address",
      "description": "This address belongs only to you in this business. Forward documents here to keep your inbox private.",
      "loading": "Preparing your private address…",
      "unavailable": "Your private address is not available right now.",
      "copy": "Copy address",
      "copied": "Private address copied",
      "copiedShort": "Copied",
      "copyFailed": "Could not copy the address",
      "rotate": "Rotate",
      "rotateConfirm": "Rotate your private forwarding address? The current address will stop accepting new documents.",
      "rotated": "Private address rotated and copied",
      "rotateFailed": "Could not rotate the private address",
      "disabled": "Email forwarding is disabled for this business. New forwards will not be accepted."
    },
    "senders": {
      "title": "Verified senders",
      "description": "Add another mailbox only when you control it. We send a verification link before it can forward documents.",
      "loginEmailNote": "Login email is verified",
      "inputLabel": "Additional sender email",
      "inputPlaceholder": "sender@example.com",
      "add": "Add sender",
      "empty": "No additional sender emails yet.",
      "pendingHint": "Check that mailbox for a verification link",
      "status": {
        "pending": "Pending",
        "verified": "Verified",
        "revoked": "Revoked"
      },
      "resend": "Resend",
      "resent": "Verification email sent",
      "revoke": "Revoke",
      "revokeConfirm": "Revoke this sender? It will no longer be able to send new documents to your private inbox.",
      "revoked": "Sender revoked",
      "requested": {
        "title": "Verification requested",
        "description": "Open the link sent to that mailbox within 10 minutes."
      },
      "error": {
        "title": "Could not update sender",
        "description": "Please try again. No sender access was changed."
      }
    },
    "detail": {
      "title": "Document details",
      "description": "Only you can view documents received at your private address.",
      "filename": "Filename",
      "sender": "Sender",
      "subject": "Subject",
      "received": "Received",
      "fileType": "File type",
      "fileSize": "File size",
      "classification": "Classification",
      "confidence": "AI confidence",
      "noSubject": "No subject",
      "unknownValue": "Not available",
      "openFile": "Open file",
      "missingFileTitle": "File unavailable",
      "missingFileDescription": "This document is still visible, but its file is no longer available for preview.",
      "unsupportedTitle": "Preview not supported",
      "unsupportedDescription": "This file type cannot be previewed here. Open the file in a new tab if it is available.",
      "previewFailedTitle": "Preview could not load",
      "previewFailedDescription": "The document details are still available. Try opening the file in a new tab.",
      "unavailableTitle": "Document details unavailable",
      "unavailableDescription": "This document could not be loaded. It may have been removed or is not available to this account."
    },
    "verify": {
      "loading": "Checking verification link…",
      "title": "Verify this sender",
      "description": "Confirm that you control this mailbox to allow it to forward documents to your private inbox.",
      "confirm": "Verify sender",
      "signInTitle": "Sign in to continue",
      "signInDescription": "Sign in with the Groot account that requested this verification. The link will be preserved.",
      "signIn": "Sign in",
      "successTitle": "Sender verified",
      "successDescription": "This mailbox can now forward documents to your private inbox for the selected business.",
      "backToInbox": "Back to Documents Inbox",
      "invalidTitle": "Verification link is incomplete",
      "invalidDescription": "Request a new verification email from Documents Inbox.",
      "errorTitle": "Verification could not be completed",
      "errorDescription": "The link may have expired, been replaced, or already been used. Request a new one and try again.",
      "tryAgain": "Try again"
    },
    "auth": {
      "signInRequired": "Please sign in to view documents"
    },
    "noBusiness": "No business found",
    "deleteConfirm": "Are you sure you want to delete this document?",
    "typeLabels": {
      "receipt": "Receipt",
      "apInvoice": "AP Invoice",
      "eInvoice": "E-Invoice",
      "expenseReceipt": "Expense Receipt",
      "businessExpense": "Other Expenses",
      "unknown": "Unknown"
    },
    "stats": {
      "needsReview": "Needs Review",
      "autoRouted": "Auto-Routed",
      "autoRouteRate": "Auto-Route Rate",
      "duplicatesCaught": "Duplicates Caught"
    },
    "table": {
      "filename": "Filename",
      "source": "Source",
      "aiSuggestion": "AI Suggestion",
      "confidence": "Confidence",
      "received": "Received",
      "actions": "Actions"
    },
    "group": {
      "attachmentsFromSameEmail": "{count} attachments from same email",
      "noSubject": "No subject",
      "classifyAllAsReceipt": "Classify All as Receipt"
    },
    "actions": {
      "classify": "Classify",
      "confirmRoute": "Confirm: {type}",
      "change": "Change",
      "delete": "Delete",
      "cancel": "Cancel",
      "confirm": "Confirm"
    },
    "modal": {
      "title": "Classify Document",
      "description": "Select the document type to route it to the correct destination.",
      "documentTypeLabel": "Document Type",
      "documentTypePlaceholder": "Select document type",
      "options": {
        "receipt": "Receipt (Expense Claim)",
        "invoice": "AP Invoice (Supplier Bill)",
        "businessExpense": "Record a business expense",
        "eInvoice": "E-Invoice (LHDN)"
      }
    },
    "toast": {
      "classified": {
        "title": "Document classified",
        "reviewBusinessExpense": "Review and record",
        "description": "Routed as {type}"
      },
      "classifyFailed": {
        "title": "Classification failed",
        "fallback": "Failed to classify"
      },
      "batchClassified": {
        "title": "{count} documents classified",
        "description": "All routed as {type} into one submission"
      },
      "batchClassifyFailed": {
        "title": "Batch classification failed",
        "fallback": "Failed to classify"
      },
      "deleted": "Document deleted",
      "deleteFailed": {
        "title": "Delete failed",
        "fallback": "Failed to delete"
      },
      "emailCopied": "Email copied to clipboard"
    },
    "howItWorks": {
      "triggerAriaLabel": "How email forwarding works",
      "title": "How Email Forwarding Works",
      "description": "Forward receipts and invoices to Groot via email. AI classifies and routes them automatically.",
      "yourForwardingEmail": "Your Forwarding Email",
      "stepsHeading": "3 Simple Steps",
      "steps": {
        "forward": {
          "title": "Forward your email",
          "description": "Forward any email with receipt or invoice attachments (PDF, JPG, PNG) to the address above."
        },
        "classify": {
          "title": "AI classifies automatically",
          "description": "Groot's AI reads the document and determines if it's a receipt or an invoice within 30 seconds."
        },
        "appears": {
          "title": "Document appears in the right place",
          "description": "High-confidence documents go directly to Expense Claims or AP Invoices. Low-confidence ones appear here for you to classify manually."
        }
      },
      "whereHeading": "Where Documents Go",
      "routes": {
        "receipts": {
          "type": "Receipts",
          "destination": "Expense Claims",
          "description": "Restaurant bills, taxi receipts, hotel stays, office supplies"
        },
        "invoices": {
          "type": "Invoices",
          "destination": "AP Invoices",
          "description": "Vendor bills, supplier invoices, service agreements"
        },
        "unclear": {
          "type": "Unclear",
          "destination": "This Inbox",
          "description": "Blurry images, mixed documents, or when AI is unsure"
        }
      },
      "tipsHeading": "Tips",
      "tips": {
        "maxAttachments": "Send up to 10 attachments per email",
        "supportedFormats": "Supported formats: PDF, JPG, PNG",
        "duplicatesDetected": "Duplicates are automatically detected",
        "allowlistOnly": "Only authorized emails in your allowlist can forward"
      },
      "manageSettingsPrefix": "To manage authorized senders or disable forwarding, go to",
      "businessSettingsLink": "Business Settings",
      "manageSettingsSuffix": "."
    },
    "empty": {
      "title": "No documents to review",
      "descriptionEnabled": "All forwarded documents have been auto-classified. Documents that need your attention will appear here.",
      "descriptionDisabled": "Enable email forwarding to start receiving documents via email.",
      "onboarding": {
        "heading": "Get started with email forwarding",
        "step1": "Copy your forwarding email:",
        "step2": "Forward any email with receipt or invoice attachments (PDF, JPG, PNG)",
        "step3": "AI auto-classifies and routes to Expense Claims or AP Invoices. Only unclear documents appear here."
      }
    }
  },
  "receivedEinvoices": {
    "title": "Supplier e-invoices",
    "subtitle": "E-invoices your suppliers filed with LHDN for your business that still need you.",
    "handledAutomatically": "Handled automatically in the last 30 days: {count}",
    "loading": "Loading...",
    "unknownSupplier": "Unknown supplier",
    "loadMore": "Load more",
    "filter": {
      "showAll": "Show all supplier e-invoices",
      "showNeedsAction": "Show only those that need me"
    },
    "columns": {
      "supplier": "Supplier",
      "invoiceNumber": "Supplier invoice no.",
      "issued": "Issued",
      "total": "Total",
      "type": "Type",
      "currency": "Currency",
      "why": "Why it is here",
      "action": "Action"
    },
    "types": {
      "11": "Self-billed invoice",
      "12": "Self-billed credit note",
      "13": "Self-billed debit note",
      "14": "Self-billed refund note",
      "01": "Invoice",
      "02": "Credit note",
      "03": "Debit note",
      "04": "Refund note",
      "unknown": "Document"
    },
    "status": {
      "cancelled": "Cancelled",
      "rejected": "Rejected by you",
      "matched": "Matched to expense claim",
      "matchedBill": "Matched to a bill"
    },
    "lastChecked": {
      "at": "Last checked with LHDN {time}",
      "never": "Not checked with LHDN yet",
      "failedAt": "Last check with LHDN failed {time}. Groot will try again.",
      "lastGood": "Last good check {time}",
      "catchingUp": "Still reading your e-invoices from LHDN. Last run {time}"
    },
    "rejectBy": "Reject by {time}",
    "actions": {
      "open": "Open"
    },
    "reason": {
      "not_read_yet": "Groot has not read this document yet. It is read on the next check, within 30 minutes.",
      "unreadable": "Groot could not read this document. Open it to see what LHDN holds.",
      "addressed_elsewhere": "This document is addressed to a different taxpayer than your business. Check it before you do anything with it.",
      "addressee_unstated": "This document does not say which taxpayer it is addressed to, so Groot cannot tell that it is yours.",
      "self_billed_for_you": "Self-billed by the other party: their statement of what they owe you, not a bill for you to pay.",
      "adjustment_note": "A credit, debit or refund note. It adjusts an earlier invoice.",
      "adjustment_note_of": "A credit, debit or refund note. It adjusts invoice {number}.",
      "no_bill_yet": "No bill in your books matches this yet.",
      "amount_differs": "A bill from this supplier with the same invoice number has a different total: {billTotal} on your bill, {total} on this e-invoice. Check which is right before the 72 hours to reject run out.",
      "currency_differs": "A bill from this supplier with the same invoice number is in {billCurrency}, but this e-invoice is in {currency}. Check which is right before the 72 hours to reject run out.",
      "supplier_differs": "The bill that carries this e-invoice's identifier belongs to a supplier with a different TIN. Check it before the 72 hours to reject run out.",
      "billPostedNote": "The bill is already posted, so a correction goes through a credit note or the correction desk.",
      "ambiguous_match": "More than one of your bills fits this e-invoice, so Groot has not picked one. Remove or fix the duplicate and it will link by itself.",
      "ambiguous_vendor": "More than one supplier in your list has this name, so Groot cannot tell whose bill this is. Give each supplier its TIN and it will link by itself.",
      "candidate_match_unconfirmed": "A bill from this supplier with the same invoice number might be this e-invoice, but its total or currency could not be read, so Groot has not linked them. Correct the bill and it will link by itself.",
      "match_unclear": "Groot found a bill that might be this one but could not be sure. Open the e-invoice to see why.",
      "same_number_one_agrees": "Two bills carry this invoice number and only one agrees with the e-invoice. Check which is right.",
      "bill_linked_to_other_einvoice": "A bill with this number is already linked to another e-invoice from this supplier. Check whether the supplier sent it twice.",
      "linked_bill_removed": "The bill this e-invoice was linked to was deleted or voided, so it is back here. Add or fix a bill with this invoice number and it will link by itself."
    },
    "empty": {
      "notConnectedTitle": "LHDN is not connected yet",
      "notConnectedBody": "Connect your LHDN MyInvois account in settings and the e-invoices your suppliers file for you will appear here.",
      "needsActionTitle": "Nothing needs your attention",
      "needsActionBody": "Every supplier e-invoice has been linked to an expense claim or a bill, rejected or cancelled.",
      "allTitle": "No e-invoices received yet",
      "allBody": "Groot checks LHDN every 30 minutes. New e-invoices from your suppliers will show up here.",
      "neverTitle": "Not checked with LHDN yet",
      "neverBody": "Groot checks LHDN every 30 minutes. The first check for your business has not finished yet, so this list may be incomplete.",
      "failedTitle": "The last check with LHDN did not finish",
      "failedBody": "Groot could not finish reading your supplier e-invoices, so this list may be incomplete. It tries again every 30 minutes. If this keeps happening, check your LHDN connection in settings.",
      "catchingUpTitle": "Still reading your supplier e-invoices",
      "catchingUpBody": "There are a lot of documents to read from LHDN. Groot carries on at the next check, so this list may be incomplete until it has caught up."
    },
    "howItWorks": {
      "title": "How supplier e-invoices work",
      "intro": "When a supplier files an e-invoice to your business on LHDN MyInvois, Groot picks it up. Only the ones that need you are listed here.",
      "step1": "Groot checks LHDN every 30 minutes and reads each new document once.",
      "step2": "A document that matches one of your expense claims or one of your bills is linked automatically and does not appear here.",
      "step3": "Open any row to see its lines and tax. While LHDN's 72-hour window is open you can reject a wrong e-invoice.",
      "step4": "If there is no bill yet, choose Create bill. Groot drafts it from the e-invoice and holds it for you to check. Nothing is posted until you confirm it.",
      "hereTerm": "Listed here",
      "hereMeaning": "Valid documents that are not linked to an expense claim or a bill and that you have not rejected. Each row says why.",
      "notHereTerm": "Not listed here",
      "notHereMeaning": "Documents already linked to an expense claim or a bill, rejected, or cancelled. Choose Show all supplier e-invoices to see them.",
      "tip": "After 72 hours an e-invoice can no longer be rejected. Ask the supplier for a credit or debit note instead.",
      "settingsLink": "Open e-invoice settings"
    },
    "drawer": {
      "title": "E-invoice from {supplier}",
      "description": "What the supplier filed with LHDN.",
      "unavailable": "This e-invoice is not available.",
      "adjusts": "Adjusts invoice",
      "supplierTin": "Supplier TIN",
      "supplierBrn": "Supplier registration no.",
      "validated": "Validated by LHDN",
      "exchangeRate": "Exchange rate",
      "rateValue": "1 {currency} = {rate} MYR",
      "totalTax": "Tax",
      "taxInCurrency": "(in {currency})",
      "totalPayable": "Total payable",
      "lines": "Lines",
      "lineDescription": "Description",
      "quantity": "Qty",
      "unitPrice": "Unit price",
      "lineTotal": "Total",
      "classification": "Class.",
      "linesShown": "Showing {shown} of {total} lines.",
      "linesUnreadable": "Groot could not read the line details of this document. The totals above come from LHDN.",
      "linesPending": "The line details have not been read yet. They are fetched on the next check.",
      "viewOnLhdn": "View on LHDN",
      "longId": "LHDN long ID",
      "rejectedNote": "You rejected this e-invoice. Reason: {reason}",
      "rejectDeadline": "You can reject this e-invoice until {deadline}, which is 72 hours after LHDN validated it.",
      "reject": "Reject e-invoice",
      "windowClosed": "The 72-hour window to reject this e-invoice closed on {deadline}. To correct it, ask the supplier for a credit or debit note.",
      "rejectMatchedNote": "This e-invoice is attached to an expense claim. If you reject it, it is removed from that claim and the person who submitted the claim is notified.",
      "matchedBill": "Linked to your bill automatically.",
      "draftedBill": "A bill was created from this e-invoice.",
      "reminderEmailed": "A deadline reminder was emailed to {count, plural, one {# person} other {# people}} on {time}.",
      "matchBasis": {
        "uuid": "The bill already carried this e-invoice's LHDN identifier.",
        "tin": "Same supplier TIN, same invoice number and same total.",
        "name": "Same supplier name, same invoice number and same total.",
        "draft": "It is held for your review. Nothing is posted until you confirm it."
      },
      "billNumber": "Your bill number",
      "billTotal": "Total on your bill",
      "rejectBillNote": "This e-invoice is linked to one of your bills. If you reject it, that bill is marked as rejected too."
    },
    "createBill": {
      "label": "Create bill",
      "working": "Creating bill",
      "hint": "Groot drafts the bill from this e-invoice and holds it for you to check. Nothing is posted until you confirm it.",
      "toast": {
        "created": {
          "title": "Draft bill created",
          "ready": "It is held for you. Check it against the e-invoice, then confirm and post.",
          "newSupplier": "The supplier is not in your list yet, so it is created when you confirm the bill. Check the bill, then confirm and post.",
          "ambiguousSupplier": "Two suppliers in your list fit, so none was chosen. Choose the right one on the bill, then confirm and post.",
          "chooseCategory": "Choose a category on the bill: this supplier does not have three bills in the same category yet. Then confirm and post."
        },
        "linkedExisting": {
          "title": "Linked to your existing bill",
          "description": "A bill with the same supplier, invoice number and total was already in your books, so no second bill was made."
        },
        "alreadyThere": {
          "title": "This e-invoice already has a bill",
          "description": "Opening it."
        }
      },
      "error": {
        "title": "The bill was not created",
        "generic": "Something went wrong and nothing was created. Try again, and tell us if it keeps happening.",
        "notDraftable": {
          "business_not_my": "Supplier e-invoices are for Malaysian businesses, so a bill cannot be created from this one.",
          "not_valid": "This e-invoice is no longer valid at LHDN, so no bill can be created from it.",
          "already_matched": "This e-invoice is already attached to an expense claim or a bill.",
          "not_read": "Groot has not read this e-invoice yet. Try again after the next check.",
          "not_an_invoice": "Only a supplier invoice becomes a bill. A credit, debit or refund note adjusts a bill you already have.",
          "not_addressed_to_business": "This e-invoice is not addressed to your business, so no bill was created from it."
        },
        "exists": "A bill with this supplier and invoice number is already in your books, so a second one was not created. The reason is shown on this e-invoice.",
        "stale": "This e-invoice is still being released from a bill that was removed. Try again in a moment.",
        "notFound": "This e-invoice is not available any more.",
        "tooManyLines": "This e-invoice has more than 50 lines, which is too many to turn into a bill. Enter the bill yourself and it will link by itself.",
        "incomplete": "This e-invoice is missing something a bill needs, such as the invoice number, the date, the total or a line amount. Enter the bill yourself and it will link by itself.",
        "fx": "A bill in a foreign currency needs the Multi-currency add-on, which is not switched on for this business. Enter the bill in your own currency, or contact us to switch it on.",
        "fullAp": "Posting supplier bills is not part of this business's plan, so a bill cannot be created from an e-invoice.",
        "forbidden": "Only an owner, finance admin or manager can create a bill from an e-invoice."
      }
    }
  },
  "invoicesTab": {
    "header": {
      "title": "Invoices"
    },
    "topTabs": {
      "accountReceivables": "Account Receivables",
      "accountPayables": "Account Payables"
    },
    "arSubTabs": {
      "dashboard": "Dashboard",
      "salesInvoices": "Sales Invoices",
      "recurring": "Recurring Invoices",
      "dailySales": "Platform & POS sales",
      "customers": "Customers",
      "productCatalog": "Product Catalog",
      "reconciliation": "Reconciliation",
      "einvoiceCompliance": "E-Invoice Compliance",
      "reports": "Reports",
      "customersMaster": "Customers (Master)",
      "marketplace": "Marketplace",
      "salesOrders": "Sales Orders",
      "quotations": "Quotations",
      "deliveries": "Deliveries"
    },
    "apSubTabs": {
      "dashboard": "Dashboard",
      "purchaseInvoices": "Purchase Invoices",
      "vendors": "Vendors",
      "priceIntelligence": "Price Intelligence",
      "purchaseOrders": "Purchase Orders",
      "goodsReceived": "Goods Received",
      "matching": "Matching",
      "reports": "Reports",
      "creditNotes": "Credit & Debit Notes",
      "creditPurchases": "Credit Purchases",
      "directPurchases": "Direct Purchases"
    },
    "reportsTabs": {
      "aging": "Aging",
      "statements": "Statements"
    },
    "captureCreditNote": "Capture supplier note",
    "apLanes": {
      "creditNote": "A credit purchase is a supplier bill you settle later. It has payment terms and a due date, and it shows up in AP aging and in pay runs. If a document you upload here clearly shows it was already paid, Groot records it as a direct purchase instead and tells you why.",
      "directNote": "A direct purchase was already paid at the point of purchase, so it never creates a payable. Anything you upload or key in on this tab is recorded as already paid, so use it only for receipts you have settled.",
      "newDirectPurchase": "Record a paid purchase"
    }
  },
  "businessSettingsUI": {
    "header": {
      "title": "Settings",
      "subtitle": "Manage your preferences and business configuration"
    },
    "unsavedChangesWarning": "You have unsaved changes in your settings. Are you sure you want to leave?",
    "loadingBusinessSettings": "Loading business settings...",
    "signInRequired": "Please sign in to access this feature.",
    "loadingNamed": "Loading {name}...",
    "tabs": {
      "business": "Business",
      "finance": "Finance",
      "people": "People",
      "integrations": "Integrations",
      "billing": "Billing",
      "referral": "Referral",
      "personal": "Personal"
    },
    "subTabs": {
      "businessProfile": "Business Profile",
      "inventory": "Inventory",
      "invoiceReview": "Invoice review",
      "eInvoice": "e-Invoice",
      "documentInbox": "Document Inbox",
      "categories": "Categories",
      "aiAutomation": "AI & Automation",
      "team": "Team",
      "leave": "Leave",
      "timesheet": "Timesheet",
      "stripe": "Stripe",
      "apiKeys": "API Keys",
      "profile": "Profile",
      "privacyData": "Privacy & Data",
      "sqlAccounting": "SQL Accounting",
      "departments": "Departments",
      "projects": "Projects",
      "expenseApproval": "Approval",
      "accounting": "Accounting",
      "trackingDimensions": "Tracking dimensions",
      "autocount": "AutoCount",
      "lark": "Lark",
      "ecommerce": "E-commerce",
      "industry": "Industry",
      "documents": "Documents",
      "chartOfAccounts": "Chart of accounts",
      "grootMemory": "Groot memory"
    },
    "loaderTitles": {
      "businessSettings": "business settings",
      "billing": "billing",
      "referral": "referral"
    },
    "categoriesMoved": {
      "title": "Categories moved to the Chart of Accounts",
      "description": "Expense and COGS categories are now managed directly in your Chart of Accounts. Tick which accounts can be used as categories, and import accounts there.",
      "cta": "Open Chart of Accounts"
    },
    "inventorySummary": {
      "title": "Inventory",
      "description": "Control the stock source of truth, fulfillment flow, receiving policy, and negative-stock behavior from Products → Stock → Settings.",
      "cta": "Open Inventory settings"
    }
  },
  "teamsManagement": {
    "loading": "Loading teams management...",
    "page": {
      "title": "Teams Management"
    },
    "accessDenied": {
      "title": "Access Denied",
      "description": "Teams management requires Finance permissions."
    },
    "rolePermissions": {
      "title": "Role Permissions",
      "description": "Understanding role permissions and capabilities",
      "inviteButton": "Invite Team Member"
    },
    "roles": {
      "employee": {
        "title": "Employee",
        "perm1": "Submit expense claims",
        "perm2": "Upload receipts",
        "perm3": "View own transactions",
        "perm4": "View own dashboard"
      },
      "manager": {
        "title": "Manager",
        "perm1": "All employee permissions",
        "perm2": "Approve/reject expenses",
        "perm3": "Manage expense categories",
        "perm4": "View team expenses",
        "perm5": "Financial reports only if the owner turns them on"
      },
      "financeAdmin": {
        "title": "Finance",
        "perm1": "All manager permissions",
        "perm2": "Full analytics dashboard",
        "perm3": "Manage user roles",
        "perm4": "Send team invitations",
        "perm5": "Access accounting entries"
      },
      "owner": {
        "title": "Owner",
        "perm1": "All Finance permissions",
        "perm2": "Manage billing & subscription",
        "perm3": "Transfer business ownership",
        "perm4": "Delete business account"
      }
    },
    "roleNames": {
      "employee": "Employee",
      "manager": "Manager",
      "financeAdmin": "Finance",
      "owner": "Owner"
    },
    "tabs": {
      "members": "Team Members ({count})",
      "invitations": "Pending Invitations ({count})"
    },
    "members": {
      "title": "Active Team Members",
      "description": "Manage role assignments for current team members",
      "empty": "No team members found",
      "fullNamePlaceholder": "Enter full name",
      "userFallback": "User",
      "youInline": "(You)",
      "youBadge": "You",
      "noEmail": "No email",
      "joined": "Joined {date}",
      "roleLabel": "Role",
      "lastOwnerTooltip": "Cannot change role - you are the last owner",
      "managerRequiredLabel": "Manager",
      "managerOptionalLabel": "Manager (Optional)",
      "assignManagerPlaceholder": "Assign manager",
      "optionalManagerPlaceholder": "Optional manager",
      "noAssignment": "No Assignment",
      "managerFallback": "Manager",
      "thisUserFallback": "this user",
      "approvesToLabel": "Forwards approvals to",
      "approvesToPlaceholder": "Final approver",
      "approvesToNone": "Final approver (no forwarding)",
      "approvesToFinalBadge": "Final approver",
      "chainPathLabel": "Approval path:",
      "chainNoApprover": "No approver assigned. Add a Manager so claims can be approved.",
      "chainForwardsTo": "Forwards to",
      "chainFinalApprover": "Final approver",
      "salesAgentLabel": "Sales agent",
      "salesAgentHint": "Offered in sales-agent pickers. While nobody is flagged, every active member is offered.",
      "salesAgentFlagged": "Flagged as a sales agent",
      "salesAgentUnflagged": "Removed from sales agents",
      "salesAgentUpdateFailed": "Couldn't update the sales-agent flag. Please try again.",
      "removeMember": "Remove member",
      "setupApprovalPolicy": "Set up approval policy",
      "editName": "Edit name"
    },
    "invitations": {
      "title": "Pending Invitations",
      "description": "Manage outstanding invitations to your business",
      "empty": "No pending invitations",
      "statusPending": "Pending",
      "statusAccepted": "Accepted",
      "statusExpired": "Expired",
      "invitedOn": "Invited {date}",
      "resend": "Resend"
    },
    "removeDialog": {
      "title": "Remove Team Member",
      "message": "Remove {name} from this business? All their membership and invitation records for this business will be removed. Their account, other businesses and historical records will be kept.",
      "confirm": "Remove",
      "checking": "Checking team and approval responsibilities…",
      "unavailable": "Cannot verify this member’s access. Close this dialog and refresh the team list.",
      "teamHandoff": "Cancel, then use the Manager and approval-routing controls on the Team page to assign a replacement. Update or cancel any pending invitations that still name this person. Suspended members keep their routing: reactivate them before assigning a replacement, or remove their access if it is no longer needed.",
      "openPolicies": "Review approval policies",
      "openApprovals": "Resolve outstanding approvals"
    },
    "toast": {
      "successTitle": "Success",
      "errorTitle": "Error",
      "warningTitle": "Warning",
      "roleUpdated": "User role updated successfully",
      "memberRemoved": "User removed from business successfully",
      "managerRequiredTitle": "Manager Required",
      "managerRequiredDescription": "Employees must have a manager assigned. Please select a manager.",
      "managerAssigned": "Manager assignment updated successfully",
      "invitationSent": "Invitation sent to {email}",
      "invitationResent": "Invitation resent successfully",
      "invitationDeleted": "Invitation deleted successfully",
      "nameUpdated": "Name updated successfully",
      "noticeTitle": "Notice",
      "resendAlreadyAccepted": "This invitation was already accepted; nothing to resend.",
      "approvesToUpdated": "Approval chain updated"
    },
    "errors": {
      "fetchInvitationsFailed": "Failed to fetch invitations",
      "fetchMembersFailed": "Failed to fetch team members",
      "updateRoleFailed": "Failed to update role",
      "removeMemberFailed": "Failed to remove member",
      "assignManagerFailed": "Failed to assign manager",
      "csrfTokenFailed": "Failed to get CSRF token",
      "teamLimitExceeded": "Team limit exceeded",
      "sendInvitationFailed": "Failed to send invitation",
      "sendInvitationNetwork": "Network error while sending invitation",
      "resendInvitationFailed": "Failed to resend invitation",
      "resendInvitationNetwork": "Network error while resending invitation",
      "deleteInvitationFailed": "Failed to delete invitation",
      "deleteInvitationNetwork": "Network error while deleting invitation",
      "nameRequired": "Please enter a valid name",
      "nameTooShort": "Name must be at least 2 characters long",
      "updateNameFailed": "Failed to update name",
      "updateNameNetwork": "Network error while updating name",
      "approvesToFailed": "Could not update the approval chain",
      "lastAdminProtected": "At least one active owner or Finance admin must remain. Add another admin before changing this access.",
      "roleHierarchyProtected": "You cannot remove a member with a higher or protected role.",
      "ownerProtected": "The business owner cannot be removed. Transfer ownership to someone else first, then remove this account.",
      "lastOwner": "A business must always have at least one owner. Transfer ownership to another member before changing this role.",
      "managerNotApprover": "That person cannot approve expenses yet. Give them the manager role or higher, then assign them.",
      "alreadyMember": "This person is already a member of this business.",
      "invitationAlreadyPending": "An invitation to this email is already pending. To send it again, open the Pending Invitations tab and choose Resend.",
      "memberHandoffRequired": "Reassign this person’s team and approval responsibilities, and resolve outstanding approvals before removing their access. Resolve or cancel draft leave requests and timesheets assigned to them too.",
      "teamReviewRequired": "This team change needs a membership review. Ask a business owner or support to resolve duplicate memberships or review the large approval queue first."
    },
    "routing": {
      "label": "Forward approvals to",
      "finalApprover": "No forwarding (final approver)",
      "unavailableApprover": "Unavailable approver (choose a replacement)",
      "saved": "Approval forwarding updated.",
      "invalid": "Choose an active approver without a circular chain or more than three approval levels.",
      "failed": "Could not update approval forwarding. Refresh the team and check your access."
    },
    "financialReports": {
      "label": "Can see financial reports",
      "help": "Profit and loss, balance sheet, trial balance, cash flow and the journal. These show your margins and the salary total, so turn this on only for people you trust with them.",
      "alwaysOn": "Always on for owners and finance admins",
      "ownerOnly": "Only the owner can change this",
      "turnedOn": "{name} can now see financial reports",
      "turnedOff": "{name} can no longer see financial reports",
      "notManager": "Only managers have this switch.",
      "error": "Could not change financial reports access. Please try again."
    },
    "salesAccess": {
      "label": "Sales access",
      "help": "Works their own customers: quotations, sales orders and draft deliveries. No invoices and no reports.",
      "agentsLabel": "Sales agent",
      "retired": "retired",
      "noActiveAgent": "{name} has no active sales agent linked, so they see only what they create. Link one under Settings, Sales agents.",
      "turnedOn": "{name} now has sales access",
      "turnedOff": "{name} no longer has sales access",
      "notEmployee": "Only employees have this switch.",
      "notAvailable": "Sales access needs the Invoicing module, which this business does not have.",
      "agentNotAvailable": "That sales agent is no longer available. Choose another, or create a new one.",
      "error": "Could not change sales access. Please try again.",
      "step": {
        "title": "{name} needs a sales agent",
        "explain": "The customers assigned to this agent are the customers {name} works. Sales access cannot be turned on without one.",
        "label": "Sales agent",
        "create": "Create a new agent",
        "loading": "Loading sales agents...",
        "confirm": "Turn on sales access",
        "cancel": "Cancel",
        "createOnly": "This creates a new sales agent from {name}'s name. No existing agent is free to link.",
        "saving": "Turning on..."
      },
      "alwaysOn": "Always on for owners, finance admins and managers"
    }
  },
  "accountingDashboard": {
    "headerTitle": "Accounting",
    "revenueThisMonth": "Revenue (This Month)",
    "expensesThisMonth": "Expenses (This Month)",
    "netProfit": "Net Profit",
    "cashBalance": "Cash Balance",
    "tabOverview": "Overview",
    "tabFinancialStatements": "Financial Statements",
    "quickSummary": "Quick Summary",
    "totalRevenueThisMonth": "Total Revenue (This Month)",
    "totalExpensesThisMonth": "Total Expenses (This Month)",
    "netProfitLoss": "Net Profit/Loss",
    "profitLossStatement": "Profit & Loss Statement",
    "dateRangeFromTo": "{from} to {to}",
    "revenueSectionHeading": "REVENUE",
    "totalRevenue": "Total Revenue",
    "expensesSectionHeading": "EXPENSES",
    "totalExpenses": "Total Expenses",
    "netProfitLossHeading": "NET PROFIT / (LOSS)",
    "trialBalance": "Trial Balance",
    "asOfDate": "As of {date}",
    "tableAccountCode": "Account Code",
    "tableAccountName": "Account Name",
    "tableDebit": "Debit",
    "tableCredit": "Credit",
    "tableTotal": "TOTAL",
    "trialBalanceBalanced": "Trial Balance is Balanced",
    "trialBalanceUnbalanced": "Trial Balance is Unbalanced (Difference: {difference})",
    "viewFullStatementsNote": "View the full Profit & Loss, Balance Sheet, Cash Flow and Trial Balance in Reports.",
    "viewInReports": "View in Reports"
  },
  "journalEntries": {
    "cashExceptionGuidance": "Bank and cash movements normally belong in Bank / Cash or their source document. A direct journal requires an owner or finance administrator to explain the exception before posting.",
    "cashExceptionReason": "Why is a manual cash journal needed?",
    "cashExceptionReasonRequired": "Explain the exception in at least 10 characters before posting.",
    "pageTitle": "Journal Entries",
    "newPageTitle": "New Journal Entry",
    "editPageTitle": "Edit Journal Entry",
    "allEntriesTitle": "All Journal Entries",
    "emptyState": "No journal entries found",
    "createFirstEntry": "Create First Entry",
    "tableDate": "Date",
    "tableDescription": "Description",
    "tableSource": "Source",
    "tableAmount": "Amount",
    "tableStatus": "Status",
    "tablePeriod": "Period",
    "tableActions": "Actions",
    "status_posted": "Posted",
    "status_draft": "Draft",
    "status_reversed": "Reversed",
    "periodLocked": "{period} Locked",
    "periodClosed": "{period} Closed",
    "periodOpen": "{period} Open",
    "sourceLabelSalesInvoice": "Invoice",
    "sourceLabelExpenseClaim": "Expense",
    "sourceLabelArReconciliation": "AR Recon",
    "sourceLabelDailySales": "Daily Sales",
    "sourceLabelDeliveryOrder": "Delivery Order",
    "sourceLabelMigrated": "Migrated",
    "postEntryTooltip": "Post entry",
    "editDraft": "Edit draft",
    "editEntry": "Edit",
    "confirmEditDraft": "Edit draft “{description}”? Review and save your changes before leaving the editor.",
    "confirmEditPosted": "Edit posted manual entry “{description}”? Changes will update this entry directly and be recorded in the audit trail.",
    "reverseEntryTooltip": "Reverse entry",
    "deleteDraft": "Delete draft",
    "deleteDraftDialogTitle": "Delete draft journal entry?",
    "deleteDraftDialogMessage": "Delete draft “{description}”? This removes the unposted entry and cannot be undone.",
    "deleteDraftSuccess": "Draft journal entry deleted",
    "deleteDraftError": "Failed to delete draft journal entry",
    "periodLockedTooltip": "Period is locked; entries cannot be edited, reversed, or voided",
    "periodClosedTooltip": "Period is closed. Reopen the period to modify entries.",
    "confirmPost": "Are you sure you want to post this entry? Later edits to manual entries are recorded in the audit trail.",
    "postSuccess": "Journal entry posted successfully",
    "postError": "Failed to post entry",
    "reversalReasonPrompt": "Enter reason for reversal:",
    "reversalReasonRequired": "Reversal reason is required",
    "reverseDialogTitle": "Reverse journal entry",
    "reversalReasonPlaceholder": "e.g. Posted to the wrong account",
    "cancel": "Cancel",
    "confirmReverse": "Are you sure you want to reverse this entry? This will create a reversing entry.",
    "reverseSuccess": "Journal entry reversed successfully",
    "reverseError": "Failed to reverse entry",
    "lockedCannotModify": "Locked (cannot be modified)",
    "periodClosedReopen": "Period closed (reopen to modify)",
    "lineAccount": "Account",
    "lineDebit": "Debit",
    "lineCredit": "Credit",
    "total": "Total",
    "viewSalesInvoice": "View Sales Invoice",
    "viewSupplierInvoice": "View Supplier Invoice",
    "viewExpenseClaim": "View Expense Claim",
    "entryNotFound": "That journal entry could not be found. It may have been deleted.",
    "viewDailySales": "View Daily Sales",
    "viewSource": "View Source",
    "createdByOn": "Created by {user} on {date}",
    "createdOn": "Created {date}",
    "post": "Post",
    "reverse": "Reverse",
    "entryDetailsTitle": "Entry Details",
    "entryDetailsDescription": "Review the journal lines, tracking dimensions, debit and credit totals, and available actions.",
    "transactionDateLabel": "Transaction Date",
    "descriptionLabel": "Description",
    "descriptionPlaceholder": "e.g., Record cash sale for March 2026",
    "journalLinesTitle": "Journal Lines",
    "addLine": "Add Line",
    "selectAccountPlaceholder": "Select account",
    "lineDescriptionPlaceholder": "Line description",
    "closedPeriodWarning": "Cannot create entry; the period for {periodName} is closed",
    "closedPeriodEditWarning": "Cannot move this draft; the period for {periodName} is closed",
    "minLinesError": "Journal entry must have at least 2 lines",
    "minLinesWithAmountsError": "Journal entry must have at least 2 lines with amounts",
    "descriptionRequired": "Please enter a description",
    "transactionDateRequired": "Please select a transaction date",
    "notBalancedError": "Entry is not balanced. Debits must equal Credits.",
    "createAndPostSuccess": "Journal entry created and posted successfully",
    "savedAsDraftSuccess": "Journal entry saved as draft",
    "draftUpdatedSuccess": "Draft journal entry updated",
    "updateAndPostSuccess": "Journal entry updated and posted successfully",
    "createError": "Failed to create journal entry",
    "updateDraftError": "Failed to update draft journal entry",
    "updatePostedError": "Failed to update the posted journal entry",
    "postedUpdateSuccess": "Posted journal entry updated successfully",
    "balanced": "Balanced",
    "unbalanced": "Unbalanced",
    "totalDebitsLabel": "Total Debits:",
    "totalCreditsLabel": "Total Credits:",
    "differenceLabel": "Difference:",
    "mustBalanceBeforePosting": "Entry must be balanced before posting. Debits must equal Credits.",
    "balancedReadyToPost": "Entry is balanced and ready to post.",
    "saving": "Saving...",
    "saveAsDraft": "Save as Draft",
    "saveChanges": "Save Changes",
    "posting": "Posting...",
    "saveAndPost": "Save and Post",
    "saveChangesAndPost": "Save Changes and Post",
    "confirmSavePostedEdit": "Are you sure? This will update the posted manual journal entry directly. The previous values will remain in the audit trail.",
    "defaultLocationLabel": "Default Location",
    "defaultLocationHint": "Applied to every line; change an individual line for reallocations.",
    "locationColumn": "Location",
    "trackingColumn": "Tracking",
    "trackingLocation": "Location",
    "trackingDepartment": "Department",
    "trackingProject": "Project",
    "trackingNone": "No tracking dimensions",
    "loadingEntryDetails": "Loading journal entry details…",
    "selectLocationPlaceholder": "Select Location",
    "unassignedLocation": "Unassigned",
    "locationRequiredError": "Choose a Location for every journal line before posting.",
    "assignLocationTitle": "Assign a Location before posting",
    "assignLocationDescription": "Some lines are missing a Location. Choose one to fill only the unassigned lines, then Groot will post the draft.",
    "assignAndPost": "Assign and post",
    "editDetailsTitle": "Edit Entry Details",
    "editingDraftTitle": "Editing {entryNumber}",
    "editingEntryTitle": "Editing {entryNumber}",
    "postedEditNotice": "This manual entry is already posted. Saving changes updates this same entry directly and records the previous values in the audit trail.",
    "draftNotEditable": "This journal entry cannot be edited here. Only manual entries in an open, unlocked period can be changed.",
    "backToJournalEntries": "Back to Journal Entries",
    "errors": {
      "entryNotFound": "We couldn't find that journal entry. It may have been deleted. Refresh the page and try again.",
      "invalidStatus": "This entry's status changed while you were working. Refresh the page to see where it stands now.",
      "periodLocked": "This entry's accounting period is locked, so it can't be changed. An owner or finance admin can reopen the period in Accounting → Periods.",
      "periodClosed": "That date falls in a closed accounting period. Pick a date in an open period, or ask an owner to reopen it.",
      "sourceManaged": "This entry was created automatically by another document, so it can't be changed or deleted here. Change or void that document instead.",
      "draftChanged": "Someone else changed this draft after you opened it. Return to Journal Entries, reopen it, and apply your changes to the latest version.",
      "entryChanged": "Someone else changed this journal entry after you opened it. Reopen it and apply your changes to the latest version.",
      "entryReconciled": "This journal entry has an active bank reconciliation match. Unmatch it before editing the entry.",
      "reversalEntry": "Reversal journal entries cannot be edited.",
      "noLines": "This entry has no lines, so there's nothing to reverse.",
      "invalidLine": "One of the lines isn't valid. Every line needs an account and either a debit or a credit, and the two sides must balance.",
      "accountNotFound": "One of the accounts on this entry no longer exists. Open the entry and pick a current account for that line.",
      "accountInactive": "One of the accounts on this entry is archived and can't take new postings. Pick an active account for that line.",
      "fxRateMissing": "We don't have an exchange rate for that currency on that date, so this entry can't be converted. Add the rate on Accounting → Chart of Accounts, or use your business currency.",
      "locationNotEditable": "This entry's location can no longer be changed.",
      "apInvoiceHasActivePayments": "Reverse this supplier invoice's payments first, then reverse its posting entry.",
      "apInvoiceHasActiveAdjustments": "Void this supplier invoice's credit and debit notes first, then reverse its posting entry.",
      "apInvoiceJournalLinkAmbiguous": "More than one supplier invoice points to this journal entry. Nothing was changed; contact support to repair the links.",
      "beforeConversionDate": "This date is before your opening-balance go-live date. Use a date on or after go-live, or review the opening balance in Accounting → Opening balance.",
      "voidBankReconciled": "This supplier bill's entry is matched in bank reconciliation, so it can't be voided. Unmatch it in Bank reconciliation first, or record an AP credit note instead.",
      "voidLhdnHeld": "LHDN holds the self-billed e-invoice for this bill. Cancel it with LHDN first, or record an AP credit note instead.",
      "voidStockReceived": "This bill received stock into inventory, so it can't be voided. Return or adjust that stock first, or record an AP credit note instead.",
      "voidExternallyFinalized": "This bill has already been exported to an external accounting system, so it can't be voided here. Record an AP credit note instead.",
      "voidEntrySetUnreadable": "Groot couldn't safely tell which journal entries belong to this bill, so nothing was changed. Record an AP credit note instead, or contact support.",
      "voidFxRevaluationNotRestatable": "A month-end foreign exchange revaluation that includes this bill can't be restated safely, so nothing was changed. Record an AP credit note instead, or re-run that month's revaluation first."
    },
    "voucher": {
      "title": "Journal Voucher",
      "account": "Account",
      "particulars": "Particulars",
      "debit": "Debit",
      "credit": "Credit",
      "total": "Total",
      "reference": "Reference",
      "referenceBlank": "No reference; write it in by hand",
      "voidReasonEntryReversed": "The journal entry behind this voucher was reversed",
      "voidReasonEntryDeleted": "The journal entry behind this voucher was deleted",
      "voidReasonApprovalRevoked": "The claim approval behind this voucher was revoked"
    },
    "tableNumber": "Number",
    "openVoucherSheet": "Open voucher",
    "voidVoucherAction": "Void voucher",
    "issueVoucherAction": "Issue voucher",
    "voucherIssuedTitle": "Voucher {number} issued",
    "voucherIssueFailed": "Could not issue a voucher for this entry",
    "voucherVoidedTitle": "Voucher voided",
    "voucherVoidFailed": "Could not void this voucher",
    "sourceLabelCashDocument": "Bank / Cash",
    "sourceLabelVendorInvoice": "Supplier bill",
    "sourceLabelPayment": "Payment",
    "sourceLabelBusinessExpense": "Business expense",
    "sourceLabelOpeningBalance": "Opening balance",
    "sourceLabelBankReconciliation": "Bank reconciliation",
    "sourceLabelInventoryAdjustment": "Stock adjustment",
    "sourceLabelPayroll": "Payroll",
    "sourceLabelFixedAsset": "Fixed asset",
    "sourceLabelOther": "Other source",
    "sourceLabelCustomerCredit": "Customer credit",
    "sourceLabelFxRevaluation": "FX revaluation",
    "confirmReverseSupplierDocument": "This entry belongs to a supplier document. If it is a bill, voiding it deletes the entry from your books and the bill stays in its list marked Voided. A credit or debit note is reversed with an opposite entry instead."
  },
  "accountingPeriods": {
    "headerTitle": "Accounting Periods",
    "cardTitle": "Accounting Periods",
    "createPeriod": "Create Period",
    "common": {
      "cancel": "Cancel",
      "dr": "DR",
      "cr": "CR"
    },
    "status": {
      "open": "Open",
      "closed": "Closed",
      "locked": "Locked"
    },
    "empty": {
      "title": "No accounting periods yet",
      "description": "Accounting periods help you manage month-end close, prevent backdating, and prepare for audits.",
      "descriptionManage": "Create your first period to get started.",
      "descriptionViewOnly": "Contact your Finance or Owner to create periods.",
      "createFirst": "Create First Period"
    },
    "table": {
      "period": "Period",
      "status": "Status",
      "entries": "Entries",
      "totalDebits": "Total Debits",
      "totalCredits": "Total Credits",
      "net": "Net",
      "actions": "Actions"
    },
    "actions": {
      "viewDetailsTitle": "View period details",
      "close": "Close",
      "closeTitle": "Closing this period prevents new entries",
      "lock": "Lock",
      "lockTitle": "Locking all entries prevents edits, reversals, and voids",
      "reopen": "Reopen",
      "reopenTitle": "Reopening this period allows new entries again",
      "lockedTooltip": "All entries are locked, so no further actions are available",
      "viewOnly": "View only",
      "viewOnlyTitle": "Only Finance or Owner can manage periods"
    },
    "detail": {
      "title": "Period Details: {period}",
      "periodCode": "Period Code",
      "status": "Status",
      "startDate": "Start Date",
      "endDate": "End Date",
      "fiscalYear": "Fiscal Year",
      "fiscalQuarter": "Fiscal Quarter",
      "financialSummary": "Financial Summary",
      "journalEntries": "Journal Entries:",
      "totalDebits": "Total Debits:",
      "totalCredits": "Total Credits:",
      "net": "Net:",
      "closeInformation": "Close Information",
      "closedBy": "Closed By:",
      "closedAt": "Closed At:",
      "notes": "Notes:",
      "createdByOn": "Created by {name} on {date}",
      "reopenHistory": "Reopen history",
      "reopenedBy": "Reopened by {name}",
      "reopenReason": "Reason: {reason}",
      "reopenPriorClose": "It had been closed on {date}"
    },
    "closeDialog": {
      "title": "Close Period: {period}",
      "description": "Closing this period will calculate final totals and prevent new journal entries from being created with dates in this period.",
      "period": "Period:",
      "dateRange": "Date Range:",
      "dateRangeValue": "{start} to {end}",
      "notesLabel": "Closing Notes (optional)",
      "notesPlaceholder": "e.g., Month-end close for March 2026",
      "submit": "Close Period",
      "submitting": "Closing..."
    },
    "lockDialog": {
      "title": "Lock Entries: {period}",
      "warning": "This will permanently lock all journal entries in this period. Locked entries cannot be edited, reversed, or voided.",
      "period": "Period:",
      "entriesToLock": "Entries to Lock:",
      "totalDebits": "Total Debits:",
      "totalCredits": "Total Credits:",
      "net": "Net:",
      "submit": "Lock All Entries",
      "submitting": "Locking..."
    },
    "reopenDialog": {
      "title": "Reopen Period: {period}",
      "warning": "Reopening this period allows new entries to be posted. This may affect previously reported financial statements.",
      "reasonLabel": "Reason for Reopening *",
      "reasonPlaceholder": "e.g., Need to add a missed invoice for March",
      "submit": "Reopen Period",
      "submitting": "Reopening...",
      "yearWarning": "This also voids the sign-off of the financial year {start} to {end}. You will need to close that year again."
    },
    "createDialog": {
      "title": "Create Accounting Period",
      "description": "Select a month to create a new accounting period. The period code, name, and date range will be generated automatically.",
      "monthExists": "{period} already exists",
      "selectMonth": "Select {month} {year}",
      "periodCode": "Period Code:",
      "periodName": "Period Name:",
      "submit": "Create Period",
      "submitting": "Creating..."
    },
    "toast": {
      "closeSuccess": "Period {period} closed successfully",
      "closeError": "Failed to close period",
      "lockSuccess": "Entries in {period} locked successfully",
      "lockError": "Failed to lock entries",
      "reopenReasonRequired": "Please provide a reason for reopening",
      "reopenSuccess": "Period {period} reopened",
      "reopenError": "Failed to reopen period",
      "selectMonthRequired": "Please select a month",
      "createSuccess": "Period {period} created",
      "createError": "Failed to create period"
    },
    "periodName": {
      "months": {
        "january": "January {year}",
        "february": "February {year}",
        "march": "March {year}",
        "april": "April {year}",
        "may": "May {year}",
        "june": "June {year}",
        "july": "July {year}",
        "august": "August {year}",
        "september": "September {year}",
        "october": "October {year}",
        "november": "November {year}",
        "december": "December {year}"
      },
      "shortMonths": {
        "january": "Jan",
        "february": "Feb",
        "march": "Mar",
        "april": "Apr",
        "may": "May",
        "june": "Jun",
        "july": "Jul",
        "august": "Aug",
        "september": "Sep",
        "october": "Oct",
        "november": "Nov",
        "december": "Dec"
      }
    },
    "errors": {
      "periodNotFound": "We couldn't find that period. Refresh the page and try again.",
      "alreadyClosed": "This period is already closed.",
      "notClosed": "Close this period before locking its entries.",
      "alreadyOpen": "This period is already open.",
      "entriesLocked": "This period's entries are locked, so it can't be reopened. Unlock the entries first.",
      "duplicatePeriod": "A period for that month already exists.",
      "financeAdminOnly": "Only an owner or finance admin can open, close or lock accounting periods."
    },
    "review": {
      "title": "Close review",
      "description": "These are your review confirmations. Groot does not automatically reconcile these schedules. Choose not applicable only when the topic does not apply.",
      "bankReconciliation": "Bank reconciliation",
      "receivablesPayables": "Receivables and payables reconciliation",
      "stockValuation": "Stock valuation",
      "accrualsPrepayments": "Accruals and prepayments",
      "depreciation": "Depreciation",
      "foreignExchange": "Revalue foreign balances",
      "trialBalance": "Trial balance",
      "choose": "Choose status",
      "reviewed": "Reviewed",
      "notApplicable": "Not applicable",
      "journals": "Journal entries",
      "required": "Complete every review topic and review the trial balance before closing.",
      "scanIncomplete": "The close review is incomplete because its read limit was reached. Contact support.",
      "scanFailed": "The close review could not finish reading the journals, so nothing was closed. Try again.",
      "ledgerChanged": "A journal was posted or edited while the close review was reading the books, so nothing was closed. Try again.",
      "drafts": "Post or remove draft journals in this period before closing.",
      "unbalanced": "A journal in this period does not balance. Resolve it before closing.",
      "provisionalStock": "Closing stock is provisional. Void the estimate and record a reviewed count before closing.",
      "monthRequired": "Accounting periods must cover one full calendar month with its matching year. Create the correct month before closing. Contact support to correct an older period with different dates.",
      "yearEnd": "Year end",
      "yearEndInfoLabel": "Why this is a year-end step",
      "yearEndInfoForeignExchange": "Foreign-currency balances must be restated at the closing rate at the end of the financial year (MPERS 30.9). In other months it is optional.",
      "yearEndInfoStockValuation": "Closing stock must be counted and valued at the end of the financial year (MPERS 13). In other months it is optional.",
      "skipMonth": "Skip this month",
      "openRevaluation": "Open",
      "fxNothingToRevalue": "The revaluation page found nothing to revalue, so this step is marked not applicable.",
      "yearEndStepRequired": "This is the financial year-end month, so closing stock and foreign balances cannot be skipped. Review them (and revalue any foreign balances) before closing."
    },
    "yearEnd": {
      "title": "Financial year close",
      "description": "Closing a financial year records a sign-off once every month of it is closed. Nothing is posted: the balance sheet already carries the profit of each year forward.",
      "yearLabel": "Financial year {start} to {end}",
      "state": {
        "closed": "Closed",
        "ready": "Ready to close",
        "blocked": "Months still open",
        "voided": "Sign-off voided"
      },
      "blockedMonths": "These months are still open: {months}. Close them first.",
      "readyHint": "Every month of this year is closed.",
      "voidedNote": "The sign-off was voided on {date} because a month of this year was reopened.",
      "voidedClosable": "Every month is closed again. You can close the financial year again.",
      "closedBy": "Closed by {name}",
      "monthsClosed": "Months closed",
      "netProfit": "Profit / (loss) for the year",
      "carriedForward": "Retained profits carried forward",
      "changedFlag": "The carried-forward figure changed: an earlier year was reopened and its profit moved after this year was closed.",
      "adminOnly": "Only an owner or a finance admin can close a financial year.",
      "closeButton": "Close financial year",
      "dialog": {
        "title": "Close financial year",
        "description": "This records that {start} to {end} is closed. Nothing is posted to the ledger.",
        "earlier": "These earlier years are closed first, in order: {years}.",
        "notesLabel": "Note (optional)",
        "submit": "Close financial year",
        "submitting": "Closing..."
      },
      "toast": {
        "closed": "Financial year closed",
        "closedMany": "{count} financial years closed",
        "alreadyClosed": "This financial year is already closed",
        "error": "The financial year could not be closed. Please try again."
      },
      "refusal": {
        "YEAR_END_NOT_ENDED": "This financial year has not ended yet.",
        "YEAR_END_PERIODS_OPEN": "Some months of this year are still open: {months}. Close them first.",
        "YEAR_END_PRIOR_YEAR_OPEN": "An earlier financial year still has open months: {months}. Close them first.",
        "YEAR_END_NO_PERIODS": "This financial year has no accounting periods."
      }
    }
  },
  "chartOfAccounts": {
    "fxAddon": {
      "title": "Multi-currency is an add-on",
      "body": "Foreign-currency bills and invoices, exchange rates and month-end revaluation are not switched on for this business. Everything in your home currency works as normal. Contact us if you would like multi-currency."
    },
    "taxRegistration": {
      "title": "Tax registration",
      "body": "Whether your business is GST or SST registered is a fact about the business, not a chart setting, so the switch lives with your other tax identifiers in Business Profile. Turning it on is what adds the input tax account you designate above.",
      "link": "Open Business Profile"
    },
    "pageTitle": "Chart of Accounts",
    "newAccount": "New Account",
    "views": {
      "accounts": "Accounts",
      "posting": "Payment & posting",
      "balances": "Balances",
      "budgets": "Budgets"
    },
    "accountGroupHeading": "{type} Accounts",
    "accountCount": "{count} accounts",
    "accountTypes": {
      "Asset": "Asset",
      "Liability": "Liability",
      "Equity": "Equity",
      "Revenue": "Revenue",
      "Expense": "Expense"
    },
    "table": {
      "code": "Code",
      "accountName": "Account Name",
      "description": "Description",
      "status": "Status",
      "actions": "Actions",
      "account": "Account",
      "claims": "Expense claims",
      "claimsTooltip": "When ON, the AI may pick this account when it categorises an expense claim. Turning it OFF removes the account from the AI's choices. You can still select it by hand.",
      "invoices": "Purchase invoices",
      "invoicesTooltip": "When ON, the AI may pick this account when it categorises a purchase invoice. Turning it OFF removes the account from the AI's choices. You can still select it by hand.",
      "businessExpenses": "Business expenses",
      "businessExpensesTooltip": "Offer this account when recording a business expense. Independent of the other two: an account can serve claims, purchase invoices and business expenses at once.",
      "budget": "Budget",
      "balance": "Balance"
    },
    "hierarchy": {
      "expand": "Show the sub-accounts of {code}",
      "collapse": "Hide the sub-accounts of {code}",
      "headingBadge": "Heading",
      "headingTooltip": "This account has sub-accounts, so it groups them instead of taking postings. Post to one of its sub-accounts.",
      "rollupLabel": "{count} sub-accounts",
      "addSubAccount": "Add sub-account",
      "createDialogTitle": "Add a sub-account under {code}",
      "createDialogDescription": "The sub-account takes the account type of {code}. Once it exists, {code} becomes a heading and stops taking postings.",
      "createSubAccountAction": "Create Sub-account",
      "parentField": "Parent account",
      "codeParentLocked": "Fixed to the parent account {code}",
      "codeSuffixLabel": "Sub-account code",
      "codeSuffixPlaceholder": "0001",
      "codeSuffixHelp": "{code} is fixed. Type only the part after the dash, for example {example}.",
      "codeSuffixRequired": "Enter the part after the dash, for example {example}.",
      "codeSuffixInvalid": "Use capital letters and numbers only, up to 16 characters, for example {example} or AM001.",
      "codeSuffixNotUppercase": "Sub-account codes use capital letters. Try {suggestion}.",
      "codeSuffixDuplicate": "{code} is already used by {name}. Pick a different sub-account code.",
      "history": {
        "title": "Past entries on {code}",
        "description": "{code} already has {count} posted journal entries. Choose what happens to them before it becomes a heading. Groot will not decide this for you.",
        "checking": "Checking the past entries on {code}.",
        "keepLabel": "Keep them on {code}",
        "keepHelp": "Reports show the {code} balance on its own, plus its sub-accounts rolled up.",
        "moveLabel": "Move them to {code}",
        "moveHelp": "Groot creates {code} General and re-codes {count} existing journal lines to it. No amounts change.",
        "moveBlockedPeriodLocked": "Groot cannot move these entries. The accounting period {periods} is closed, and a closed period must not be rewritten. Keep them on {code}, or reopen that period first.",
        "moveBlockedTooMany": "Groot cannot move these entries. {code} holds more than {max} journal lines, and re-coding that many in one step is not safe. Keep them on {code} instead.",
        "choiceRequired": "Pick one before you create the sub-account."
      },
      "createDialogDescriptionUnderHeading": "The sub-account takes the account type of {code}, which is already a heading."
    },
    "status": {
      "system": "System",
      "active": "Active",
      "inactive": "Inactive"
    },
    "createDialog": {
      "title": "Create New Account",
      "description": "Add a new account to your chart of accounts. Account codes must be unique.",
      "accountCodeHelp": "Must be 4 digits within the selected type range"
    },
    "editDialog": {
      "title": "Edit Account",
      "description": "Update account details. Account code and type cannot be changed."
    },
    "recode": {
      "title": "Recode account",
      "description": "Rename this account's code and move its ledger references with it. The Edit dialog cannot change a code, because 11 tables store it as text.",
      "currentCode": "Current code",
      "newCode": "New code",
      "newCodeHint": "Four digits, optionally with sub-code suffixes: 6100 or 6100-0001.",
      "newName": "Account name",
      "newNameHint": "Posted entries carry the name as it was booked; renaming here relabels them too.",
      "checkImpact": "Check what changes",
      "checking": "Checking…",
      "applying": "Recoding…",
      "confirm": "Rename account",
      "impactLines": "{count} posted entries will be relabelled",
      "impactCategories": "{count} expense categories will point at the new code",
      "impactNote": "Amounts, dates and the trial balance are unchanged.",
      "toast": {
        "success": "Account recoded",
        "error": "Account was not recoded"
      },
      "errors": {
        "accountNotFound": "This account no longer exists. Refresh and try again.",
        "sameCode": "That is already this account's code.",
        "invalidFormat": "That code is not valid. Use four digits, optionally with sub-code suffixes (6100-0001).",
        "codeTaken": "Another account already uses that code. Merging two accounts is not supported here. Deactivate the unused one first, or ask for a chart migration.",
        "headingWithChildren": "This code is the parent of sub-accounts, so renaming it would separate those balances from their parent. Ask for a chart migration.",
        "parentChange": "A sub-account can change its suffix, not its parent. To move it, deactivate this one and create it under the new parent.",
        "undeclaredReferences": "This code is also stored on records a rename cannot safely rewrite. Ask for a chart migration.",
        "tooManyLines": "Too many posted entries use this code for a single rename. Ask for a chart migration.",
        "scanIncomplete": "Not every reference could be checked, so nothing was renamed. Try again, or ask for a chart migration.",
        "unexpected": "The account could not be recoded. Nothing was changed."
      }
    },
    "fields": {
      "accountType": "Account Type",
      "accountCode": "Account Code",
      "accountName": "Account Name",
      "descriptionOptional": "Description (Optional)",
      "normalBalance": "Normal Balance",
      "moneyAccount": "Money account"
    },
    "placeholders": {
      "accountCode": "e.g., 1100",
      "accountName": "e.g., Petty Cash",
      "accountNameSimple": "Account name",
      "description": "Account description"
    },
    "actions": {
      "cancel": "Cancel",
      "createAccount": "Create Account",
      "saveChanges": "Save Changes",
      "edit": "Edit",
      "recode": "Recode",
      "remove": "Remove",
      "restore": "Restore"
    },
    "toast": {
      "createSuccess": "Account created successfully",
      "createError": "Failed to create account",
      "updateSuccess": "Account updated successfully",
      "updateError": "Failed to update account",
      "deactivateSuccess": "Account deactivated successfully",
      "deactivateError": "Failed to deactivate account",
      "deleteSuccess": "Account deleted",
      "deleteError": "Failed to delete account",
      "restoreSuccess": "Account restored",
      "restoreError": "Failed to restore account"
    },
    "confirm": {
      "deactivate": "Are you sure you want to deactivate this account?"
    },
    "defaultAccounts": {
      "cash": {
        "name": "Cash",
        "description": "Cash on hand and in bank accounts."
      },
      "accountsReceivable": {
        "name": "Accounts Receivable",
        "description": "Money owed by customers for sales made on credit."
      },
      "chequeGiroClearing": {
        "name": "Cheque / GIRO Clearing",
        "description": "Temporary holding account for cheque/GIRO receipts before bank clearance."
      },
      "inventory": {
        "name": "Inventory",
        "description": "Goods available for sale."
      },
      "accountsPayable": {
        "name": "Accounts Payable",
        "description": "Money owed to vendors for purchases made on credit."
      },
      "otherPayablesAccruals": {
        "name": "Other Payables & Accruals",
        "description": "Non-trade amounts owed: an expense incurred but not yet paid at period end. Trade purchases belong in Accounts Payable."
      },
      "salesTaxPayable": {
        "name": "Sales Tax Payable",
        "description": "Sales tax collected from customers and owed to government."
      },
      "ownersEquity": {
        "name": "Owner's Equity",
        "description": "Owner's investment in the business."
      },
      "retainedEarnings": {
        "name": "Retained Earnings",
        "description": "Accumulated profits retained in the business."
      },
      "retainedProfits": {
        "name": "Retained Profits / (Accum. Losses)"
      },
      "salesRevenue": {
        "name": "Sales Revenue",
        "description": "Income from primary business operations."
      },
      "otherIncome": {
        "name": "Other Income",
        "description": "Income from non-primary activities."
      },
      "costOfGoodsSold": {
        "name": "Direct Production Costs",
        "description": "Direct costs of producing goods sold."
      },
      "operatingExpenses": {
        "name": "Operating Expenses",
        "description": "General business expenses."
      },
      "platformFees": {
        "name": "Platform Fees",
        "description": "Fees charged by e-commerce platforms."
      },
      "otherExpenses": {
        "name": "Other Expenses",
        "description": "Non-primary expenses."
      },
      "inventoryAdjustments": {
        "name": "Inventory Adjustments",
        "description": "Gains/losses from inventory adjustments (stocktake, damage, etc.)."
      },
      "currentAssets": {
        "name": "Current Assets"
      },
      "tradeDebtors": {
        "name": "Trade Debtors"
      },
      "otherDebtors": {
        "name": "Other Debtors"
      },
      "bank": {
        "name": "Bank"
      },
      "primaryBankAccount": {
        "name": "Primary Bank Account"
      },
      "cashInHand": {
        "name": "Cash In Hand"
      },
      "deposits": {
        "name": "Deposits"
      },
      "prepayments": {
        "name": "Prepayments"
      },
      "salesSettlementClearing": {
        "name": "Sales Settlement Clearing"
      },
      "transfersInTransit": {
        "name": "Transfers in Transit"
      },
      "fixedAssets": {
        "name": "Fixed Assets"
      },
      "furnitureFittings": {
        "name": "Furniture & Fittings"
      },
      "shopEquipment": {
        "name": "Shop Equipment"
      },
      "computerEquipment": {
        "name": "Computer Equipment"
      },
      "accumDepreciationFurnitureFittings": {
        "name": "Accum. Depreciation - Furniture & Fittings"
      },
      "accumDepreciationShopEquipment": {
        "name": "Accum. Depreciation - Shop Equipment"
      },
      "accumDepreciationComputerEquipment": {
        "name": "Accum. Depreciation - Computer Equipment"
      },
      "currentLiabilities": {
        "name": "Current Liabilities"
      },
      "tradeCreditors": {
        "name": "Trade Creditors"
      },
      "otherCreditors": {
        "name": "Other Creditors"
      },
      "accruals": {
        "name": "Accruals"
      },
      "statutoryPayables": {
        "name": "Statutory Payables"
      },
      "equity": {
        "name": "Equity"
      },
      "shareCapital": {
        "name": "Share Capital"
      },
      "profitLossAccount": {
        "name": "Profit & Loss Account"
      },
      "sales": {
        "name": "Sales"
      },
      "creditSales": {
        "name": "Credit Sales"
      },
      "cashSales": {
        "name": "Cash Sales"
      },
      "discountAllowed": {
        "name": "Discount Allowed"
      },
      "costOfSales": {
        "name": "Cost of Goods Sold"
      },
      "creditPurchase": {
        "name": "Credit Purchase"
      },
      "cashPurchase": {
        "name": "Cash Purchase"
      },
      "materialsSupplies": {
        "name": "Materials & Supplies"
      },
      "packagingMaterials": {
        "name": "Packaging Materials"
      },
      "freightDutiesImportCharges": {
        "name": "Freight, Duties & Import Charges"
      },
      "distributionDeliveryCosts": {
        "name": "Distribution & Delivery Costs"
      },
      "outsourcedServices": {
        "name": "Outsourced Services"
      },
      "platformServiceFees": {
        "name": "Platform & Service Fees"
      },
      "otherCostOfSales": {
        "name": "Other Cost of Sales"
      },
      "purchaseReturn": {
        "name": "Purchase Return"
      },
      "otherNonOperatingExpenses": {
        "name": "Other Non-Operating Expenses"
      },
      "expenses": {
        "name": "Expenses"
      },
      "accountingFee": {
        "name": "Accounting Fee"
      },
      "auditFee": {
        "name": "Audit Fee"
      },
      "bankCharges": {
        "name": "Bank Charges"
      },
      "cleaningSanitation": {
        "name": "Cleaning & Sanitation"
      },
      "commission": {
        "name": "Commission"
      },
      "deliveryCourier": {
        "name": "Delivery & Courier"
      },
      "entertainmentHospitality": {
        "name": "Entertainment & Hospitality"
      },
      "insurance": {
        "name": "Insurance"
      },
      "itSoftware": {
        "name": "IT & Software"
      },
      "licencesPermits": {
        "name": "Licences & Permits"
      },
      "marketingAdvertising": {
        "name": "Marketing & Advertising"
      },
      "medicalExpenses": {
        "name": "Medical Expenses"
      },
      "officeSupplies": {
        "name": "Office Supplies"
      },
      "printingStationery": {
        "name": "Printing & Stationery"
      },
      "professionalFees": {
        "name": "Professional Fees"
      },
      "rentalLease": {
        "name": "Rental & Lease"
      },
      "repairsMaintenance": {
        "name": "Repairs & Maintenance"
      },
      "secretarialFee": {
        "name": "Secretarial Fee"
      },
      "securitySafety": {
        "name": "Security & Safety"
      },
      "smallToolsEquipment": {
        "name": "Small Tools & Equipment"
      },
      "staffWelfare": {
        "name": "Staff Welfare"
      },
      "telecommunications": {
        "name": "Telecommunications"
      },
      "trainingDevelopment": {
        "name": "Training & Development"
      },
      "travelTransportation": {
        "name": "Travel & Transportation"
      },
      "utilities": {
        "name": "Utilities"
      },
      "employeeBenefits": {
        "name": "Employee Benefits"
      },
      "salaries": {
        "name": "Salaries"
      },
      "wages": {
        "name": "Wages"
      },
      "bonus": {
        "name": "Bonus"
      },
      "allowance": {
        "name": "Allowance"
      },
      "eisContribution": {
        "name": "EIS Contribution"
      },
      "epfContribution": {
        "name": "EPF Contribution"
      },
      "socsoContribution": {
        "name": "SOCSO Contribution"
      },
      "cpfContribution": {
        "name": "CPF Contribution"
      },
      "sdlContribution": {
        "name": "SDL Contribution"
      },
      "depreciationOfFixedAssets": {
        "name": "Depreciation of Fixed Assets"
      },
      "amortisationOfIntangibleAssets": {
        "name": "Amortisation of Intangible Assets"
      },
      "impairmentLosses": {
        "name": "Impairment Losses"
      },
      "inventoryWriteDowns": {
        "name": "Inventory Write-downs"
      },
      "otherOperatingExpenses": {
        "name": "Other Operating Expenses"
      },
      "inputGstRecoverable": {
        "name": "Input GST Recoverable"
      },
      "inputVat": {
        "name": "進項稅額 (Input VAT)"
      },
      "outputVat": {
        "name": "銷項稅額 (Output VAT)"
      },
      "relatedPartyPayables": {
        "name": "Amounts Owing to Related Parties"
      },
      "openingBalanceEquity": {
        "name": "Opening Balance Equity"
      },
      "affiliateCommission": {
        "name": "Affiliate Commission"
      },
      "realisedFxGain": {
        "name": "Realised Foreign Exchange Gain"
      },
      "realisedFxLoss": {
        "name": "Realised Foreign Exchange Loss"
      },
      "unrealisedFxGain": {
        "name": "Unrealised Foreign Exchange Gain"
      },
      "unrealisedFxLoss": {
        "name": "Unrealised Foreign Exchange Loss"
      },
      "hrdf": {
        "name": "HRDF Contribution",
        "description": "Employer HRDF levy on eligible Malaysian employees. Never withheld from employee wages."
      }
    },
    "notACategory": "—",
    "search": {
      "placeholder": "Search accounts by code or name…",
      "noMatch": "No accounts match your search."
    },
    "picker": {
      "listLabel": "GL accounts",
      "headingNotSelectable": "This is a heading. Pick one of the accounts under it."
    },
    "emptyState": {
      "title": "No accounts yet",
      "description": "Import your Chart of Accounts or add an account to get started.",
      "onboardingPendingTitle": "Finishing your chart",
      "onboardingPendingDescription": "Your onboarding is confirmed. We are adding the accounts your business needs now.",
      "onboardingFailedTitle": "Your chart still needs finishing",
      "onboardingFailedDescription": "Your business was created, but its starter accounts were not added. Try again to finish setup.",
      "onboardingRetry": "Finish setup",
      "onboardingRetryQueued": "Setup restarted",
      "onboardingRetryFailed": "We could not restart setup. Try again."
    },
    "budgets": {
      "title": "Monthly budgets",
      "subtitle": "Set a monthly spending limit per category, in {currency}.",
      "loading": "Loading budgets…",
      "emptyTitle": "No expense categories yet",
      "emptyDescription": "Add an expense account first, then set its monthly budget here.",
      "noBudget": "No budget set",
      "save": "Save",
      "saved": "Budget saved",
      "removed": "Budget removed",
      "saveError": "Couldn't save the budget. Please try again.",
      "invalidAmount": "Enter a positive amount, or 0 to remove the budget.",
      "inputPlaceholder": "No limit",
      "inputAria": "Monthly budget for {category}",
      "spendOfLimit": "{spend} of {limit}",
      "statusOnTrack": "On track",
      "statusWarning": "Warning",
      "statusOverspent": "Overspent",
      "cap": {
        "label": "Cap",
        "inputPlaceholder": "No cap",
        "inputAria": "Policy cap for {category}",
        "help": "Flags claims over this amount at approval (separate from the monthly budget).",
        "saved": "Cap saved",
        "removed": "Cap removed",
        "saveError": "Couldn't save the cap. Please try again.",
        "invalidAmount": "Enter a positive amount, or 0 to remove the cap.",
        "readOnly": "Cap: {amount}"
      },
      "autoApprove": {
        "label": "Auto-approve at or below",
        "inputPlaceholder": "No auto-approve",
        "inputAria": "Auto-approve threshold for {category}",
        "help": "Claims at or below this amount with a receipt are approved automatically (no human review). Leave blank to require approval.",
        "saved": "Auto-approve threshold saved",
        "removed": "Auto-approve threshold removed",
        "saveError": "Couldn't save the auto-approve threshold. Please try again.",
        "invalidAmount": "Enter a positive amount, or 0 to remove the threshold.",
        "readOnly": "Auto-approve at or below: {amount}"
      },
      "summary": {
        "totalBudgeted": "Total budgeted",
        "totalSpent": "Spent this period",
        "overBudget": "Over budget",
        "inWarning": "In warning"
      },
      "movedNotice": "These amounts are now set in Settings → Approvals, beside the switches that turn them on. Shown here for reference.",
      "movedLink": "Open spend control",
      "errors": {
        "permission": "You don't have permission to change spend controls. Ask an owner or finance admin.",
        "missing": "We couldn't find that category. It may have been renamed or removed. Refresh and try again."
      }
    },
    "removeDialog": {
      "title": "Remove account",
      "intro": "Choose how to remove “{name}”. Archiving hides it from new selections but keeps its history; deleting removes it permanently.",
      "archiveLabel": "Archive",
      "archiveHint": "Hide from new selections, keep history.",
      "deleteLabel": "Delete",
      "deleteHint": "Permanently remove. Can’t be undone.",
      "deleteBlockedHistory": "Can’t delete: has {count} posted entries.",
      "deleteBlockedLinked": "Can’t delete: still linked to a category or bank account.",
      "bothBlockedPostingTarget": "This account is used by automated bookkeeping. Reassign that role in Posting accounts settings before removing it.",
      "archivedAlready": "This account is already archived.",
      "deleteTitle": "Delete account?",
      "archiveTitle": "Archive account?",
      "checking": "Checking this account…",
      "hasHistory": "This account has {count} posted journal entries. It can’t be deleted (that would destroy audit history). Archive it instead to remove it from new selections while keeping its history.",
      "isPostingTarget": "This account is used by automated bookkeeping. Reassign that role to another account in the Posting accounts settings before removing it.",
      "isLinked": "This account is the GL target of an active category or a bank account. Remove that link before deleting, or archive the account instead to keep it out of new selections.",
      "confirmDelete": "Permanently delete “{name}”? This can’t be undone.",
      "deleteAction": "Delete",
      "archiveAction": "Archive"
    },
    "postingAccounts": {
      "badgeArchived": "Archived",
      "badgeMissing": "No account",
      "badgeNotSet": "Not set",
      "badgeOptional": "Optional",
      "badgeNotUsed": "Not used",
      "summaryOkExceptOptional": "All {total} required posting accounts are set. {names} is not set, so a payment from it will be refused until you pick an account.",
      "badgeHeading": "Heading",
      "cashAccountsEmpty": "Nothing picked yet. Recording a cash payment offers only your default cash account.",
      "methodAccountsEmpty": "Nothing picked yet, so this payment method offers no account when recording a payment.",
      "summaryAttention": "{count, plural, one {# of {total} needs attention} other {# of {total} need attention}}",
      "summaryAttentionDetail": "These rows point at an account your chart does not hold, or at an archived one, so Groot cannot post to them yet.",
      "summaryHidden": "{count, plural, one {# of them is behind the Show more accounts toggle.} other {# of them are behind the Show more accounts toggle.}}",
      "summaryJump": "Go to {label}",
      "summaryJumpAria": "Go to {label}, the first account that needs attention",
      "summaryOk": "All {total} posting accounts point at an active account in your chart.",
      "summaryOkApplicable": "All {total} posting accounts that apply to your business point at an active account in your chart.",
      "summaryOkBadge": "All set",
      "title": "Posting accounts",
      "subtitle": "The accounts Groot posts to on its own, so nobody has to choose one every time. Accountants call these your control accounts. An account chosen here cannot be deleted until you point the setting at a different one.",
      "ap": "Accounts Payable",
      "apDesc": "What the business owes suppliers (credited when a supplier invoice is posted for later payment, debited when you pay it). Approving an expense claim does not raise a payable here.",
      "bank": "Default bank account",
      "bankDesc": "The bank account Groot uses when nobody picks one: customer receipts, supplier payments, reimbursements, and cheque or GIRO amounts once they clear.",
      "cash": "Cash on hand",
      "cashDesc": "Notes and coins in the till, or a petty cash float. Set this if you pay for things in cash, so cash appears as somewhere to pay from. Leave it empty if you do not.",
      "bankSections": "Bank & cheque",
      "bankSectionsDesc": "Select a heading to include every account under it, or select individual accounts.",
      "bankSectionsUnset": "Nothing picked yet. Until you pick something, recording a payment offers only your default bank account, so a second bank cannot be chosen.",
      "bankSectionsNoAssets": "No active asset accounts in your chart yet.",
      "bankSectionsDeriveOffer": "Your chart identifies {sections} as the bank section. Use this selection?",
      "bankSectionsDeriveOfferLikely": "It looks like your bank accounts are under {sections}. Use this selection if that is correct.",
      "bankSectionsDeriveApply": "Use {sections}",
      "roleOptionUsedBy": "{code} {name} (already your {role} account)",
      "ar": "Accounts Receivable",
      "arDesc": "What customers owe (debited when a sales invoice is issued, credited when payment is received).",
      "accrual": "Accruals",
      "accrualDesc": "Costs already incurred but not yet invoiced, such as utilities or rent (credited when you record a bill before paying it, debited when you pay it). Kept apart from Accounts Payable so supplier aging shows only what suppliers are chasing.",
      "prepayment": "Prepayments",
      "prepaymentDesc": "Costs paid before the period they belong to, such as rent or insurance paid in advance (debited when you pay early, released to the expense as the cost is recognised). The paid-early mirror of Accruals.",
      "payrollExpense": "Employee benefits expense",
      "payrollExpenseDesc": "Debited with the whole wage bill when you post a pay run: gross pay plus the employer's own statutory contributions, as one figure. Kept as a single account because IFRS 18 reports employee benefits as one by-nature line.",
      "statutoryPayable": "Statutory payables",
      "statutoryPayableDesc": "Credited with the EPF, SOCSO, EIS and PCB you withhold on payday, and with net pay you have not transferred yet, then debited when you remit or pay it out. Kept apart from Accounts Payable so supplier aging shows only what suppliers are chasing.",
      "choose": "Choose an account",
      "saveError": "Couldn’t save the posting accounts. Please try again.",
      "sales": "Sales revenue",
      "salesDesc": "Credited when a sales invoice is issued.",
      "cogs": "Cost of goods sold",
      "cogsDesc": "Debited when stock is sold or consumed.",
      "inventory": "Inventory",
      "inventoryDesc": "Stock on hand; moved when goods are received or sold.",
      "chequeGiroClearing": "Cheque / GIRO clearing",
      "chequeGiroClearingDesc": "Holds post-dated cheque/GIRO receipts until they clear the bank.",
      "salesSettlementClearing": "Sales settlement clearing",
      "salesSettlementClearingDesc": "Holds daily POS and platform sales until their bank settlement is reconciled.",
      "outputTax": "Output tax (on sales)",
      "outputTaxDesc": "Tax collected on sales invoices (e.g. SST/VAT payable).",
      "inputTax": "Input tax (on purchases)",
      "inputTaxDesc": "Tax paid on purchases you can reclaim.",
      "inputTaxDescMy": "Tax paid on purchases. Malaysian SST is not generally reclaimable, so post only genuinely recoverable or deductible SST here.",
      "platformFees": "Platform fees",
      "platformFeesDesc": "Marketplace commission and selling fees deducted from payouts.",
      "marketingAdvertising": "Marketing and advertising",
      "marketingAdvertisingDesc": "Advertising and promotional charges deducted by sales platforms.",
      "otherIncome": "Other income",
      "otherIncomeDesc": "Credited when a settlement pays more than the order value.",
      "otherExpense": "Other expense",
      "otherExpenseDesc": "Debited when a settlement pays less than the order value.",
      "depreciationExpense": "Depreciation expense",
      "depreciationExpenseDesc": "Debited each month when a scheduled depreciation run posts, for every registered fixed asset that has not yet been fully depreciated or disposed.",
      "openingBalanceEquity": "Opening balance equity",
      "openingBalanceEquityDesc": "Where a migration cutover parks the difference when the opening trial balance you bring in does not foot, as a visible unreconciled opening difference you can clear later. Kept apart from share capital so a migration artefact is never read as money the owners put in.",
      "showAdvanced": "Show {count} more accounts",
      "hideAdvanced": "Hide {count} more accounts",
      "advancedSetCount": "{count} changed",
      "errors": {
        "invalidAccount": "That account can't be used for this role. This role needs an active account of the right type that takes postings directly. Pick another.",
        "belongsToAnotherRole": "That account is already set up as another job on this screen, such as Accounts Receivable or Inventory, or it sits inside or around one. A bank or cash account can't be one of those. Pick one of your own bank or cash accounts.",
        "partyAccount": "That is one supplier's or customer's own account, so it can't be this control account. Groot gives each supplier and customer an account of their own under it automatically. Leave this setting on the main account.",
        "hasSubAccounts": "That account has other accounts under it, so it can't take postings itself. Pick one that takes postings directly."
      },
      "rolesHeading": "One account for each job",
      "rolesIntro": "Groot posts to these without asking. Pick one account per row.",
      "groups": {
        "partners": "Customers and suppliers",
        "money": "Bank and cash",
        "trading": "Sales and stock",
        "payroll": "Payroll",
        "inTransit": "Money in transit",
        "tax": "Tax",
        "marketplace": "Marketplace and settlement",
        "foreignExchange": "Foreign exchange",
        "migration": "Opening balances",
        "fixedAssets": "Fixed assets"
      },
      "state": {
        "missing": "Account {code} is not in your chart, so nothing can post here yet. Pick an account.",
        "archived": "Account {code} is archived, so it cannot take postings. Pick an active account.",
        "inferredPrompt": "Suggested: {code} {name}.",
        "partyLedgerAp": "{count, plural, =0 {Each supplier gets its own account under {control}.} other {Each supplier has its own account under {control} ({count}).}} Bills post to the supplier's account.",
        "partyLedgerAr": "{count, plural, =0 {Each customer gets its own account under {control}.} other {Each customer has its own account under {control} ({count}).}} Invoices post to the customer's account.",
        "confirmInferred": "Confirm",
        "confirmInferredAria": "Confirm that {label} posts to {code}",
        "notSetOptional": "Not set. Cash will not be offered as somewhere to pay from until you pick an account.",
        "notUsedSst": "Tax paid on purchases is part of the cost under SST, so Groot does not post to this account.",
        "notUsedGst": "This business is not registered for GST, so GST paid on purchases is part of the cost and Groot does not post to this account. It is set up when you register for GST.",
        "heading": "Account {code} has sub-accounts, so it is a heading and cannot take postings. Pick one of its sub-accounts.",
        "clear": "Clear",
        "clearAria": "Clear the {label} account"
      },
      "bankSectionsKind": "Choose the bank accounts available for bank transfers and cheques.",
      "bankSectionsFilterPlaceholder": "Filter by code or name",
      "accountListAbout": "About this setting",
      "accountListNone": "Choose accounts",
      "accountListSelected": "{count} selected",
      "accountListNoMatches": "No matching accounts",
      "methodAccountsTitle": "Accounts available by payment method",
      "methodAccountsSubtitle": "Choose what appears in Pay from account and Deposit to account when recording a payment.",
      "methodAccountsHelp": "These lists control what users can choose. They do not change the default posting accounts above.",
      "cashAccounts": "Cash",
      "cashAccountsHelp": "Choose the cash heading or individual cash accounts available for AP payments and AR receipts. Cash on hand remains the default.",
      "outgoingCardAccounts": "Card · paid out",
      "outgoingCardAccountsHelp": "Bank assets work for debit cards. Liability accounts work for corporate cards, amounts due to a director, or personal-card reimbursements.",
      "incomingCardAccounts": "Card · received",
      "incomingCardAccountsHelp": "Choose Asset accounts that receive card settlements. Liability accounts are never offered for customer receipts.",
      "outgoingOtherAccounts": "Other · paid out",
      "outgoingOtherAccountsHelp": "Choose the Asset or Liability accounts allowed for outgoing payments classified as Other.",
      "incomingOtherAccounts": "Other · received",
      "incomingOtherAccountsHelp": "Choose the Asset accounts allowed for incoming receipts classified as Other.",
      "bankSectionsInside": "{count} inside",
      "bankSectionsBlockedIs": "{code} {name} is your {role} account, so it cannot hold bank accounts.",
      "bankSectionsBlockedContains": "{code} {name} contains your {role} account ({otherCode}). Picking it would offer that account as a bank. Pick the heading your banks sit under instead.",
      "bankSectionsSelectedBlocked": "{code} {name} is your {role} account and it is still picked, so it appears in the bank list when recording a payment. Remove it.",
      "bankSectionsRemove": "Remove {code}",
      "noBank": {
        "title": "No bank account can take a payment",
        "impact": "Every screen that records a payment offers no bank account to choose from, so nobody can say which bank the money moved through.",
        "missing": "Account {code} is not in your chart, so nothing can post there. Set {role} to an account you have, on this screen.",
        "archived": "{code} {name} is archived, so nothing can post there. Make it active again in your chart of accounts, or set {role} to an active account on this screen.",
        "heading": "{code} {name} has sub-accounts, so it is a heading and nothing can post there. Set {role} to one of its sub-accounts on this screen.",
        "headingExample": "{code} {name} has sub-accounts, so it is a heading and nothing can post there. Set {role} to one of its sub-accounts, such as {childCode} {childName}, on this screen.",
        "wrongType": "{code} {name} is not an asset account, so money cannot move through it. Set {role} to a bank or cash account on this screen.",
        "unknown": "No account in your chart can take a bank payment. Check {role} on this screen, and check which bank accounts you can choose from."
      },
      "preview": {
        "title": "What the bank list will show",
        "body": "Read back from your saved settings, using the same query the payment screens use.",
        "defaultBadge": "Default",
        "empty": "Nothing yet. Pick where your bank accounts live above.",
        "emptyDiagnosedAbove": "Nothing yet, and picking a section above will not change that. The warning at the top of this card names the account and the fix.",
        "outsideDefault": "Your default bank account ({code} {name}) is not one of the accounts above. Automated postings still use it. If your money actually moves through one of the accounts above, set that one as the default bank account."
      },
      "section": {
        "inferred": "Suggested from {heading}: {code} {name}.",
        "inSectionGroup": "Under {heading}",
        "otherGroup": "Other accounts"
      },
      "otherCreditor": "Other creditors",
      "otherCreditorDesc": "Where an invoiced non-trade bill sits until you pay it: utilities, rent, professional fees. Separate from Accruals, which is for costs you have incurred but not yet been invoiced for.",
      "relatedPartyPayable": "Amounts owing to related parties",
      "relatedPartyPayableDesc": "Money owed to directors, shareholders, or businesses under common control. Disclosed separately from trade and other creditors.",
      "affiliateCommission": "Affiliate commission",
      "affiliateCommissionDesc": "The cost of sales account that AffiliateWP commissions are billed to. It must be a cost of sales account, never an operating expense.",
      "affiliateCommissionNotSet": "Not set. AffiliateWP commissions will wait as Held until you pick a cost of sales account.",
      "realisedFxGain": "Realised foreign exchange gain",
      "realisedFxLoss": "Realised foreign exchange loss",
      "unrealisedFxGain": "Unrealised foreign exchange gain",
      "unrealisedFxLoss": "Unrealised foreign exchange loss",
      "realisedFxGainDesc": "The income account for the gain when a foreign-currency bill or invoice is settled at a better rate than the one it was recorded at. Kept apart from the unrealised gain.",
      "realisedFxLossDesc": "The expense account for the loss when a foreign-currency bill or invoice is settled at a worse rate than the one it was recorded at. Kept apart from the unrealised loss.",
      "unrealisedFxGainDesc": "The income account for the gain when open foreign-currency balances are restated at the period-end rate. Not settled yet, so kept apart from the realised gain.",
      "unrealisedFxLossDesc": "The expense account for the loss when open foreign-currency balances are restated at the period-end rate. Not settled yet, so kept apart from the realised loss.",
      "fxRealisedNotSet": "Not set. The standard account is created for you the first time a foreign-currency payment needs it.",
      "fxUnrealisedNotSet": "Not set. It is only needed once foreign-currency balances are revalued at period end.",
      "hrdfExpense": "HRDF employer expense",
      "hrdfExpenseDesc": "Employer HRDF levy, kept apart from wages and other statutory contributions. Its credit uses Statutory Payables."
    },
    "autosave": {
      "saving": "Saving…",
      "saved": "Saved",
      "failed": "Not saved",
      "retry": "Retry",
      "savedAt": "Saved"
    },
    "columns": {
      "showAdvanced": "Show advanced columns",
      "hideAdvanced": "Hide advanced columns",
      "showArchived": "Show archived accounts",
      "hideArchived": "Hide archived accounts"
    },
    "rowDetails": {
      "show": "Show the settings for {code}",
      "hide": "Hide the settings for {code}",
      "tooltip": "Budget, expense claims and purchase invoices for this account",
      "noDescription": "No description",
      "headingNote": "{code} groups its sub-accounts, so it takes no postings.",
      "expenseOnlyNote": "Only expense accounts receive expense claims and purchase invoices.",
      "addSubAccountLabel": "Add a sub-account under {code}"
    },
    "subAccountOption": {
      "checkboxLabel": "This is a sub-account of",
      "pickerPlaceholder": "Choose the parent account",
      "parentRequired": "Pick the parent account to continue.",
      "consequence": "Code becomes {code}. {parent} turns into a heading and stops taking postings.",
      "typeLocked": "A sub-account always takes the account type of its parent.",
      "noParents": "No account can take a sub-account yet. Create a four-digit account first.",
      "consequenceUnderHeading": "Code becomes {code}. {parent} is already a heading, so nothing about it changes."
    },
    "howItWorks": {
      "title": "How the chart of accounts works",
      "introHeading": "What the chart of accounts is",
      "introBody": "The chart of accounts is the list of buckets your money moves through. Every sale, bill, payment and receipt lands in one of them, and your reports are those buckets added up. Groot gives you a standard list to start with. Rename, add or archive accounts so it matches how you actually run the business.",
      "subAccountsHeading": "Sub-accounts, and why you would want one",
      "subAccountsBody": "A plain account tells you how much. A sub-account tells you which one. Fixed Assets can tell you that you spent 12,000 on equipment, but it cannot tell you how much of that was the air conditioner and how much was the furniture. Add Air conditioner and Furniture as sub-accounts of Fixed Assets, and each one carries its own balance while Fixed Assets keeps showing the total.",
      "subAccountsHow": "There are two ways to add one. Press the folder icon on any row in the table, or tick This is a sub-account of in the New Account dialog and choose the parent.",
      "headingsHeading": "Headings",
      "headingsBody": "The moment an account gets its first sub-account it becomes a heading. A heading groups the accounts under it and reports their total, and it stops taking postings. That is on purpose. If both Fixed Assets and Air conditioner could take an entry, the same money could be recorded in two places and the total would count it twice. Post to the sub-account instead.",
      "controlHeading": "Control accounts",
      "controlBody": "A control account is the account Groot posts to on its own, so nobody has to pick one. When an invoice goes out, a bill is approved or a payment is recorded, Groot already knows where it belongs.",
      "controlRoles": "The roles are accounts receivable, accounts payable, default bank account, cash on hand, sales revenue, cost of goods sold, inventory, cheque and GIRO clearing, sales settlement clearing, output tax, input tax, platform fees, other income and other expense.",
      "controlNoSubAccounts": "A control account cannot have sub-accounts. Giving it one turns it into a heading, a heading takes no postings, and Groot would then have nowhere to post. If you need that level of detail, leave the control account as it is and put the sub-accounts under a different account.",
      "controlWhere": "You choose them on the Posting accounts screen, which the link below opens.",
      "settingsLink": "Open posting account settings",
      "tipsHeading": "Tips",
      "tipRollup": "The balance on a heading row is the total of everything beneath it, which is the figure your statements have to agree with.",
      "tipAdvanced": "Show advanced columns brings back budgets and the expense claim and purchase invoice switches for every row. To see them for one account only, press the sliders icon on that row.",
      "tipRemove": "Archiving an account keeps its history and hides it from new selections. Deleting is only offered when an account has never been used.",
      "controlBankSections": "Two of these settings look alike and are not. A control account is the one account Groot posts to. Where your bank accounts live is a list of places to look, so the right banks appear in the dropdown when you record a payment."
    },
    "normalBalance": {
      "debit": "Debit",
      "credit": "Credit",
      "lockedToParent": "A sub-account sits on the same side of the ledger as {code}.",
      "usualHelp": "The usual side for a {type} account. Leave this alone unless you are creating a contra account.",
      "contraHelp": "This is a contra {type} account: it will be presented as a deduction from the accounts it belongs to, like accumulated depreciation under fixed assets.",
      "contraBadge": "Contra",
      "contraTooltip": "A contra account. This {type} account carries a {side} balance, so it reduces the total it sits under instead of adding to it."
    },
    "errors": {
      "accountNotFound": "We couldn't find that account. It may have been removed. Refresh the page and try again.",
      "accountHasHistory": "This account already has posted entries, so deleting it would destroy your audit history. Archive it instead. An archived account stays out of new entries and keeps everything already recorded.",
      "accountIsPostingTarget": "Automated bookkeeping posts to this account. Point that role at a different account in Accounting → Chart of Accounts first, then remove this one.",
      "accountIsGlTarget": "This account is still linked to a category or a bank account. Unlink it there first, or archive it instead to keep it out of new entries.",
      "duplicateAccountCode": "That account code is already used. Pick a different code.",
      "postedCashScopeImmutable": "This account already has posted entries, so its Money account choice cannot change. Use a new chart account for future postings.",
      "moneyAccountInherited": "Sub-accounts inherit their parent’s Money account choice. Use a standalone account to choose a different one.",
      "moneyAccountLeafOnly": "Choose a standalone Asset account without sub-accounts or another classification for Bank / Cash.",
      "moneyAccountChanged": "This account’s classification changed while you were editing. Close and reopen the dialog to review the current choice."
    },
    "namedSibling": {
      "legend": "How should this account be numbered?",
      "nestedLabel": "Numbered under the parent",
      "nestedHelp": "Code becomes {example}. {parent} turns into a heading.",
      "namedLabel": "Named account beside the parent",
      "namedHelp": "Code becomes {example}, taking its letter from the account name. Banks and customer accounts are numbered this way, and the total on {parent} still includes it.",
      "derivedHelp": "Groot builds this code from the account name below, so the code and the name always agree. Renaming the account later keeps the code it was first issued.",
      "needsName": "Type the account name first, because the code is built from its first letter.",
      "duplicate": "{code} already belongs to another account. Adjust the account name.",
      "nestedHelpUnderHeading": "Code becomes {example}, under the heading {parent}."
    },
    "moneyAccount": {
      "none": "Not a bank or cash account",
      "cash": "Cash",
      "bank": "Bank",
      "help": "Cash and Bank accounts appear in Bank / Cash and can receive an Official Receipt."
    }
  },
  "salesOrderListCard": {
    "quotationsTitle": "Quotations",
    "columns": {
      "number": "Number",
      "customer": "Customer",
      "date": "Date",
      "status": "Status",
      "total": "Total",
      "toDeliver": "To deliver"
    }
  },
  "invoiceListCard": {
    "supplierTitle": "Supplier invoices",
    "salesTitle": "Sales invoices",
    "overdueTitle": "Overdue invoices",
    "totalOutstanding": "Total outstanding",
    "columns": {
      "supplier": "Supplier",
      "customer": "Customer",
      "invoice": "Invoice",
      "date": "Date",
      "dueDate": "Due date",
      "daysOverdue": "Days overdue",
      "amount": "Amount",
      "outstanding": "Outstanding",
      "posted": "Posted",
      "status": "Status"
    }
  },
  "changeHistoryCard": {
    "columns": {
      "when": "When",
      "document": "Document",
      "who": "Changed by",
      "what": "Type",
      "why": "Basis",
      "reason": "Reason",
      "changed": "Changed fields",
      "origin": "Origin"
    },
    "partialTitle": "Change history of the owning record, may be incomplete"
  },
  "cashBook": {
    "direct": {
      "title": "Receive, pay or transfer",
      "description": "Plan a direct bank or cash movement. Check the source and tax treatment before posting.",
      "reviewOnly": "Review only",
      "kind": "Movement type",
      "purpose": "What happened?",
      "bankInterest": "Earned bank interest",
      "bankCharge": "Bank charge",
      "directExpense": "Other direct expense",
      "ownTransfer": "Between our accounts",
      "receivePurposeGuide": "Customer payments and sales receipts belong to Sales. Unknown credits stay under review.",
      "payPurposeGuide": "Bills, claims and other expenses with an owning source must be paid there.",
      "transferPurposeGuide": "Both accounts must belong to this business and use the same currency.",
      "offsetSetupHold": "A compatible income or expense account and tax review must be confirmed before posting.",
      "transitSetupHold": "A reviewed transit account is needed until the destination value date is confirmed.",
      "transferAccountHold": "Both owned accounts and value dates must be verified before posting.",
      "receive": "Receive",
      "pay": "Pay",
      "transfer": "Transfer",
      "account": "Bank or cash account",
      "fromAccount": "From account",
      "toAccount": "To account",
      "chooseAccount": "Choose an account",
      "amount": "Amount",
      "valueDate": "Value date",
      "outgoingDate": "Outgoing value date",
      "incomingDate": "Incoming value date, when known",
      "reference": "Evidence or reference",
      "accountRequired": "Choose the account that moves money.",
      "destinationRequired": "Choose a different destination account.",
      "amountRequired": "Enter a positive amount with up to two decimal places.",
      "dateRequired": "Enter the evidenced value date.",
      "incomingDateRequired": "The incoming date must be on or after the outgoing date.",
      "referenceRequired": "Add the bank advice or source reference.",
      "sameDayPreview": "Same-day transfer: one balanced posting between the two accounts.",
      "transitPreview": "Different value dates: the outgoing amount stays in transit until the destination is confirmed.",
      "awaitingDestinationPreview": "If the incoming date is not yet evidenced, the transfer remains awaiting destination.",
      "reviewDetails": "Review details",
      "taxDocument": "Bank tax document",
      "ordinaryStatement": "Ordinary bank statement",
      "bankIssuedDocument": "Bank-issued validated e-Invoice",
      "feeNote": "Bank fee note",
      "taxChoiceGuide": "Record what you have; this choice does not approve tax treatment.",
      "bankEvidence": "Imported bank line",
      "chooseBankEvidence": "Choose the matching bank line",
      "evidenceRequired": "Choose an imported line for this account and amount.",
      "evidenceListIncomplete": "Only recent unmatched lines are shown. Open Bank Reconciliation for older lines.",
      "holdTaxFacts": "Tenant tax facts still need review.",
      "holdTaxDocument": "The bank document and tax decision still need review.",
      "holdBrowser": "Browser confirmation and source checks are still pending.",
      "holdEvidence": "The selected bank evidence no longer matches. Choose a current line.",
      "confirmDisabled": "Posting unavailable",
      "browserConfirmed": "Browser confirmed",
      "offsetAccount": "Income or expense account",
      "chooseOffsetAccount": "Choose the posting account",
      "offsetRequired": "Choose the compatible income or expense account.",
      "confirmPosting": "Confirm and post",
      "confirming": "Posting…",
      "posted": "Movement posted.",
      "confirmationFailed": "Posting could not be confirmed. Review the current evidence and try again.",
      "readyToConfirm": "Source and tax checks passed. Confirm this exact posting.",
      "reviewHold": "Details saved on this screen. Source ownership, tax review and human confirmation are still required before posting.",
      "awaitingTitle": "Awaiting destination",
      "awaitingCompletionHold": "The outgoing leg is posted. Destination completion awaits reviewed evidence and confirmation.",
      "releaseHold": "Posting is on hold until source ownership, tax review and browser confirmation are available."
    },
    "title": "Cash Book",
    "description": "Posted movements for one bank or cash account.",
    "account": "Bank or cash account",
    "chooseAccount": "Choose an account",
    "archived": "Archived",
    "selectPrompt": "Choose an account to view its posted movements.",
    "chatChooseByName": "Choose an account by name to view its posted movements.",
    "denied": "You do not have access to this Cash Book.",
    "incomplete": "This account's history is still being checked. An exact balance is not available yet.",
    "incompleteHistory": "The history for this account has not been verified yet, so there is no exact balance. Bank / Cash, Cash Book shows why. Your ledger is not affected.",
    "incompleteNotStarted": "The history for this account has not been built yet, so there is no exact balance. An owner or finance admin can build it in Bank / Cash, Cash Book. Your ledger is not affected.",
    "incompleteRunning": "The history for this account is being built or updated, for example after recent entries, so there is no exact balance yet. It appears when that finishes. Bank / Cash, Cash Book shows how far it has got. Your ledger is not affected.",
    "incompleteStopped": "The history build for this account stopped before it finished, so there is no exact balance. An owner or finance admin can resume it in Bank / Cash, Cash Book. Your ledger is not affected.",
    "openingBalance": "Opening balance",
    "closingBalance": "Closing balance",
    "empty": "No posted movements in this period.",
    "morePending": "No movements on this page. More may be available.",
    "date": "Date",
    "movement": "Movement",
    "reference": "Reference",
    "postedAmount": "Posted amount",
    "viewPosting": "View posting",
    "bankMatch": "Bank match",
    "matchedOpenLine": "Matched · view bank line",
    "notMatched": "Not matched to a bank line",
    "voidedReceipt": "Receipt voided",
    "bankLineDetails": "Bank line details",
    "closeBankLine": "Close",
    "bankLineLoading": "Loading bank line…",
    "bankLineUnavailable": "Bank line is unavailable or access was denied.",
    "openAccountInquiry": "Open Account Inquiry",
    "openBankReconciliation": "Open bank reconciliation",
    "loadMore": "Load more",
    "previousPage": "Previous page",
    "needsReview": {
      "title": "Needs review",
      "description": "Imported statement lines awaiting a source decision or accounting recovery. Import and suggestions do not post money.",
      "loading": "Loading statement review…",
      "unavailable": "Statement review is unavailable or access was denied.",
      "incomplete": "Statement review is incomplete. Refresh before relying on line status.",
      "moreMayNeedReview": "More lines exist in this session. Open bank reconciliation for the full review.",
      "emptySession": "No lines on this session page need review.",
      "unnamedLine": "Statement line",
      "lifecycle": "Line lifecycle",
      "draftRecovery": "A historic journal draft exists. It is not posted or reconciled; review it in Journal Entries.",
      "purposeHold": "A reason is needed before any accounting action.",
      "reviewBeforeEffect": "Review the source and accounting effect before taking action.",
      "matchExisting": "Match existing · no new posting",
      "createReceiptPayment": "Create receipt/payment · one reviewed posting",
      "routesPending": "These routes are guidance only until the shared confirmed effect is available here.",
      "openReconciliation": "Open bank reconciliation",
      "openDrafts": "Review journal drafts"
    }
  },
  "accountInquiry": {
    "filters": {
      "account": "GL account",
      "accountPlaceholder": "Select a GL code",
      "dateFrom": "From",
      "dateTo": "To",
      "voucher": "Voucher",
      "voucherPlaceholder": "JV2608, PV..."
    },
    "header": {
      "period": "{from} to {to}",
      "caption": "Account inquiry for GL code {account}"
    },
    "table": {
      "date": "Date",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "balance": "Balance",
      "broughtForward": "Balance brought forward",
      "closingBalance": "Closing balance",
      "reference": "Reference",
      "openSource": "Open {source}"
    },
    "sides": {
      "debit": "Dr",
      "credit": "Cr"
    },
    "source": {
      "salesInvoice": "Sales invoice",
      "dailySales": "Platform & POS sales",
      "purchaseInvoice": "Purchase invoice",
      "expenseClaim": "Expense claim",
      "reimbursementBatch": "Reimbursement batch",
      "journalEntry": "Journal entry",
      "businessExpense": "Business expense"
    },
    "batch": {
      "title": "Reimbursement batch {code}",
      "paidOn": "Paid on",
      "reference": "Bank reference",
      "noReference": "Not recorded",
      "claim": "Claim",
      "amount": "Amount",
      "total": "Total",
      "empty": "This payment run has no claims to show.",
      "noRuns": "No payment run has been recorded for this report yet.",
      "claimsRestricted": "Claim details are visible to finance roles only.",
      "truncated": "This report has more claims than can be listed here.",
      "backfilled": "Reconstructed from payment history, so the batch grouping is an inference.",
      "drawerTitle": "Reimbursement details"
    },
    "states": {
      "loading": "Loading account inquiry...",
      "loadingAccounts": "Loading your chart of accounts...",
      "pickAccountTitle": "Choose a GL account",
      "pickAccountHint": "Pick any GL code, including a sub-code, to see every posting with its running balance.",
      "noAccountTitle": "Nothing posted to this account",
      "noAccountHint": "Only posted journal entries appear here. Expense claims post when they are reimbursed, and manual entries post when you post them. Widen the dates if the activity sits in another period.",
      "noMovement": "No movement in this period.",
      "invertedRange": "The From date is after the To date. Adjust the range to run the inquiry.",
      "loadError": "We could not load this account inquiry. Please try again."
    },
    "openingNote": "Revenue and expense accounts open at zero on the first day of the financial year. Balance sheet accounts carry their balance forward."
  },
  "accountActivity": {
    "filters": {
      "type": "Account type",
      "allTypes": "All types",
      "search": "Search",
      "searchPlaceholder": "Search by account code or name"
    },
    "actions": {
      "exportCsv": "Export CSV",
      "backToAll": "Back to all accounts"
    },
    "states": {
      "loading": "Loading the general ledger...",
      "empty": "No general ledger entries found for this period.",
      "loadError": "Failed to load the general ledger."
    },
    "sides": {
      "debit": "Dr",
      "credit": "Cr",
      "zero": "Zero"
    },
    "table": {
      "account": "Account",
      "type": "Type",
      "opening": "Opening",
      "debits": "Debits",
      "credits": "Credits",
      "netMovement": "Net movement",
      "closing": "Closing"
    },
    "detail": {
      "title": "General Ledger",
      "period": "{from} to {to}",
      "activeHint": "Showing journal entries for this account in the selected period.",
      "empty": "No journal entries for this account in the selected period.",
      "date": "Date",
      "entry": "Journal entry",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "running": "Running balance"
    },
    "openingNote": "Revenue and expense accounts open at zero on the first day of the financial year. Balance sheet accounts carry their balance forward."
  },
  "bankStatementImport": {
    "title": "Review bank statement import",
    "loading": "Loading statement review…",
    "unavailable": "This statement review is unavailable. Reopen the statement in chat.",
    "account": "Bank account",
    "rows": "Statement rows",
    "currency": "Currency",
    "currencySupplied": "Currency was supplied by the statement.",
    "currencyAssumed": "The statement did not supply currency. Review the selected bank account's currency.",
    "totalsVerified": "Supplied statement totals were checked.",
    "totalsPartial": "The statement supplied only part of its totals; a full balance check is unavailable.",
    "totalsNotProvided": "Statement totals were not provided; no total has been verified.",
    "opening": "Opening balance",
    "closing": "Closing balance",
    "progress": "Imported {inserted} · Reused {existing} · Held {held} · Pending {pending}",
    "credit": "Money in",
    "debit": "Money out",
    "rowStatus": "Import status",
    "page": "Source page {number}",
    "sheet": "Source sheet {name}",
    "status_pending": "Pending",
    "status_held": "Needs review",
    "status_inserted": "Imported",
    "status_existing": "Reused existing line",
    "status_alreadyImported": "Already imported",
    "alreadyImportedCount": "Already imported (same bank reference) {count}",
    "referenceConflictCount": "Bank reference conflicts {count}",
    "bankReference": "Bank reference: {reference}",
    "alreadyImportedRow": "Already imported. This account already holds a line with the same bank reference, date, amount and direction, so this line is skipped and counted as reused.",
    "referenceCandidates": "Lines already on this account with this bank reference",
    "referenceNote_conflict": "A line on this account already has this bank reference, but its amount or money in/out direction is different. It may be a second real payment, so it is not merged. Import it as its own line or hold it.",
    "referenceNote_date_differs": "A line on this account already has this bank reference, amount and direction, but on a different date. A bank can reuse a reference, so this line is not skipped. Import it as its own line or hold it.",
    "referenceNote_ambiguous": "This bank reference is already on more than one line of this account, so it cannot tell which line this is. Import it as its own line or hold it.",
    "referenceNote_tooMany": "This bank reference is already on too many lines to compare, so this line is held and will not be imported from this review.",
    "referenceNote_changed": "The earlier line this one matched has changed since you reviewed it. Refresh the overlap review to read the current lines.",
    "newSource": "New statement",
    "existingSource": "Existing statement",
    "sourcePosition": "Source row",
    "sourceSession": "Import session",
    "unknownSource": "Unknown",
    "scanHold": "Some rows are held because the overlap check reached its safe limit. Refresh their overlap evidence before importing.",
    "possibleOverlap": "Possible overlap with another statement",
    "reuse": "Reuse this bank line",
    "distinct": "Import as a separate real line",
    "hold": "Hold for review",
    "previous": "Previous rows",
    "next": "Next rows",
    "unselectedHold": "Any overlap without a choice stays on hold. Other rows can still import.",
    "refreshOverlaps": "Refresh overlap review",
    "confirmFacts": "I checked the bank account, dates, amounts and money in/out direction against the statement.",
    "confirmPdf": "I checked each PDF row against its source page.",
    "writeFailed": "The import could not finish. Review the latest progress and try again.",
    "resume": "Resume import",
    "confirm": "Confirm and import",
    "stale": "This review expired or was replaced. Prepare the statement again.",
    "complete": "Import complete. These are bank lines, not posted accounting entries.",
    "partial": "Import partially complete. Held or pending rows remain.",
    "changeMapping": "Change mapping",
    "mappingLocked": "This statement is imported, so its account and mapping are locked. If it went to the wrong account, retract it from Upload history and import it again."
  },
  "bankStatementSections": {
    "title": "This file has several accounts",
    "intro": "Groot found {count} accounts in this file and checked each one on its own. Nothing is imported until you confirm each account.",
    "introRepeated": "Groot found {statements, plural, one {# statement} other {# statements}} for {accounts, plural, one {# account} other {# accounts}} in this file and checked each statement on its own. Nothing is imported until you confirm each account.",
    "accountHeading": "Account {number}",
    "facts": "Opening {opening} · Closing {closing} · {count, plural, one {# line} other {# lines}}",
    "balanceOk": "Opening balance plus the lines equals the closing balance.",
    "matched": "Matched to {name} ••{last4}",
    "chooseLabel": "Which account is this?",
    "choosePlaceholder": "Choose an account",
    "ambiguous": "More than one account in Groot fits this statement. Choose the right one.",
    "unknown": "No account in Groot has these last digits yet. You can give it to an account that has no number saved.",
    "remember": "Groot will save the last digits ({digits}) on the account you choose, so the next file matches by itself.",
    "refused": {
      "balance_mismatch": "The opening balance and the lines do not add up to the closing balance (off by {difference}). This account is skipped; the others are not affected.",
      "account_repeated": "This account appears more than once in the file. Upload its statements in a separate file.",
      "no_account_line": "This statement has no account number, so Groot cannot tell which account it belongs to.",
      "no_lines": "This statement has no lines, so there is nothing to import.",
      "currency_mismatch": "The account in Groot that ends with these digits uses a different currency.",
      "no_account_for_number": "No account in Groot fits this statement. Add the account, or save its number in Bank accounts, then choose the file again.",
      "account_shared": "Another statement in this file points to the same account in Groot. Upload them in separate files.",
      "dates_inconsistent": "The dates in this statement do not line up.",
      "too_many_rows": "This statement has more than 500 lines. Split it into smaller files.",
      "unsupported": "This statement has a feature Groot cannot read yet.",
      "unreadable": "This statement could not be read."
    },
    "confirm": "I checked the accounts, balances and lines above.",
    "createPreviews": "Prepare the reviews",
    "preparing": "Preparing",
    "skippedNote": "{count, plural, one {# statement} other {# statements}} will not be imported from this file; the others carry on.",
    "noneStageable": "No account in this file can be prepared yet.",
    "noneImportable": "Nothing in this file can be imported yet. Every statement above was refused, and each one says why. Fix the reason shown on it, then choose the file again.",
    "reviewUnavailable": "This statement is being reviewed by someone else, or is not available.",
    "error": {
      "account_not_allowed": "That account cannot take this statement. Choose again.",
      "account_used_twice": "The same account was chosen for two statements. Choose a different account for each.",
      "section_not_stageable": "This statement cannot be prepared.",
      "generic": "This account could not be prepared. The other accounts are not affected."
    },
    "remembered": "Saved the last digits ({digits}) on {name}.",
    "rememberFailed": "Groot could not save the last digits, so you will be asked again next time.",
    "inspecting": "Splitting the file by account",
    "inspectFailed": "The file could not be split. Try again."
  },
  "bankRecon": {
    "pageTitle": "Accounting",
    "selectBusinessPrompt": "Select a business to view bank reconciliation",
    "selectBankAccount": "Select bank account",
    "selectBankAccountPrompt": "Select a bank account to view reconciliation",
    "manageAccounts": "Manage Accounts",
    "addBankAccount": "Add Bank Account",
    "rematch": "Re-match",
    "matchingInProgress": "Matching...",
    "rematchTooltip": "Re-run smart matching on unmatched transactions",
    "aiClassify": "Find suggestions",
    "classifyingInProgress": "Classifying...",
    "aiClassifyTooltip": "Find suggestions for unmatched transactions",
    "emptyState": {
      "title": "No bank accounts",
      "description": "Register your bank accounts to start importing statements and reconciling transactions against your accounting records."
    },
    "notifications": {
      "importedWithDuplicates": "Imported {imported} {imported, plural, one {transaction} other {transactions}}. {duplicates} {duplicates, plural, one {duplicate} other {duplicates}} skipped.",
      "importedSuccess": "Successfully imported {imported} {imported, plural, one {transaction} other {transactions}}.",
      "analyzingMatches": "Analyzing transactions for smart matches...",
      "matchesFoundThenClassify": "Found {matched} suggested {matched, plural, one {match} other {matches}}. Now running AI classification...",
      "runningClassification": "Running AI classification on unmatched transactions...",
      "classifiedReviewGl": "AI classified {classified} {classified, plural, one {transaction} other {transactions}}. Review suggested GL postings.",
      "noAdditionalClassifications": "No additional classifications found. You can manually categorize remaining transactions.",
      "classificationErrorManual": "AI classification encountered an error. You can still manually classify transactions.",
      "reanalyzingMatches": "Re-analyzing unmatched transactions...",
      "newMatchesFound": "Found {matched} new suggested {matched, plural, one {match} other {matches}}!",
      "noNewMatches": "No new matches found. All unmatched transactions have been analyzed.",
      "matchingError": "Matching encountered an error. Please try again.",
      "classifiedSuccess": "AI classified {classified} {classified, plural, one {transaction} other {transactions}}.",
      "classifiedWithErrors": "AI classified {classified} {classified, plural, one {transaction} other {transactions}}. {errors} could not be classified.",
      "noUnmatchedToClassify": "No unmatched transactions to classify.",
      "classificationError": "AI classification encountered an error. Please try again.",
      "suggestionOutcome": "{classified, plural, =0 {} one {# suggestion ready to review. } other {# suggestions ready to review. }}{unsure, plural, =0 {} one {# line needs your decision. } other {# lines need your decision. }}{unavailable, plural, =0 {} one {# line could not be given a suggestion. } other {# lines could not be given a suggestion. }}{moreUnread, select, yes {More lines are still waiting. Find suggestions again to continue.} other {{remaining, plural, =0 {} one {# line is still waiting. Find suggestions again to continue.} other {# lines are still waiting. Find suggestions again to continue.}}}}",
      "classifyBankNotLinked": "This bank account is not linked to a Cash at Bank account in your chart, so Groot cannot suggest accounts for its lines. Link it in Bank accounts, then find suggestions again."
    },
    "importButton": {
      "importFailed": "Import failed",
      "importing": "Importing...",
      "importStatement": "Import Statement",
      "errors": {
        "accountNotFound": "We couldn't find that bank account. Refresh the page and try again.",
        "wrongBusiness": "That bank account belongs to a different business. Switch workspace and try again.",
        "batchTooLarge": "That file has too many rows to import at once. Split it into smaller files and import them one at a time.",
        "generic": "We couldn't import those transactions. Nothing was imported, so please try again.",
        "unreadableDate": "“{value}” isn't a date we can read. Fix the date column and upload the statement again. Nothing was imported.",
        "mixedDateOrder": "Some dates in this file are written day first and others month first (“{dayFirst}” and “{monthFirst}”). Check the date column and upload the statement again. Nothing was imported.",
        "invalidDate": "A transaction date couldn't be read, so nothing was imported. Upload the statement again, and contact support if it keeps happening."
      }
    },
    "uploadHistory": {
      "button": "Upload history",
      "buttonTooltip": "See and manage past statement uploads",
      "title": "Upload history",
      "reviewTitle": "Imported lines",
      "reviewDashboardTitle": "Statement lines to review",
      "reviewChooseBusiness": "Select a business to review imported statement lines.",
      "reviewChooseUpload": "Choose an upload to review its bank lines.",
      "reviewNoUploads": "No statement uploads are available for this business.",
      "reviewRowCount": "{count} source rows",
      "reviewImportedLines": "Review imported lines",
      "backToHistory": "Back to upload history",
      "reviewLoading": "Loading imported lines…",
      "reviewUnavailable": "This upload is unavailable to review.",
      "reviewIncomplete": "These lines could not be checked completely. Try again later.",
      "reviewEmpty": "This upload has no live imported lines.",
      "reviewPage": "Page {page}",
      "reviewLines": "Imported lines on this page",
      "reviewUnnamedLine": "Bank line",
      "reviewPrevious": "Previous lines",
      "reviewNext": "Next lines",
      "empty": "No uploads yet.",
      "rowSummary": "{rows} rows imported · {transactions} transactions",
      "importedAt": "Uploaded {date}",
      "deleteTooltip": "Delete this upload",
      "deleteBlockedTooltip": "Can't delete: {count} transaction(s) already matched, categorized, or posted",
      "deleteSuccess": "Upload removed",
      "errors": {
        "notFound": "That upload could not be found. It may have already been removed.",
        "hasReconciledTransactions": "This upload has transactions that have already been matched, categorized, classified, reconciled, or posted, and can't be removed here. Only an upload whose transactions are still untouched can be cleared this way.",
        "generic": "Couldn't delete this upload. Please try again.",
        "hasBookedTransactions": "Some transactions from this upload were posted to your books. Reverse those entries first, then delete the upload."
      },
      "deleteConfirmWithTransactions": "This will permanently delete this upload and its {count} transaction(s). This can't be undone.",
      "deleteUndoTooltip": "Undo {count} matched or categorized transaction(s) and delete this upload",
      "deleteUndoTitle": "Undo matches and delete this upload?",
      "deleteUndoConfirm": "{undo} of this upload's {count} transaction(s) are matched or categorized. Those matches are undone first: the journal entries they were matched to stay in your books, only their link to this statement is removed. Then the upload and all {count} transaction(s) are deleted. This can't be undone.",
      "deleteUndoConfirmButton": "Undo matches and delete",
      "deleteUndoSuccess": "Upload removed. {count} transaction(s) were unmatched first.",
      "deleteBlockedBookedTooltip": "Can't delete: {count} transaction(s) from this upload were posted to your books. Reverse those entries first."
    },
    "rulesButton": "Rules",
    "rulesButtonTooltip": "See and change the rules Groot uses to suggest accounts"
  },
  "leaveUI": {
    "page": {
      "title": "Leave",
      "subtitle": "Apply for and track your leave requests"
    },
    "noBusiness": {
      "description": "Please select a business to view and manage your leave requests."
    },
    "form": {
      "sentToApprover": "Sent to {approver} for approval.",
      "sentForApproval": "Sent for approval.",
      "draftSaved": "Draft saved. Submit it from My Leave Requests when you are ready.",
      "draftNotSubmitted": "Saved as a draft, but it was not sent. Submit it from My Leave Requests.",
      "goToMyRequests": "Go to My Leave Requests"
    }
  },
  "leaveManagementUI": {
    "header": {
      "title": "Leave & Timesheet",
      "subtitle": "Manage leave, attendance, and timesheets"
    },
    "tabs": {
      "teamCalendar": "Team Calendar",
      "myLeave": "My Leave",
      "timesheet": "Timesheet",
      "reports": "Reports",
      "payroll": "Payroll",
      "myPayslips": "My Payslips"
    },
    "loading": {
      "teamCalendar": "Loading team calendar",
      "timesheet": "Loading timesheet",
      "reports": "Loading reports",
      "payroll": "Loading payroll",
      "myPayslips": "Loading payslips"
    }
  },
  "teamCalendar": {
    "header": {
      "title": "Team Calendar",
      "subtitle": "View team leave schedule and availability"
    },
    "heading": {
      "title": "Team Calendar",
      "subtitle": "View team absences and public holidays"
    },
    "controls": {
      "today": "Today",
      "previousMonth": "Previous month",
      "nextMonth": "Next month"
    },
    "daysOfWeek": {
      "sun": "Sun",
      "mon": "Mon",
      "tue": "Tue",
      "wed": "Wed",
      "thu": "Thu",
      "fri": "Fri",
      "sat": "Sat"
    },
    "months": {
      "january": "January",
      "february": "February",
      "march": "March",
      "april": "April",
      "may": "May",
      "june": "June",
      "july": "July",
      "august": "August",
      "september": "September",
      "october": "October",
      "november": "November",
      "december": "December"
    },
    "holiday": "Holiday",
    "moreCount": "+{count} more",
    "dayCount": "{count, plural, one {# day} other {# days}}",
    "fallback": {
      "employee": "Employee",
      "leave": "Leave"
    },
    "upcoming": {
      "title": "Upcoming",
      "subtitle": "Next 7 days",
      "empty": "No upcoming absences"
    },
    "legend": {
      "title": "Legend",
      "publicHoliday": "Public Holiday",
      "nonWorkingDay": "Weekend or holiday (not counted)",
      "spanNote": "A leave bar covers the whole span. Muted days do not count against the balance."
    }
  },
  "reportsUI": {
    "salesViews": {
      "label": "Sales report",
      "location": "By Location",
      "agent": "By Agent",
      "profitability": "Profitability"
    },
    "salesByAgent": {
      "title": "Sales by Agent",
      "subtitle": "Which agent sells how much, from the sales agent recorded on each invoice. Amounts are in your home currency.",
      "exportCsv": "Export CSV",
      "periodMode": {
        "label": "Period type",
        "month": "Calendar month",
        "quarter": "Calendar quarter",
        "custom": "Custom dates"
      },
      "reportMonth": "Report month",
      "reportQuarter": "Report quarter",
      "startDate": "Report start date",
      "endDate": "Report end date",
      "statusLabel": "Invoice status",
      "status": {
        "all": "All sales (sent, part-paid, overdue, paid)",
        "sent": "Sent",
        "partially_paid": "Partially paid",
        "overdue": "Overdue",
        "paid": "Paid"
      },
      "scopeNote": "Counts issued invoices by invoice date. Drafts and voided invoices are never counted; credit and refund notes reduce the agent's total.",
      "invalidRange": "The start date must be on or before the end date.",
      "loading": "Loading sales by agent",
      "truncated": "This period has more invoices than the report can read in one pass, so these totals are a floor. Narrow the period or the status to see complete figures.",
      "unconvertedForeign": "{count, plural, one {# foreign-currency invoice has} other {# foreign-currency invoices have}} no exchange rate and {count, plural, one {is} other {are}} left out of the {currency} totals.",
      "tiles": {
        "gross": "{currency} gross sales",
        "paid": "Paid",
        "outstanding": "Outstanding",
        "invoices": "Invoices",
        "invoicesHint": "{unassigned} unassigned · {creditNotes} credit / refund notes"
      },
      "tableTitle": "By agent",
      "columns": {
        "agent": "Agent",
        "invoices": "Invoices",
        "gross": "Gross sales",
        "paid": "Paid",
        "outstanding": "Outstanding",
        "share": "Share"
      },
      "total": "Total",
      "unassigned": "Unassigned",
      "empty": {
        "title": "No sales in this period",
        "hint": "Adjust the period or status, or record a sales agent on your invoices in the invoice editor."
      },
      "error": {
        "noAccess": "You do not have access to this report. Sales by Agent needs the Invoices feature and an owner or finance admin role.",
        "failed": "We could not load this report. Please try again."
      },
      "retry": "Try again"
    },
    "header": {
      "title": "Reports",
      "subtitle": "View your profit & loss, financial statements, intelligence and audit trail"
    },
    "agingReports": {
      "title": "Aging Reports",
      "subtitle": "Generate AP and AR aging reports with debtor statements"
    },
    "actions": {
      "howItWorks": "How it works",
      "financialIntelligence": "Financial Intelligence",
      "generateStatements": "Generate Statements",
      "generateReport": "Generate Report",
      "download": "Download report",
      "profitLoss": "Profit & Loss"
    },
    "pendingBanner": {
      "message": "{count, plural, one {# debtor statement pending review} other {# debtor statements pending review}}",
      "reviewAndSend": "Review & Send"
    },
    "aiInsights": {
      "heading": "AI Insights: {type} Aging ({period})"
    },
    "reportType": {
      "arShort": "AR",
      "apShort": "AP",
      "arAging": "AR Aging",
      "apAging": "AP Aging"
    },
    "history": {
      "title": "Report History",
      "empty": {
        "title": "No reports generated yet",
        "hint": "Click \"Generate Report\" to create your first aging report"
      }
    },
    "table": {
      "type": "Type",
      "period": "Period",
      "asOf": "As Of",
      "outstanding": "Outstanding",
      "generated": "Generated",
      "method": "Method",
      "actions": "Actions"
    },
    "method": {
      "auto": "Auto",
      "manual": "Manual"
    },
    "badges": {
      "warnings": "Warnings",
      "aiInsights": "AI Insights"
    },
    "states": {
      "noBusinessSelected": "No business selected",
      "adminOnly": "Reports are only accessible to Finance and business owners."
    },
    "toasts": {
      "statementsGenerated": "{count, plural, one {# debtor statement generated} other {# debtor statements generated}}",
      "generateStatementsFailed": "Failed to generate statements",
      "generateStatementsFailedFallback": "Failed"
    },
    "tabs": {
      "agingReports": "Aging Reports",
      "auditTrail": "Audit Trail",
      "statements": "Financial Statements",
      "financialIntelligence": "Financial Intelligence",
      "tax": "GST",
      "expenseReport": "Expense Report",
      "sales": "Sales",
      "duplicates": "Duplicates",
      "profitLoss": "Profit & Loss",
      "stock": "Stock"
    },
    "auditTrail": {
      "title": "Audit Trail",
      "subtitle": "A read-only record of who did what, and when, across your finances.",
      "howItWorks": "How the audit trail works",
      "accountingHistory": {
        "groupedRecords": "{count} linked records in this change set"
      },
      "groups": {
        "corrections": "Corrections",
        "payables": "Payables and expenses",
        "receivables": "Receivables and sales",
        "ledger": "Ledger",
        "payroll": "Payroll",
        "inventory": "Inventory and sales imports",
        "masterData": "Master data",
        "operations": "Operations"
      },
      "filters": {
        "eventType": "Event type",
        "entityType": "Entity type",
        "actor": "Team member",
        "from": "From",
        "to": "To",
        "clear": "Clear filters",
        "all": "All",
        "allEvents": "All events",
        "allEntities": "All entities",
        "allActors": "All users"
      },
      "entity": {
        "expense_claims": "Expense claims",
        "invoices": "Invoices (AP)",
        "journal_entries": "Journal entries",
        "vendors": "Vendors",
        "sales_invoices": "Sales invoices (AR)",
        "business_expenses": "Business expenses",
        "payment_vouchers": "Payment vouchers",
        "employee_payroll_profiles": "Payroll",
        "daily_sales_import_batches": "Daily sales imports",
        "inventory_production_runs": "Inventory production",
        "payments": "Payments",
        "receipts": "Receipts",
        "reconciliation_matches": "Bank reconciliation",
        "fixed_assets": "Fixed assets",
        "operational_sales_orders": "Sales orders",
        "purchase_orders": "Purchase orders",
        "accounting_periods": "Accounting periods",
        "fx_revaluation_runs": "FX revaluations",
        "cash_documents": "Cash documents",
        "supplier_payment_runs": "Supplier payment runs",
        "attendance_records": "Attendance",
        "bank_import_sessions": "Bank statement imports",
        "bank_recon_classification_rules": "Bank rules",
        "bank_transactions": "Bank transactions",
        "business_expense_drafts": "Expense drafts",
        "catalog_items": "Catalogue items",
        "sales_stock_formulas": "Stock formulas",
        "catalog_item_stock_relief_links": "Stock links",
        "catalog_vendor_item_mappings": "Supplier item mappings",
        "catalog_item_price_revisions": "Item price changes",
        "chart_of_accounts": "Chart of accounts",
        "woocommerce_connections": "Store connections",
        "businesses": "Business settings",
        "customer_loyalty_settings": "Loyalty settings",
        "customers": "Customers",
        "customer_stock_balances": "Customer held stock",
        "daily_sales_payout_import_batches": "Payout imports",
        "daily_sales_payout_import_batch": "Payout import",
        "daily_sales_payout": "Payouts",
        "fx_true_ups": "Currency true-ups",
        "gateway_payouts": "Gateway payouts",
        "gst_register_items": "Tax register",
        "inventory_movements": "Stock movements",
        "inventory_settings": "Inventory settings",
        "items_sold_batches": "Items sold batches",
        "items_sold_orders": "Items sold orders",
        "marketplace_overlap_holds": "Settlement overlaps",
        "business_memberships": "Team members",
        "official_receipts": "Official receipts",
        "price_tiers": "Price tiers",
        "dunning_policies": "Payment reminders",
        "projects": "Projects",
        "expense_reimbursement_batches": "Reimbursement batches",
        "report": "Reports",
        "timesheets": "Timesheets",
        "inventory_delivery_orders": "Delivery orders",
        "fiscal_year_closes": "Financial year close",
        "sql_bridge_companions": "SQL Bridge",
        "sql_bridge_write_jobs": "SQL Bridge writes",
        "sql_bridge_master_runs": "SQL Bridge reads",
        "weighbridge_tickets": "Weighbridge tickets",
        "sales_agents": "Sales agents"
      },
      "actor": {
        "system": "System",
        "autoApproval": "Automatic approval rule"
      },
      "details": {
        "show": "Details",
        "hide": "Hide details",
        "empty": "No additional details recorded.",
        "booleanTrue": "Yes",
        "booleanFalse": "No",
        "formerMember": "A former member",
        "currencyNotRecorded": "currency not recorded",
        "approvalMethodAuto": "Automatic approval",
        "autoApprovalRule": "{category} up to {amount}"
      },
      "loadMore": "Load more",
      "loading": "Loading activity…",
      "empty": {
        "title": "No audit activity yet",
        "hint": "Financial actions such as approvals, payments and journal posts appear here once performed."
      },
      "events": {
        "expense_claim": {
          "submitted": "Submitted expense claim",
          "approved": "Approved expense claim",
          "rejected": "Rejected expense claim",
          "recalled": "Recalled expense claim",
          "dangling_journal_link_cleared": "Cleared a link to a missing journal entry",
          "dangling_journal_link_relinked": "Relinked a claim to its own approval entry",
          "edited_by_approver": "Edited by approver",
          "paid": "Marked expense claim as paid",
          "posted_corrected": "Corrected posted expense claim"
        },
        "invoice": {
          "created": "Created AP invoice",
          "posted": "Posted invoice to AP",
          "payment_recorded": "Recorded payment on invoice",
          "voided": "Voided invoice",
          "posted_corrected": "Corrected posted AP invoice",
          "extraction_edited": "Edited extracted invoice data",
          "payment_held": "Put a bill's payment on hold",
          "payment_hold_released": "Released the payment hold on a bill",
          "settlement_bank_account_changed": "Changed the bank account a bill is paid from",
          "sql_export_requeued": "Queued a bill for export again",
          "total_confirmed": "Confirmed the total of a bill",
          "merged_document_acknowledged": "Confirmed a file with several invoices is one invoice"
        },
        "invoice_settings": {
          "payment_qr_changed": "Changed the payment QR printed on invoices"
        },
        "journal_entry": {
          "created": "Created journal entry",
          "posted": "Posted journal entry",
          "posted_updated": "Corrected posted journal entry",
          "draft_deleted": "Deleted draft journal entry",
          "draft_updated": "Updated draft journal entry"
        },
        "business_expense": {
          "created": "Created business expense",
          "paid": "Paid business expense",
          "reopened": "Reopened business expense",
          "posted_corrected": "Corrected posted business expense",
          "deleted": "Deleted business expense"
        },
        "payment_voucher": {
          "voided": "Voided payment voucher",
          "period_renumbered": "Renumbered vouchers into their transaction period",
          "family_backfilled": "Backfilled voucher numbers",
          "issued_retroactively": "Issued voucher retroactively",
          "renumbered": "Renumbered payment voucher",
          "renumbered_by_backfill": "Renumbered voucher during backfill",
          "settings_updated": "Updated voucher numbering settings",
          "supersede_pointer_renumbered": "Renumbered a voucher that replaced another"
        },
        "payroll": {
          "posted": "Posted payroll",
          "settled": "Settled payroll",
          "reversed": "Reversed payroll",
          "payslip_viewed": "Opened a payslip",
          "statutory_remitted": "Remitted statutory payroll contributions",
          "hrdf_settings_updated": "Updated the HRDF settings",
          "shg_fund_revealed": "Viewed an employee's self-help group fund"
        },
        "inventory": {
          "production_posted": "Posted inventory production",
          "production_corrected": "Corrected production run",
          "pack_conversion_corrected": "Corrected pack conversion",
          "costing_method_changed": "Changed the stock costing method",
          "stock_transferred": "Transferred stock between locations",
          "delivery_order_proof_recorded": "Recorded the signed copy of a delivery order",
          "delivery_order_proof_replaced": "Replaced the signed copy of a delivery order",
          "delivery_order_created": "Created a delivery order",
          "delivery_order_reserved": "Reserved stock for a delivery order",
          "delivery_order_posted": "Posted a delivery order",
          "delivery_order_cancelled": "Cancelled a delivery order",
          "delivery_order_voided": "Voided a delivery order",
          "credit_note_restocked": "Returned credit note goods to stock",
          "settings_changed": "Changed the stock settings",
          "weighbridge_ticket_confirmed": "Confirmed a weighbridge ticket",
          "delivery_order_invoiced": "Billed a delivery order on an invoice",
          "delivery_order_invoice_released": "Released a delivery order from its invoice"
        },
        "daily_sales": {
          "batch_confirmed": "Confirmed daily sales import",
          "batch_voided": "Voided daily sales import",
          "duplicate_source_released": "Duplicate import released",
          "batch_discarded": "Draft import discarded",
          "posting_partial": "Posting incomplete",
          "posting_completed": "Posting completed",
          "accounting_agent_review_confirmed": "Confirmed the accounting review of a sales import"
        },
        "statement": {
          "commit": "Statement posted",
          "recommit": "Statement reposted",
          "marketplace_commit": "Marketplace settlement posted",
          "cancel": "Cancelled statement posting"
        },
        "marketplace": {
          "hold_resolved": "Settlement overlap resolved"
        },
        "vendor": {
          "created": "Added vendor",
          "updated": "Updated vendor",
          "bank_account_sealed": "Encrypted vendor bank account"
        },
        "sales_invoice": {
          "created": "Created sales invoice",
          "posted": "Posted sales invoice",
          "emailed": "Emailed sales invoice to customer",
          "sent": "Posted sales invoice",
          "reopened": "Reopened sales invoice",
          "credit_note_created": "Created sales credit note",
          "debit_note_created": "Created sales debit note",
          "voided": "Voided sales invoice",
          "posted_updated": "Corrected posted sales invoice",
          "adjustment_note_issued": "Issued sales credit or debit note",
          "customer_credit_refunded": "Refunded customer credit",
          "customer_credit_applied": "Applied customer credit to an invoice",
          "customer_credit_refund_reversed": "Reversed a customer credit refund",
          "customer_credit_unapplied": "Unapplied customer credit",
          "dimensions_assigned": "Assigned dimensions to sales invoice",
          "payment_reference_backfill_collision": "Found a clashing payment reference during backfill",
          "refund_note_issued": "Issued a refund note",
          "stock_relief_retried": "Retried the stock deduction for an invoice"
        },
        "accounting_period": {
          "closed": "Accounting period closed",
          "reopened": "Accounting period reopened",
          "entries_locked": "Locked journal entries of an accounting period",
          "created": "Accounting period created"
        },
        "chart_of_accounts": {
          "marked_bank_on_link": "Marked chart account as bank when linking a bank account",
          "bank_designation_adopted": "Adopted a bank account designation",
          "recode_applied": "Renumbered accounts",
          "starter_archived": "Replaced the starter chart with an imported chart",
          "sub_account_history_decision": "Decided how history moves to a sub-account",
          "provider_chart_choice": "Chose how to use a provider chart",
          "dev_cleanup_archived": "Archived unused accounts in a chart cleanup"
        },
        "fx_revaluation": {
          "posted": "Posted FX revaluation",
          "reposted": "Re-ran FX revaluation"
        },
        "membership": {
          "removed": "Removed team member",
          "financial_reports_changed": "Changed financial reports access",
          "sales_access_changed": "Changed sales access"
        },
        "cash_document": {
          "first_post": "Posted cash document",
          "reversed": "Reversed cash document"
        },
        "financial_intelligence": {
          "viewed": "Viewed financial intelligence"
        },
        "opening_balance": {
          "posted": "Posted opening balances",
          "replaced": "Replaced opening balances"
        },
        "operational_sales_order": {
          "created": "Created sales order",
          "revised": "Revised sales order",
          "submitted": "Submitted sales order",
          "accepted": "Accepted sales order",
          "converted": "Converted sales order to invoice",
          "cancelled": "Cancelled a sales order",
          "reopened": "Reopened a sales order after its draft invoice was deleted"
        },
        "operational_quotation": {
          "created": "Created quotation",
          "converted_to_order": "Converted quotation to sales order",
          "declined": "Recorded quotation as declined",
          "expired": "Closed quotation as expired",
          "emailed": "Emailed quotation to the customer"
        },
        "purchase_order": {
          "created": "Created purchase order",
          "revised": "Revised purchase order",
          "submitted": "Submitted purchase order",
          "approved": "Approved purchase order",
          "accepted": "Accepted purchase order",
          "received": "Received purchase order goods",
          "converted": "Converted purchase order to bill"
        },
        "supplier_payment_run": {
          "recorded": "Recorded supplier payment run",
          "reversed": "Reversed supplier payment run"
        },
        "attendance": {
          "check_in": "Checked in",
          "check_out": "Checked out",
          "manual_entry": "Entered attendance by hand",
          "waive_deduction": "Waived an attendance deduction"
        },
        "bank_import": {
          "session_deleted": "Deleted a bank statement import",
          "session_retracted": "Retracted a bank statement import"
        },
        "bank_recon_rule": {
          "created": "Created a bank rule",
          "updated": "Updated a bank rule",
          "deleted": "Deleted a bank rule",
          "builtin_enabled": "Turned on a built-in bank rule",
          "builtin_disabled": "Turned off a built-in bank rule"
        },
        "bank_reconciliation": {
          "legacy_draft_created": "Created a draft entry from a bank line",
          "match_confirmed": "Confirmed a bank match"
        },
        "bank_statement": {
          "closing_entered": "Entered the statement closing balance",
          "closing_cleared": "Cleared the statement closing balance"
        },
        "business_expense_draft": {
          "discarded": "Discarded an expense draft"
        },
        "catalog": {
          "pair_collapsed": "Merged a sales item and a stock item",
          "product": {
            "uses_no_stock": {
              "set": "Marked a product as using no stock",
              "unset": "Marked a product as using stock",
              "cleared": "Cleared the no-stock setting on a product"
            }
          },
          "stock_item": {
            "not_deducted_by_sales": {
              "set": "Marked a stock item as not deducted by sales",
              "unset": "Marked a stock item as deducted by sales",
              "cleared": "Cleared the not-deducted setting on a stock item"
            }
          },
          "sales_stock_formula": {
            "created": "Created a stock formula for a sales item",
            "replaced": "Replaced a stock formula",
            "archived": "Archived a stock formula"
          },
          "stock_relief_link": {
            "created": "Linked a sales item to a stock item",
            "superseded": "Replaced a stock link",
            "archived": "Archived a stock link"
          },
          "supplier_item_mapping": {
            "created": "Mapped a supplier item to a stock item",
            "stock_item_changed": "Changed the stock item of a supplier mapping",
            "deactivated": "Deactivated a supplier item mapping",
            "reactivated": "Reactivated a supplier item mapping",
            "pack_review_requested": "Asked for a pack size review",
            "recovered": "Recovered a supplier item mapping"
          }
        },
        "catalog_item_price_revision": {
          "created": "Changed an item price"
        },
        "connector": {
          "affiliatewp_connected": "Connected AffiliateWP",
          "affiliatewp_disconnected": "Disconnected AffiliateWP",
          "affiliate_supplier_created": "Created a supplier for an affiliate",
          "affiliate_supplier_account_created": "Created an account for an affiliate supplier",
          "affiliate_commission_account_prepared": "Prepared the affiliate commission account",
          "affiliate_commission_posted": "Posted an affiliate commission",
          "affiliate_commission_held": "Created an affiliate commission bill and held it for review",
          "authorisation_changed": "Changed a store connection's permissions",
          "paid_order_settings_changed": "Changed the paid order settings of a store connection",
          "paid_order_history_confirmed": "Confirmed the paid order history of a store connection",
          "buyer_index_prepared": "Prepared the buyer index for store orders",
          "clearing_account_prepared": "Prepared the clearing account for store orders",
          "order_posted": "Posted a paid store order",
          "order_posted_open": "Posted an unpaid store order"
        },
        "customer_loyalty": {
          "settings_updated": "Updated loyalty settings"
        },
        "customer_points": {
          "adjusted": "Adjusted a customer's points",
          "redeemed": "Redeemed a customer's points"
        },
        "customer_payment": {
          "cheque_cleared": "Cleared a customer cheque",
          "opening_items_recorded": "Recorded opening customer payments"
        },
        "customer_stock": {
          "hold_created": "Held stock for a customer",
          "released": "Released held stock to a customer",
          "release_reversed": "Reversed a release of held stock",
          "voided": "Voided held stock"
        },
        "daily_sales_payout": {
          "duplicate_source_released": "Released a duplicate payout source"
        },
        "daily_sales_payout_imported": "Imported a payout statement",
        "daily_sales_payout_matched": "Matched a payout to a bank line",
        "daily_sales_payout_match_rejected": "Rejected a payout match",
        "einvoice": {
          "received_bill_drafted": "Drafted a bill from a received e-invoice"
        },
        "fx_true_up": {
          "applied": "Applied a currency true-up",
          "unwound": "Unwound a currency true-up"
        },
        "gateway": {
          "payout_settled": "Settled a payment gateway payout"
        },
        "gst_register": {
          "reviewed": "Reviewed a tax register item",
          "evidence_linked": "Linked evidence to a tax register item"
        },
        "items_sold": {
          "created": "Started an items sold batch",
          "capture_saved": "Saved captured orders",
          "order_reviewed": "Reviewed a captured order",
          "evidence_paired": "Paired evidence with an order",
          "order_removed": "Removed an order from a batch",
          "replacement_prepared": "Prepared a replacement batch",
          "draft_deleted": "Deleted a draft items sold batch",
          "posted": "Posted an items sold batch",
          "reversed": "Reversed an items sold batch"
        },
        "official_receipt": {
          "issued_for_payment": "Issued an official receipt for a payment",
          "emailed": "Emailed an official receipt",
          "printed": "Printed an official receipt"
        },
        "official_receipts": {
          "auto_email_changed": "Changed automatic receipt emailing",
          "setting_changed": "Changed an official receipt setting"
        },
        "price_tier": {
          "created": "Created a price tier",
          "updated": "Updated a price tier",
          "archived": "Archived a price tier"
        },
        "dunning_policy": {
          "updated": "Updated payment reminder settings"
        },
        "project": {
          "created": "Created a project"
        },
        "reimbursement_batch": {
          "sql_exported": "Exported a reimbursement batch",
          "sql_export_requeued": "Queued a reimbursement batch for export again"
        },
        "report": {
          "emailed": "Emailed a report"
        },
        "sales_import": {
          "setup_updated": "Updated the sales import setup"
        },
        "timesheet": {
          "confirmed": "Confirmed a timesheet",
          "entry_edited": "Edited a timesheet entry",
          "approved": "Approved a timesheet",
          "rejected": "Rejected a timesheet",
          "finalized": "Finalised a timesheet",
          "unfinalized": "Reopened a finalised timesheet",
          "locked": "Locked a timesheet"
        },
        "fiscal_year": {
          "closed": "Financial year closed",
          "voided": "Financial year sign-off voided"
        },
        "sql_bridge": {
          "enrolled": "Registered or re-registered the SQL Bridge",
          "revoked": "Revoked the SQL Bridge",
          "company_confirmed": "Confirmed the SQL Account company",
          "ambiguous_resolved": "Recorded what SQL Account holds for an unknown write",
          "settings_changed": "Changed the SQL Bridge posting settings",
          "master_pull_requested": "Asked the SQL Bridge to read SQL Account",
          "chart_applied": "Imported the chart of accounts through the SQL Bridge",
          "supplier_codes_imported": "Brought in supplier codes through the SQL Bridge",
          "chart_auto_import_changed": "Changed the SQL Bridge weekly chart read"
        },
        "customer": {
          "default_sales_agent_changed": "Changed a customer's sales agent",
          "default_sales_agent_bulk_assigned": "Assigned a sales agent to several customers"
        },
        "sales_agent": {
          "login_link_changed": "Changed a sales agent's login"
        }
      },
      "financialReports": {
        "turnedOn": "Turned on financial reports for",
        "turnedOff": "Turned off financial reports for"
      },
      "salesAccess": {
        "turnedOn": "Turned on sales access for",
        "turnedOff": "Turned off sales access for"
      }
    },
    "pro": {
      "statements": {
        "title": "Pro statements",
        "message": "Upgrade to Pro for Balance Sheet, Cash Flow & Trial Balance."
      },
      "intelligence": {
        "title": "Financial Intelligence",
        "message": "Upgrade to Pro for anomaly detection, vendor risk, forecasting & spend analytics."
      },
      "audit": {
        "title": "Audit Trail",
        "message": "Upgrade to Pro for a full read-only audit trail of who did what, and when."
      }
    },
    "stockClosing": {
      "title": "Stock balance as at a date",
      "subtitle": "What was on the shelf on a date, at cost, checked against the Inventory account in your books.",
      "howItWorks": {
        "open": "How the stock balance works",
        "title": "How the stock balance works",
        "intro": "This list shows each item and location with the quantity on hand at the end of the date you choose, the unit cost and the value.",
        "stepsHeading": "Reading the report",
        "step1Title": "Pick a date",
        "step1Desc": "Today reads the live stock. An earlier date is rebuilt from every stock movement up to the end of that day.",
        "step2Title": "Narrow the list",
        "step2Desc": "Filter by location, search by item name or SKU, and choose whether sold-out items appear. Group by location or category to see a subtotal for each.",
        "step3Title": "Check the ledger line",
        "step3Desc": "The card above the list compares the stock list with the Inventory account at the same date. The difference is always shown, even when it is zero.",
        "goodToKnowHeading": "Good to know",
        "goodToKnow1": "A difference usually means stock movements dated after the chosen date, goods received but not yet booked, or a manual journal on the Inventory account.",
        "goodToKnow2": "Quantities of different units are never added together. The total row lists each unit on its own.",
        "goodToKnow3": "Export the list to CSV or Excel. The file carries the same ledger comparison under the total.",
        "goodToKnow4": "Stock is valued at weighted average cost. Under MPERS section 13.18 and MFRS 102, first-in first-out and weighted average are both allowed; first-in first-out will be added later."
      },
      "filters": {
        "asAt": "As at",
        "location": "Location",
        "allLocations": "All locations",
        "search": "Search by item name or SKU",
        "hideZero": "Hide zero balances",
        "groupBy": "Group by",
        "groupNone": "No grouping",
        "groupLocation": "Location",
        "groupCategory": "Category",
        "preset": {
          "today": "Today",
          "lastMonthEnd": "Last month end",
          "lastQuarterEnd": "Last quarter end"
        }
      },
      "export": {
        "csv": "Export CSV",
        "xlsx": "Export Excel",
        "failed": "The file could not be created. Try again in a moment.",
        "sheetName": "Closing stock",
        "summarySheetName": "Summary",
        "status": "Status",
        "statusComplete": "Complete",
        "statusIncomplete": "Incomplete: the list was cut off at the history limit, so these totals are partial",
        "driftRows": "Rows that differ from live stock",
        "glPartialList": "Not compared: the stock list is partial"
      },
      "counts": {
        "summary": "{items, plural, one {# item} other {# items}}, {withStock} with stock"
      },
      "source": {
        "live": "Read from the live stock rows",
        "replay": "Rebuilt from stock movements up to the end of this date"
      },
      "gl": {
        "title": "Check against the ledger",
        "perLedger": "Inventory per ledger",
        "perList": "Per stock list",
        "difference": "Difference",
        "matches": "The stock list agrees with the ledger.",
        "explain": "A difference usually means stock movements dated after this date, goods received but not yet booked, or a manual journal on the Inventory account.",
        "notCompared": "Not compared",
        "listScope": "The comparison uses every location, whatever the location filter says.",
        "unavailable": "Ledger comparison unavailable: {reason}",
        "reason": {
          "STOCK_TAKE_LEDGER_TOO_LARGE": "the Inventory account has more entries than one check can read. Contact support.",
          "POSTING_ACCOUNT_NOT_CONFIGURED": "no Inventory account is set. Choose one in Payment & posting settings.",
          "POSTING_ACCOUNT_IS_HEADING": "the Inventory account chosen is a heading, not an account that holds entries. Choose another in Payment & posting settings.",
          "GL_COMPARISON_PARTIAL_LIST": "the stock list is partial, so a difference would be misleading.",
          "other": "the ledger could not be read right now."
        },
        "accountLabel": "Inventory account",
        "account": "Compared with the Inventory account {code} {name}.",
        "rounding": "The difference of {amount} is cent rounding: each posting is rounded to the cent, so the stock list and the ledger can differ by a few cents with nothing wrong."
      },
      "columns": {
        "itemCode": "Code",
        "category": "Category",
        "percentOfTotal": "% of total",
        "item": "Item",
        "location": "Location",
        "unit": "Unit",
        "quantity": "Quantity",
        "unitCost": "Unit cost",
        "value": "Value"
      },
      "subtotal": "{name} subtotal",
      "uncategorised": "No category",
      "showing": "Showing {shown} of {total} lines",
      "showMore": "Show more",
      "costMethod": {
        "label": "Costing method",
        "weighted_average": "Weighted average cost",
        "fifo": "First in first out (FIFO)"
      },
      "headline": {
        "value": "Stock balance {value}",
        "items": "{count, plural, one {# item} other {# items}}",
        "locations": "{count, plural, one {# location} other {# locations}}",
        "ties": "ties to the ledger",
        "differs": "differs from the ledger by {amount}",
        "unavailable": "ledger comparison unavailable",
        "seeWhy": "See why",
        "why1": "Stock movements dated after the report date.",
        "why2": "Purchases not yet received into stock.",
        "why3": "Manual journals posted to the Inventory account.",
        "valuePartial": "At least {value}, partial list",
        "partialNotCompared": "not compared with the ledger",
        "filtered": "Filtered view",
        "attention": "{count, plural, one {# needs attention} other {# need attention}}",
        "attentionWholeList": "{count, plural, one {# needs attention in the whole list} other {# need attention in the whole list}}"
      },
      "partial": "This list is partial. The business has more stock movements than one report can read ({movements} were read), so these figures are not final and are not compared with the ledger.",
      "drift": "{count, plural, one {# stock row does not} other {# stock rows do not}} agree with its movement history, so the figures for those items may be off. Open Products, Stock to check them.",
      "noCost": "No cost",
      "total": "Total",
      "stockCard": "Stock card",
      "openItem": "Open {name} in Products",
      "empty": {
        "title": "No stock to show",
        "hint": "Nothing matches at this date. Try another date, another location, or show zero balances."
      },
      "loading": "Working out closing stock",
      "error": {
        "noAccess": "Stock costs are available to owners and finance admins only.",
        "invalidDate": "Choose a valid date.",
        "failed": "Closing stock could not be loaded. Try again in a moment."
      },
      "retry": "Retry",
      "totalPartial": "Total (partial list)",
      "attention": {
        "title": "Needs attention",
        "count": "{count, plural, one {# line needs attention} other {# lines need attention}}",
        "andMore": "and {count} more",
        "showFewer": "Show fewer",
        "notListed": "{count, plural, one {# more is not listed here.} other {# more are not listed here.}}",
        "kind": {
          "negative_quantity": "Negative quantity",
          "non_positive_cost": "Zero or negative cost",
          "cost_outlier": "Cost far from other locations",
          "no_movement_90d": "No movement for 90 days",
          "cost_missing": "No cost recorded",
          "replay_drift": "History disagrees with stock"
        },
        "detail": {
          "negative_quantity": "{quantity} on hand",
          "non_positive_cost": "{quantity} on hand at a cost of {cost}",
          "cost_outlier": "Costs {cost} here against {peer} at its other locations ({ratio} times apart)",
          "no_movement_90d": "{quantity} on hand, no movement for {days} days",
          "cost_missing": "{quantity} on hand with no cost, so the total understates them",
          "replay_drift": "History says {quantity}, the stock row says {stored}"
        },
        "countWholeList": "{count, plural, one {# line needs attention (whole list)} other {# lines need attention (whole list)}}",
        "clean": "Nothing needs attention",
        "unchecked": "Not checked: the list is partial"
      },
      "priceHistory": "Price history"
    },
    "stockCard": {
      "title": "Stock card",
      "subtitle": "Every unit in and out of one item: what came in and from whom, what went out and to whom.",
      "backToClosing": "Back to closing stock",
      "openItem": "Open {name} in Products",
      "howItWorks": {
        "open": "How the stock card works",
        "title": "How the stock card works",
        "intro": "Use this when the count on the shelf does not match the system. It lists every movement of one item in the dates you choose, with the balance after each one.",
        "stepsHeading": "Reading the card",
        "step1Title": "Start from the opening balance",
        "step1Desc": "That is what was held just before your first date. Each line then adds or removes units.",
        "step2Title": "Open the document",
        "step2Desc": "The number on each line is the invoice, bill, journal entry or other document behind it. Select it to open that document.",
        "step3Title": "Check the closing balance",
        "step3Desc": "It matches the closing stock report for the last date, and the stock held now when that date is today.",
        "goodToKnowHeading": "Good to know",
        "goodToKnow1": "Balances follow the order entries were recorded. An entry keyed in late but dated earlier sits at its date and is marked, so the balance can look out of order.",
        "goodToKnow2": "A write-off typed without a cost leaves at the average cost the units were held at, and the line says so.",
        "goodToKnow3": "Opening stock, adjustments, transfers and production runs are all here, each with its own words."
      },
      "filters": {
        "from": "From",
        "to": "To",
        "location": "Location",
        "allLocations": "All locations",
        "preset": {
          "thisMonth": "This month",
          "lastMonth": "Last month",
          "thisYear": "This year",
          "last12Months": "Last 12 months"
        },
        "defaultedFrom": "No start date was chosen, so this shows the 12 months up to {to}.",
        "yearNote": "\"This year\" runs from the first day of the financial year set in Business Profile to today."
      },
      "headline": {
        "range": "{from} to {to}",
        "opening": "Opening {quantity}",
        "in": "{quantity} in",
        "out": "{quantity} out",
        "closing": "Closing {quantity}, {value}"
      },
      "costMethod": {
        "label": "Costing method",
        "weighted_average": "Weighted average cost",
        "fifo": "First in first out (FIFO)"
      },
      "columns": {
        "date": "Date",
        "document": "Document",
        "description": "What happened",
        "location": "Location",
        "in": "In",
        "out": "Out",
        "unit": "Unit",
        "unitCost": "Unit cost",
        "balance": "Balance",
        "balanceValue": "Balance value"
      },
      "opening": "Opening balance",
      "closing": "Closing balance",
      "noCost": "No cost",
      "costFromAverage": "At the average cost the units were held at",
      "backdated": {
        "badge": "Keyed in later",
        "hint": "This was recorded after entries with a later date, so the balance on this line follows the order entries were recorded."
      },
      "openDocument": "Open {number}",
      "banner": {
        "partial": "This card is partial. The item has more movements than one card can read ({movements} were read, oldest first, up to {until}), so the closing balance is not final and is not checked against the stock held now. Narrow the date range to see later movements.",
        "drift": "The movements here do not agree with the stock held now, so these figures may be off. Open Products, Stock to check this item.",
        "lateRecorded": "{count, plural, one {# entry dated before this range was} other {# entries dated before this range were}} recorded after entries inside it, so the balances on the lines can differ from the opening balance plus the changes.",
        "documentsCapped": "Only the first {cap} documents are linked. The other lines show their description without a link."
      },
      "description": {
        "received_from": "Received from {supplier}",
        "received": "Received",
        "received_on_claim": "{has, select, yes {Received on an expense claim from {supplier}} other {Received on an expense claim}}",
        "sold_to": "Sold to {customer}",
        "sold": "Sold",
        "sold_to_order": "Sold to {customer} ({channel} order {order})",
        "delivered_to": "Delivered to {customer}",
        "delivered": "Delivered",
        "delivery_voided": "Delivery cancelled",
        "sale_reversed": "{has, select, yes {Sale to {customer} cancelled} other {Sale cancelled}}",
        "sale_reopened": "{has, select, yes {Sale to {customer} reopened} other {Sale reopened}}",
        "customer_return": "{has, select, yes {Returned by {customer}} other {Customer return}}",
        "customer_return_voided": "Customer return cancelled",
        "returned_to_supplier": "{has, select, yes {Returned to {supplier}} other {Returned to supplier}}",
        "supplier_return_voided": "Return to supplier cancelled",
        "production_used": "{has, select, yes {Used in production run {production}} other {Used in production}}",
        "production_made": "{has, select, yes {Made in production run {production}} other {Made in production}}",
        "production_reversed_used": "Production run corrected: components returned",
        "production_reversed_made": "Production run corrected: finished goods removed",
        "adjustment": "Adjustment: {reason}",
        "opening_stock": "Opening stock",
        "transfer_out": "{has, select, yes {Transfer to {location}} other {Transfer out}}",
        "transfer_in": "{has, select, yes {Transfer from {location}} other {Transfer in}}",
        "items_sold": "{has, select, yes {Sold through {platform}} other {Items sold}}",
        "items_sold_reversed": "Items sold report reversed",
        "pack_corrected": "Pack size corrected",
        "movement_in": "Stock in",
        "movement_out": "Stock out",
        "costing_switch_opening": "Opening stock layer when the costing method changed"
      },
      "adjustReason": {
        "manual_adjustment": "stock count correction",
        "free_of_charge": "received free of charge",
        "owner_supplied": "supplied by the owner",
        "wastage": "wastage",
        "rnd_testing": "R&D and testing",
        "staff_meal": "staff meal",
        "sample_marketing": "sample given away",
        "other": "other"
      },
      "platform": {
        "pos": "POS",
        "grabfood": "GrabFood",
        "shopee": "Shopee",
        "foodpanda": "foodpanda",
        "other": "another platform"
      },
      "empty": {
        "noItem": {
          "title": "Choose an item",
          "hint": "Open the stock card from a row of the closing stock report."
        },
        "noMovements": {
          "title": "No movements in this range",
          "hint": "This item has no stock movements between these dates. Try a longer range or another location."
        }
      },
      "loading": "Working out the stock card",
      "error": {
        "noAccess": "Stock costs are available to owners and finance admins only.",
        "invalidDate": "Choose a valid date.",
        "rangeReversed": "The end date is before the start date.",
        "notFound": "This stock item could not be found.",
        "failed": "The stock card could not be loaded. Try again in a moment."
      },
      "retry": "Retry",
      "export": {
        "csv": "Download CSV",
        "xlsx": "Download Excel",
        "sheetName": "Stock card",
        "summarySheetName": "Summary",
        "failed": "The file could not be created. Try again.",
        "status": "Status",
        "statusComplete": "Complete",
        "statusIncomplete": "Incomplete: the movement limit cut the read, so the closing balance is not final",
        "drift": "Check against live stock",
        "driftNone": "The history agrees with the stock rows",
        "driftFound": "The history disagrees with the stock rows",
        "driftNotChecked": "Not checked: the card is partial"
      },
      "criteria": {
        "item": "Item"
      },
      "showMore": "Show {count} more lines",
      "closingIncomplete": "Closing balance (incomplete)",
      "voucher": {
        "void": "Void",
        "noNumber": "No number"
      },
      "totals": {
        "line": "In the range: {valueIn} received, {valueOut} issued.",
        "unknownCost": "{count, plural, one {# line has no cost and is left out of these figures.} other {# lines have no cost and are left out of these figures.}}",
        "backdated": "{count, plural, one {# line is dated earlier than lines already recorded.} other {# lines are dated earlier than lines already recorded.}}"
      }
    },
    "priceHistory": {
      "title": "Purchase price history",
      "subtitle": "What you paid for an item, from whom, at what exchange rate, and the margin you make at today's cost.",
      "loading": "Loading price history",
      "retry": "Try again",
      "howItWorks": {
        "open": "How price history works",
        "title": "How price history works",
        "intro": "Every purchase of the item you choose is listed with the supplier, the document, the price in the currency you bought in, the exchange rate and the cost in your home currency.",
        "stepsHeading": "Reading the report",
        "step1Title": "Start with the margin",
        "step1Desc": "The panel at the top shows each product that sells this item, its selling price, the cost at the latest purchase and the margin. Use it before you set or raise a price.",
        "step2Title": "See how the cost moved",
        "step2Desc": "The chart plots the cost of every purchase, coloured by supplier. The table shows the change from the last purchase, and from the last purchase from the same supplier.",
        "step3Title": "Open the document",
        "step3Desc": "Click a document number to open the supplier bill or expense claim behind the price.",
        "goodToKnowHeading": "Good to know",
        "goodToKnow1": "The rate shown is the one recorded when the stock was received, so the cost is exactly what is in your stock value.",
        "goodToKnow2": "Costs are per unit of the item, for example per gram, even when the supplier sells by the kilogram.",
        "goodToKnow3": "Opening stock, adjustments, transfers, production and returns are not purchases and are not listed.",
        "goodToKnow4": "A margin is never guessed: with no selling price, no known cost or a selling price in another currency, the panel says so instead of showing a number."
      },
      "picker": {
        "label": "Choose a stock item",
        "placeholder": "Search by item name or SKU",
        "empty": "No stock item matches.",
        "choose": "Choose another item",
        "change": "Change item"
      },
      "error": {
        "noAccess": "You do not have access to purchase costs.",
        "invalidRange": "Choose a valid date range.",
        "notFound": "This item is not available.",
        "failed": "The price history could not be loaded. Try again in a moment."
      },
      "latest": {
        "label": "Latest cost",
        "fromPurchase": "From {supplier} on {date}",
        "fromAverage": "Average cost in stock, no purchase on record",
        "none": "No cost on record for this item."
      },
      "partial": {
        "purchaseCap": "This item has more purchases than one report shows. The newest are listed; narrow the dates to see older ones.",
        "scanCap": "This item has too much history to read in one go, so older purchases may be missing. Narrow the dates to check."
      },
      "filters": {
        "title": "Filters",
        "from": "From",
        "to": "To",
        "supplier": "Supplier",
        "allSuppliers": "All suppliers",
        "clear": "Clear filters"
      },
      "margin": {
        "title": "Selling price and margin",
        "subtitle": "At the latest purchase cost, for each product that sells this item.",
        "price": "Selling price",
        "noPrice": "None",
        "costAtLatest": "Cost at latest purchase",
        "margin": "Margin",
        "marginPct": "Margin %",
        "noSellingProducts": "No product sells this item through an On-sale formula, so there is no selling price to compare.",
        "bundle": "Bundle of {count} items",
        "usesAverage": "Some costs use the average cost in stock because there is no purchase on record.",
        "component": "{quantity} {unit} {name} at",
        "truncated": "More products sell this item than are shown here.",
        "reason": {
          "no_price": "No selling price",
          "cost_unknown": "Cost unknown",
          "currency_mismatch": "Selling price is in another currency"
        },
        "onPromotion": "Promotion price in use (regular price {regular})"
      },
      "chart": {
        "title": "Cost per purchase over time",
        "label": "Chart of the unit cost of {count, plural, one {# purchase} other {# purchases}} over time, coloured by supplier",
        "other": "Other suppliers"
      },
      "table": {
        "title": "Purchases",
        "summary": "{count, plural, one {# purchase} other {# purchases}} since {from}",
        "firstPurchase": "First purchase",
        "vsLast": "vs last purchase",
        "vsSupplier": "vs same supplier",
        "notRecorded": "Not recorded",
        "unknownSupplier": "Supplier not recorded",
        "openDocument": "Open {number}",
        "documentUnavailable": "no longer available",
        "documentDate": "Document dated {date}",
        "pack": "Bought as {quantity} {unit}",
        "source": {
          "bill": "Supplier bill",
          "claim": "Expense claim"
        },
        "columns": {
          "date": "Received",
          "supplier": "Supplier",
          "document": "Document",
          "price": "Price paid",
          "rate": "Rate",
          "unitCost": "Unit cost",
          "change": "Change"
        },
        "flags": {
          "currencyChanged": "Currency changed",
          "rateChanged": "Rate changed",
          "unitChanged": "Unit changed",
          "corrected": "Pack corrected",
          "documentRateDiffers": "Bill rate {rate}",
          "backdated": "Keyed in after a later purchase"
        },
        "notCounted": "Not counted",
        "status": {
          "voided": "Voided bill, not counted",
          "deleted": "Deleted, not counted"
        }
      },
      "empty": {
        "title": "No purchases in this range",
        "hint": "Receive stock from a supplier bill or an expense claim, or widen the dates."
      },
      "costUnknown": "Cost unknown",
      "export": {
        "csv": "Export CSV",
        "xlsx": "Export Excel",
        "failed": "The file could not be created. Try again in a moment.",
        "sheetName": "Price history",
        "summarySheetName": "Summary",
        "item": "Item",
        "documentDate": "Document date",
        "source": "Source",
        "quantity": "Quantity",
        "unit": "Unit",
        "currency": "Currency",
        "changeSupplier": "Change vs same supplier",
        "changeSupplierPct": "Change vs same supplier %",
        "changeOverall": "Change vs last purchase",
        "changeOverallPct": "Change vs last purchase %",
        "latestCost": "Latest cost",
        "averageCost": "Average cost",
        "lowestCost": "Lowest cost",
        "highestCost": "Highest cost",
        "statusColumn": "Status",
        "product": "Product",
        "priceUsed": "Price used",
        "priceRegular": "Regular price",
        "pricePromotion": "Promotion price",
        "status": "Status",
        "partial": "Partial: newest {purchases} purchases only",
        "partialSelling": "Partial: not every selling product is listed"
      },
      "headline": {
        "label": "Cheapest supplier and latest change",
        "cheapest": "Cheapest now: {supplier} at {cost}",
        "cheapestBelow": "Cheapest now: {supplier} at {cost}, {pct}% below {latest}, the supplier of the latest purchase",
        "cheapestBadge": "Cheapest now",
        "latestChange": "Latest change: {change} against the previous purchase"
      },
      "nav": {
        "backToClosing": "Back to stock balance",
        "stockCard": "Stock card"
      }
    }
  },
  "reportsLibrary": {
    "heading": "All reports",
    "empty": "No reports are available for your role and plan.",
    "breadcrumbLabel": "Reports breadcrumb",
    "libraryLink": "Reports library",
    "moreReports": "More reports",
    "lockLabel": "Locked, upgrade to unlock",
    "areas": {
      "financial-statements": "Financial statements",
      "sales": "Sales",
      "purchases": "Purchases",
      "stock": "Stock",
      "tax": "Tax and e-invoice",
      "controls": "Controls",
      "people": "People"
    },
    "profit-loss": {
      "title": "Profit & Loss",
      "description": "Income, expenses and net profit for a period."
    },
    "trial-balance": {
      "title": "Trial Balance",
      "description": "Debit and credit balance of every account at a date."
    },
    "balance-sheet": {
      "title": "Balance Sheet",
      "description": "Assets, liabilities and equity at a date."
    },
    "cash-flow": {
      "title": "Cash Flow",
      "description": "Where cash came from and where it went in a period."
    },
    "account-activity": {
      "title": "Account Activity",
      "description": "Every posting to one account, with its running balance."
    },
    "financial-intelligence": {
      "title": "Financial Intelligence",
      "description": "Trends, ratios and insights from your books."
    },
    "sales-by-location": {
      "title": "Sales by Location",
      "description": "Daily sales for each outlet or location."
    },
    "sales-by-agent": {
      "title": "Sales by Agent",
      "description": "How much each sales agent sold."
    },
    "ar-aging": {
      "title": "Receivables Aging",
      "description": "Unpaid customer invoices, grouped by how long they are overdue."
    },
    "ar-statements": {
      "title": "Customer Statements",
      "description": "Review and send statements of account to customers."
    },
    "expense-report": {
      "title": "Expense Report",
      "description": "Monthly expense claims by employee and status, with CSV export."
    },
    "ap-aging": {
      "title": "Payables Aging",
      "description": "Unpaid supplier bills, grouped by how long they are overdue."
    },
    "gst-purchase-register": {
      "title": "GST Purchase Register",
      "description": "Purchases with GST, for your Singapore IRAS return."
    },
    "duplicate-expenses": {
      "title": "Duplicate Expenses",
      "description": "Possible duplicate expense claims across the business."
    },
    "audit-trail": {
      "title": "Audit Trail",
      "description": "Who changed what, and when."
    },
    "leave-reports": {
      "title": "Leave Reports",
      "description": "Leave balances and absence reports, in Leave management."
    },
    "closing-stock": {
      "title": "Stock balance as at a date",
      "description": "What was on the shelf on a date, at cost, checked against the Inventory account in your books."
    },
    "stock-card": {
      "title": "Stock card",
      "description": "Every unit in and out of one item: what came in and from whom, what went out and to whom."
    },
    "price-history": {
      "title": "Purchase price history",
      "description": "What you paid for an item, from whom, at what exchange rate, and the margin you make at today's cost."
    },
    "profitability": {
      "title": "Profitability",
      "description": "Profit and margin by customer, invoice, product, category, channel or affiliate."
    },
    "fx-gain-loss": {
      "title": "FX gain and loss",
      "description": "Gains and losses from foreign currency bills and receipts, realised and unrealised."
    },
    "supplier-statement": {
      "title": "Supplier statement",
      "description": "What a supplier has billed, been paid and is still owed, in the currency of each bill."
    },
    "equity-changes": {
      "title": "Statement of Changes in Equity",
      "description": "How equity moved over a period: capital, profit, drawings and dividends."
    }
  },
  "financialIntelligenceUI": {
    "header": {
      "title": "Financial Intelligence",
      "subtitle": "Anomalies, vendor risk, forecasting and spend analytics"
    },
    "entryButton": "Financial Intelligence",
    "actions": {
      "howItWorks": "How it works",
      "viewPayablesDetail": "View payables detail →"
    },
    "tabs": {
      "anomalies": "Anomaly Detection",
      "vendorRisk": "Vendor Risk",
      "forecasting": "Forecasting",
      "spend": "Spend Analytics",
      "priceTrends": "Price Trends"
    },
    "controls": {
      "sensitivity": "Sensitivity",
      "sensitivityHigh": "High",
      "sensitivityMedium": "Medium",
      "sensitivityLow": "Low",
      "window": "Window",
      "window30": "30 days",
      "window90": "90 days",
      "window365": "365 days",
      "horizon": "Horizon"
    },
    "states": {
      "noBusinessSelected": "No business selected",
      "loading": "Loading…"
    },
    "anomalies": {
      "summary": "{anomalies, plural, one {# anomaly} other {# anomalies}} in {transactions} transactions across {categories} categories",
      "emptyTitle": "No anomalies detected",
      "emptySubtitle": "Not enough data, or all transactions are within normal range",
      "table": {
        "description": "Description",
        "category": "Category",
        "amount": "Amount",
        "zScore": "z-score",
        "baseline": "Baseline",
        "severity": "Severity"
      },
      "severityHigh": "High",
      "severityMedium": "Medium",
      "priceAlertsTitle": "Vendor price alerts",
      "priceAlertsEmpty": "No active vendor price alerts",
      "priceAlertsTable": {
        "vendor": "Vendor",
        "type": "Type",
        "oldValue": "Was",
        "newValue": "Now",
        "change": "Change",
        "severity": "Severity"
      }
    },
    "vendorRisk": {
      "riskTitle": "Vendor risk scores",
      "riskSummary": "{high} of {total} vendors flagged high risk",
      "riskEmptyTitle": "No elevated vendor risk",
      "riskEmptySubtitle": "Not enough vendor activity to assess risk",
      "table": {
        "vendor": "Vendor",
        "riskScore": "Risk score",
        "factors": "Factors",
        "recentSpend": "Recent spend",
        "transactions": "Transactions",
        "severity": "Severity"
      },
      "concentrationTitle": "Category concentration",
      "concentrationEmptyTitle": "No concentration risk",
      "concentrationEmptySubtitle": "Spend is well distributed across vendors",
      "concentrationTable": {
        "vendor": "Vendor",
        "category": "Category",
        "share": "Share",
        "vendorSpend": "Vendor spend",
        "categorySpend": "Category spend",
        "severity": "Severity"
      },
      "severityHigh": "High",
      "severityMedium": "Medium",
      "severityLow": "Low"
    },
    "forecasting": {
      "runwayTitle": "Cash runway",
      "runwayDays": "{days} days",
      "runwayOverCap": "More than 5 years",
      "runwayEmptyTitle": "Not enough data",
      "runwayEmptySubtitle": "Cash flow runway needs more posted transactions",
      "monthlyBurn": "Monthly expenses",
      "estimatedBalance": "Cash balance",
      "expenseRatio": "Expense / income ratio",
      "alertsTitle": "Alerts",
      "projectionTitle": "AP / AR projection",
      "projectionEmptyTitle": "No projected cash flow",
      "projectionEmptySubtitle": "No invoices due in the selected window",
      "projectedInflows": "Projected inflows",
      "projectedOutflows": "Projected outflows",
      "netCashFlow": "Net cash flow",
      "agingTitle": "Aging breakdown",
      "runwayNotBurning": "Cash is not falling",
      "runwayUnknown": "Not enough cash history",
      "noCashAccountsTitle": "No bank or cash accounts",
      "noCashAccountsSubtitle": "Add a bank or cash account in Bank / Cash to see your cash runway.",
      "cashUnverifiedTitle": "Cash balance is not available yet",
      "cashUnverifiedSubtitle": "The Cash Book cannot show a verified balance for your bank and cash accounts yet. Bank / Cash, Cash Book shows the state of each account.",
      "cashBuildingTitle": "The Cash Book is being built",
      "cashBuildingSubtitle": "Your balance and runway appear here when it finishes, in a few minutes. You do not need to do anything.",
      "cashNotBuiltTitle": "The Cash Book history has not been built",
      "cashNotBuiltSubtitle": "An owner or finance admin builds it in Bank / Cash, Cash Book: choose the account and press Build history. Your ledger is not affected.",
      "cashNeedsReviewTitle": "A cash account needs a review",
      "cashNeedsReviewSubtitle": "Support has to review the Cash Book for one of your bank or cash accounts before a balance can be shown. Your ledger is not affected.",
      "cashAsAt": "Cash as at {date}",
      "lastStatement": "Bank statement lines up to {date}",
      "foreignExcluded": "Not included (other currency): {accounts}",
      "netCashRunRate": "Net cash change per month",
      "runwayNegative": "Cash is negative",
      "runwayEmpty": "No cash on hand",
      "countedAccounts": "Based on {count, plural, one {# registered bank or cash account} other {# registered bank and cash accounts}}{names}",
      "onlyRegistered": "Only registered bank and cash accounts are counted.",
      "profitViewTitle": "Profit view (not cash)",
      "unregisteredCash": "Cash outside the registered accounts is not counted: {amount} in {accounts}.",
      "unregisteredCashNoAmount": "Cash outside the registered accounts is not counted: {accounts} holds postings.",
      "unregisteredCashAskSupport": "Ask Groot support to count it",
      "profitViewTruncated": "Profit view not shown: more than {limit, number} entries in the last {days, number} days",
      "unregisteredCashIncomplete": "Cash outside the registered accounts is not counted, and there are too many such accounts to total here: {accounts}.",
      "ledgerPayablesGap": "The ledger holds {balance} of payables; {unscheduled} of it is not deducted from the projected cash: it has no due date, is overdue, is due this month, or falls beyond the forecast.",
      "ledgerPayablesUnavailable": "Ledger payables could not be read, so the AP figure covers only open supplier bills with a due date."
    },
    "spend": {
      "title": "Top vendor spend",
      "summary": "Total spend {total} over the period",
      "emptyTitle": "No vendor spend",
      "emptySubtitle": "Not enough posted expense activity in this period",
      "table": {
        "vendor": "Vendor",
        "totalSpend": "Total spend",
        "share": "Share",
        "transactions": "Transactions"
      }
    },
    "howItWorks": {
      "title": "How Financial Intelligence works",
      "intro": "This page surfaces the same server-side intelligence the chat agent uses. It is read-only, computed on demand from your ledger.",
      "stepsHeading": "What each tab shows",
      "step1Title": "Anomaly Detection",
      "step1Desc": "Transactions whose amount is statistically unusual for their category (z-score), plus vendor price-change alerts.",
      "step2Title": "Vendor Risk",
      "step2Desc": "Risk scores per vendor and categories where one vendor dominates spend (concentration risk).",
      "step3Title": "Forecasting",
      "step3Desc": "Cash-flow runway and burn rate, plus projected AP outflows vs AR inflows for the window.",
      "step4Title": "Spend Analytics",
      "step4Desc": "Top vendors by spend and each vendor's share of the total.",
      "goodToKnowHeading": "Good to know",
      "goodToKnow1": "This is a read-only view, so nothing here is editable. Manage vendors and invoices in Payables and Invoices.",
      "goodToKnow2": "Each tab loads its data only when you open it, to keep things fast.",
      "goodToKnow3": "Empty states mean there isn't enough data yet, not an error.",
      "goodToKnow4": "Ask the chat agent the same questions for a conversational answer."
    },
    "priceTrends": {
      "headlineTop": "{item} is up {pct}%",
      "headlineTopSuffix": "(your biggest cost increase this period).",
      "headlineNoIncrease": "No cost increases this period.",
      "headlineSummary": "{up, plural, one {# item trending up} other {# items trending up}}, {down} down over the last {days} days · across confirmed purchases only.",
      "periodLabel": "Period",
      "period30": "30d",
      "period90": "90d",
      "period180": "180d",
      "period365": "365d",
      "direction": {
        "all": "All",
        "up": "↑ Increases",
        "down": "↓ Decreases"
      },
      "confirmedBuys": "{n, plural, one {# confirmed buy} other {# confirmed buys}}",
      "showingTopN": "Showing top {n} of {total} movers",
      "cappedNotice": "Bounded for performance. Refine the period to see more.",
      "confirmedOnly": "Confirmed (posted) prices only",
      "backToList": "Back to Price Trends",
      "emptyTitle": "No price trends yet",
      "emptySubtitle": "Trends appear automatically as you post purchase invoices. Once an item has been bought twice, its price movement shows here.",
      "errorTitle": "Price trends are temporarily unavailable",
      "errorSubtitle": "We could not load your price movers just now. Please try again shortly."
    }
  },
  "reportingExports": {
    "sqlMasterData": {
      "guidance": {
        "title": "Import-first workflow",
        "intro": "SQL Accounting imports masters in order. Set them up before importing transactions:",
        "step1": "Export or check your existing SQL master data.",
        "step2": "Import any missing masters into SQL Accounting.",
        "step3": "Import transactions that reference those masters.",
        "exportDirection": "Export master data from Groot to SQL: Groot builds files to seed SQL Accounting.",
        "importDirection": "Import SQL master data into Groot so exports reuse the codes SQL already has.",
        "importLink": "Import your SQL master data",
        "stockPrereqTitle": "Stock Items need Stock Groups and UOMs first",
        "stockPrereqBody": "SQL rejects a Stock Item import unless its STOCKGROUP and base UOM already exist. Export Stock Groups and Units of Measure first, or import your SQL masters so Groot can check.",
        "noSnapshotBody": "No imported SQL master data found, so Groot can't confirm which Stock Groups and UOMs exist in your SQL company.",
        "acknowledge": "I understand SQL requires these masters to exist, and I want to continue without Groot verifying them.",
        "verifiedAgainstStock": "Checked against your imported SQL stock masters."
      },
      "readiness": {
        "title": "Export readiness",
        "summaryReady": "{count} ready",
        "summaryBlocked": "{count} need attention",
        "summaryExcluded": "{count} already in SQL",
        "allReady": "All records are ready to export.",
        "missingTitle": "Missing in SQL Accounting",
        "missingStockGroups": "Stock groups not found in SQL: {codes}",
        "missingUoms": "Units of measure not found in SQL: {codes}",
        "resolveHint": "Export Stock Groups and Units of Measure first, or confirm you created them in SQL.",
        "manualOverride": "I've already created these stock groups and UOMs in SQL Accounting.",
        "includeAll": "Include records that already exist in SQL",
        "includeAllHint": "By default only records missing from SQL are exported.",
        "excludedNote": "{count} records already exist in SQL and are excluded by default.",
        "sourceTruncated": "Groot checked {count} source rows, then stopped at the safety limit of {cap}. Narrow or repair the catalog before downloading.",
        "sourceUnavailable": "Groot could not verify this master list right now. Refresh and try again before downloading.",
        "blockedNote": "Resolve the issues above before downloading."
      },
      "actions": {
        "title": "Seed directly into SQL Accounting",
        "hint": "Create these records in SQL using its own Import screen. The same tools also appear during invoice export."
      },
      "requeue": {
        "button": "Re-queue for SQL export",
        "hint": "Reset this invoice so it appears again under \"Not exported\".",
        "confirmBody": "Re-queue this invoice for SQL export?",
        "confirmBodyMany": "Re-queue {count} invoices for SQL export?",
        "confirmHint": "Use this if the SQL import failed or you deleted the invoice in SQL Accounting. The invoice reappears under the \"Not exported\" filter.",
        "confirmAction": "Re-queue",
        "cancel": "Cancel",
        "toast": {
          "successTitle": "Re-queued for SQL export",
          "successBody": "{count} invoice(s) reset and will appear under \"Not exported\".",
          "errorTitle": "Couldn't re-queue",
          "errorBody": "Something went wrong resetting the SQL export status. Please try again."
        }
      }
    },
    "sqlPiReadiness": {
      "title": "SQL import readiness",
      "summaryReady": "{count} ready",
      "summaryNeedsAttention": "{count} need attention",
      "issuesTitle": "Resolve before exporting to SQL Accounting",
      "missingSupplierCode": "{count} invoice(s) have a supplier with no SQL creditor code",
      "missingItemCode": "{count} invoice(s) have line items with no SQL item code",
      "missingAccount": "{count} invoice(s) have no resolvable account",
      "mastersFirstTitle": "Import these masters into SQL first",
      "mastersFirstHint": "New suppliers and items must already exist in SQL Accounting before this Purchase Invoice imports. Use the SQL master-data export to create them first.",
      "newSuppliersLabel": "New suppliers ({count}):",
      "newItemsLabel": "New items ({count}):",
      "andMore": " and {count} more",
      "scanCapped": "Assessed the first {count} invoices. Narrow the date range to check the rest.",
      "allReady": "All invoices are ready to import into SQL.",
      "empty": "No invoices to assess."
    },
    "header": {
      "title": "Import & Export",
      "subtitle": "Export your expense, invoice and accounting data to CSV",
      "subtitleGeneral": "Move your expense, invoice and accounting data in and out of Groot"
    },
    "mainTabs": {
      "ariaLabel": "Import or export data",
      "import": "Import",
      "export": "Export"
    },
    "importTab": {
      "status": {
        "processingLabel": "Processing",
        "completedLabel": "Backup read, nothing imported yet",
        "failedLabel": "Import failed",
        "processingBody": "Extraction runs in the background, so you can leave this page.",
        "failedBody": "Something went wrong during import. Please try again.",
        "restricted": "Import status is only visible to the business owner or a finance admin.",
        "counts": {
          "accounts": "{count} accounts",
          "suppliers": "{count} suppliers",
          "customers": "{count} customers",
          "items": "{count} items",
          "none": "No records imported"
        },
        "time": {
          "justNow": "Just now",
          "minutes": "{count}m ago",
          "hours": "{count}h ago",
          "days": "{count}d ago"
        }
      },
      "title": "Import into Groot",
      "description": "Bring codes and master data from your SQL Account file into Groot so exports line up with your accounting software.",
      "cards": {
        "expenseCategories": {
          "title": "Expense categories",
          "description": "SQL Account expense GL codes become Groot expense categories with matching GL codes."
        },
        "cogsCategories": {
          "title": "COGS categories",
          "description": "SQL Account cost-of-goods GL codes become Groot COGS categories with matching GL codes."
        },
        "suppliers": {
          "title": "Suppliers (creditor codes)",
          "description": "SQL supplier codes auto-fill the CODE column on AP invoice exports."
        },
        "customers": {
          "title": "Customers (debtor codes)",
          "description": "SQL customer codes auto-fill the CODE column on AR invoice exports."
        }
      },
      "toasts": {
        "categoriesImported": {
          "title": "Categories imported",
          "description": "Imported {created} categories ({skipped} skipped)"
        }
      },
      "backupCard": {
        "title": "Import everything from a SQL Account backup",
        "description": "Upload one backup file and we extract your expense GL accounts, COGS accounts, suppliers and customers in a single pass. Import whatever it contains."
      },
      "orImportOne": "or import one at a time",
      "backup": {
        "title": "Import everything from a SQL Account backup",
        "subtitle": {
          "upload": "Upload one backup and we extract your chart of accounts, suppliers and customers. Then import whichever categories you need.",
          "extracting": "We extract only your master data from the backup. The file itself is deleted right after.",
          "review": "Here's what we found. Import all of it, or pick one category at a time."
        },
        "dropzone": {
          "title": "Upload SQL Account backup (.zip)",
          "description": "One file, we do the rest. We extract only your master data: chart of accounts, suppliers and customers. The backup is deleted immediately after.",
          "howTo": "How to create a backup"
        },
        "uploading": "Uploading backup… {pct}%",
        "processingTitle": "Processing your backup (~3-5 min)",
        "processingBody": "Extraction runs in the background, so you can safely close this window. Come back to this page (or Settings → Integrations) any time to see the result.",
        "categories": {
          "expense": "Expense categories",
          "cogs": "COGS categories",
          "suppliers": "Suppliers (creditor codes)",
          "customers": "Customers (debtor codes)"
        },
        "chartOfAccounts": "Chart of Accounts",
        "selectAll": "Select all",
        "loadingBreakdown": "Loading your chart of accounts…",
        "accountTypes": {
          "asset": "Assets",
          "liability": "Liabilities",
          "equity": "Equity",
          "revenue": "Revenue",
          "expense": "Expenses",
          "cogs": "Cost of sales (COGS)"
        },
        "unclassifiedNote": "{count} accounts couldn't be typed and won't be imported",
        "found": {
          "count": "{count} found",
          "none": "None found in this backup"
        },
        "imported": "Imported {created} ({skipped} skipped)",
        "importedTotal": "Imported {created} accounts and codes",
        "starterReplacement": {
          "replaced": "Replaced {archived} sample accounts with your imported chart.",
          "replacedKept": "Replaced {archived} sample accounts with your imported chart. {kept} stayed because they are still in use, such as default posting accounts. Choose your own defaults in Payment & posting, then archive the rest from the Chart of Accounts.",
          "keptOnly": "{kept} sample accounts stayed because they are still in use, such as default posting accounts. Choose your own defaults in Payment & posting, then archive the rest from the Chart of Accounts.",
          "skipped": "Your sample accounts were left as they are because Groot could not check them automatically. Contact support and we will tidy them up."
        },
        "ownChartReplacement": {
          "replaced": "Archived {archived, plural, one {# account of yours} other {# accounts of yours}} that nothing was using, and brought in your imported chart.",
          "replacedKept": "Archived {archived, plural, one {# account of yours} other {# accounts of yours}} that nothing was using. {kept, plural, one {# stayed because it is} other {# stayed because they are}} still in use, for example by postings or a posting role. Archive the rest from the Chart of Accounts when you are ready.",
          "keptOnly": "{kept, plural, one {# of your accounts stayed because it is} other {# of your accounts stayed because they are}} still in use, for example by postings or a posting role.",
          "skipped": "Your existing accounts were left as they are because Groot could not check them automatically. Contact support and we will tidy them up."
        },
        "importOne": "Import",
        "importAll": "Import all available",
        "importSelected": "Import selected",
        "importing": "Importing…",
        "done": "Done",
        "tryAgain": "Try again",
        "errors": {
          "empty": "The backup was processed but no importable master data was found in it.",
          "processing": "We could not process this backup. Please try again, or use the per-category CSV import below.",
          "timeout": "Processing is taking longer than expected. You can safely close this window and check back later, or try uploading the backup again.",
          "noBusiness": "No active business selected.",
          "uploadFailed": "Backup upload failed. Please try again.",
          "importFailed": "Import failed. Please try again.",
          "jobNotFound": "We couldn't find that backup any more. Upload it again, then import.",
          "jobNotReady": "That backup hasn't finished processing yet. Wait for it to finish, then import.",
          "tooManyRows": "This backup holds more rows than one import can take (2,000 maximum). Import a smaller export instead."
        }
      },
      "providerLabel": "Accounting software",
      "providerHelp": "Choose which software you are importing from.",
      "noProviders": "No accounting software is available to import from yet.",
      "entity": {
        "nouns": {
          "suppliers": "suppliers",
          "customers": "customers",
          "supplier": "supplier",
          "customer": "customer"
        },
        "title": "Import {entity} from accounting software",
        "subtitle": {
          "choose": "Bring your {entitySingular} list in from SQL Account to fill the SQL {entitySingular} codes used by the SQL Account exports.",
          "source": "Upload your SQL Account {entitySingular} export: two columns, code and name.",
          "pick": "Pick the {entity} to import.",
          "pickWithSource": "Pick the {entity} to import. Source: {fileName}",
          "done": "Import complete."
        },
        "csvDropzone": {
          "title": "Upload a CSV/Excel export instead",
          "description": "Two columns, code and name (.csv, .txt, .psv or .xlsx). A header row is optional."
        },
        "chooseFile": "Choose a file",
        "chooseFileHint": ".csv, .txt, .psv or .xlsx: two columns, code and name (header row optional)",
        "backupFileName": "SQL Account backup",
        "searchPlaceholder": "Search by code or name...",
        "selectAllFiltered": "Select all (filtered)",
        "noMatches": "No {entity} match the current search.",
        "alreadyImported": "already imported",
        "selectedSummary": "{selected} selected of {shown} shown",
        "importCodes": "{count, plural, one {Import # {entitySingular} code} other {Import # {entitySingular} codes}}",
        "importedSummary": "{created, plural, one {Imported # {entitySingular} code} other {Imported # {entitySingular} codes}} ({updated} updated, {skipped} skipped)",
        "errors": {
          "parseFailed": "We couldn't read that file. Check that it has two columns (code and name), then try again.",
          "backupImportFailed": "We couldn't import from this backup. Please try a CSV or Excel export instead.",
          "noneFound": "The backup was processed but no {entity} were found in it.",
          "noRows": "No {entitySingular} rows found in this file. Expected columns: code and name.",
          "nothingSelected": "No importable rows selected: each row needs both a code and a {entitySingular} name.",
          "timeout": "Processing is taking longer than expected. Please try uploading the backup again, or upload a CSV or Excel export instead."
        }
      }
    },
    "tabs": {
      "reports": "Reports",
      "export": "Export",
      "templates": "Templates",
      "schedules": "Schedules",
      "history": "History"
    },
    "moduleLabels": {
      "expense": "Expense Claims",
      "invoice": "Invoices",
      "leave": "Leave Records",
      "accounting": "Accounting Records",
      "masterData": "Master Data",
      "timesheet": "Timesheets"
    },
    "reports": {
      "loadingGenerator": "Loading report generator...",
      "duplicateExpenseReport": "Duplicate Expense Report",
      "arAgingReport": "AR Aging Report"
    },
    "steps": {
      "selectModule": {
        "title": "Select Module",
        "description": "Choose which data you want to export"
      },
      "chooseTemplate": {
        "title": "Choose Template",
        "description": "Select a pre-built or custom export template",
        "emptyMessage": "No templates available for {module} module"
      },
      "mapCodes": {
        "title": "Map Codes",
        "description": "Map Groot Finance values to {system} codes",
        "completedSummary": "Codes mapped"
      },
      "filterExport": {
        "title": "Filter & Export",
        "description": "Apply filters and preview your export",
        "backToMapCodes": "Back to Map Codes",
        "duplicateWarning": "Re-exporting the same records may create duplicates in Master Accounting. Ensure you haven't already imported these records."
      },
      "lineItemReview": {
        "title": "Review quantities & unit prices",
        "description": "These quantities & unit prices become the stock received & cost in SQL Account.",
        "caption": "These quantities & unit prices become the stock received & cost in SQL Account. OCR often sets quantity to 1 and unit price to the line total. Correct any line before exporting.",
        "colInvoice": "Invoice No.",
        "colSupplier": "Supplier",
        "colItemCode": "Item Code",
        "colDescription": "Description",
        "colQuantity": "Quantity",
        "colUnitPrice": "Unit Price",
        "hint": "{count} line item(s) will be imported with the quantities & unit prices above.",
        "empty": "No purchase invoice line items to review."
      }
    },
    "templatesTab": {
      "title": "Export Templates",
      "description": "Manage your custom export templates",
      "createTemplate": "Create Template",
      "emptyMessage": "No custom templates yet. Click 'Create Template' to get started."
    },
    "schedulesTab": {
      "title": "Scheduled Exports",
      "description": "Configure automated export schedules",
      "newSchedule": "New Schedule",
      "emptyMessage": "No schedules configured. Click 'New Schedule' to set up automated exports."
    },
    "historyTab": {
      "title": "Export History",
      "description": "View and re-download past exports",
      "emptyTitle": "No Export History",
      "emptyDescription": "Your export history will appear here after you run your first export",
      "recordCount": "{count} records",
      "redownloadAriaLabel": "Re-download export",
      "status": {
        "completed": "completed",
        "failed": "failed",
        "processing": "processing",
        "pending": "pending"
      }
    },
    "templateCopyName": "{name} (Copy)",
    "unknownTemplate": "Unknown Template",
    "toasts": {
      "tryAgain": "Please try again.",
      "templateCloned": {
        "title": "Template cloned",
        "description": "You can now customize this template."
      },
      "templateCloneFailed": {
        "title": "Failed to clone template"
      },
      "templateDeleted": {
        "title": "Template deleted",
        "description": "The template has been removed."
      },
      "templateDeleteFailed": {
        "title": "Failed to delete template"
      },
      "exportCompleted": {
        "title": "Export completed",
        "description": "Successfully exported {count} records."
      },
      "exportTruncated": {
        "title": "Export limited to {exported} records",
        "description": "{omitted} of {total} records were not included because the export caps at {exported}. Narrow your filters and export again to capture the rest."
      },
      "exportRecordsUnavailable": {
        "title": "Couldn't load the records for this export",
        "description": "Nothing was exported. Try again, or narrow the date range or filters if the range is very large. Contact support if this keeps happening."
      },
      "exportFailed": {
        "title": "Export failed",
        "description": "Couldn't generate the SQL export. Please try again, or contact support if the problem continues."
      },
      "exportNotRecorded": {
        "title": "Export completed, but not recorded",
        "description": "Groot could not mark these payment runs as exported, so they still show under New only. Check SQL Account before you export them again, or the vouchers will post twice."
      },
      "redownloadUnavailable": {
        "title": "Re-download unavailable",
        "description": "Please run a new export to download the data."
      },
      "scheduleCreated": {
        "title": "Schedule created",
        "description": "Your automated export has been scheduled."
      },
      "scheduleCreateFailed": {
        "title": "Failed to create schedule"
      },
      "scheduleEnabled": {
        "title": "Schedule enabled",
        "description": "The export will run on schedule."
      },
      "scheduleDisabled": {
        "title": "Schedule disabled",
        "description": "The export has been paused."
      },
      "scheduleUpdateFailed": {
        "title": "Failed to update schedule"
      },
      "scheduleDeleted": {
        "title": "Schedule deleted",
        "description": "The automated export has been removed."
      },
      "scheduleDeleteFailed": {
        "title": "Failed to delete schedule"
      },
      "templateDeleteBlockedInUse": "This template is used by an export schedule, so it can't be deleted. Delete that schedule, or point it at another template first."
    },
    "accessRestricted": {
      "title": "Exports access is restricted",
      "description": "Your role does not include access to data exports. Ask a business owner or Finance if you need an export."
    },
    "masterSeed": {
      "title": "Set up new {entity} in SQL first",
      "suppliers": "suppliers",
      "customers": "customers",
      "show": "Show",
      "hide": "Hide",
      "help": "SQL Account rejects invoices whose code isn't yet a creditor/customer. Copy this list, paste into SQL: {screen} → Paste From Clipboard → Validate → Import. Then your invoice export will import cleanly.",
      "loading": "Loading…",
      "none": "No entities found to seed.",
      "copy": "Copy {count} for SQL Account",
      "copied": "Copied. Paste into SQL: {screen}",
      "download": "Download .txt"
    },
    "stockWriteback": {
      "title": "New items to add to SQL",
      "show": "Show",
      "hide": "Hide",
      "help": "These items came from your invoices but don't exist in SQL Account yet. Copy or download the list, import it via SQL: Stock → Import Stock Item. SQL assigns each item a code. Groot can then stamp it on future exports automatically.",
      "loading": "Loading…",
      "none": "No new items. Every item on your invoices already exists in SQL.",
      "copy": "Copy {count} for SQL Account",
      "copied": "Copied. Paste into SQL: Stock → Import Stock Item",
      "copyFailed": "Couldn't copy to clipboard. Use Download .csv instead.",
      "partial": "Showing {shown} of {total}. The other {omitted} aren't in this export. Import these into SQL first, then reopen to export the rest.",
      "download": "Download .csv",
      "reviewIntro": "Review each item, then confirm. Groot suggests a code. Edit it to match your SQL naming. The stock group and unit must already exist in SQL.",
      "colItem": "Item",
      "colCode": "Code",
      "colGroup": "Stock group",
      "colUom": "Unit",
      "colCost": "Cost",
      "confirmDownload": "Confirm & download .csv",
      "confirmCopy": "Confirm & copy",
      "confirming": "Confirming…",
      "confirmedN": "Confirmed {count} item(s). Import into SQL: Stock → Import Stock Item, then re-export your invoice.",
      "needFields": "Every item needs a code and a stock group before exporting.",
      "newGroupWarn": "New stock group(s) not yet in SQL: {groups}. Create them first (Stock → Maintain Stock Group) or download the group file.",
      "downloadGroups": "Download new-group file",
      "confirmPartial": "Downloaded, but couldn’t confirm {count} item(s): {error}. They stay in the list, so you can try again.",
      "uomNewWarn": "New unit(s) not yet in SQL: {uoms}. Make sure they exist in SQL (Stock → Maintain UOM) first, or SQL will reject the line."
    },
    "purchaseImportMode": {
      "label": "Purchases import as:",
      "expense": "Expense lines",
      "itemized": "Itemized",
      "needAliases": "(import your SQL item list to enable itemized)",
      "change": "Change"
    },
    "modules": {
      "expense": {
        "name": "Expense Claims",
        "description": "Export expense claims and reimbursements"
      },
      "invoice": {
        "name": "Invoices",
        "description": "Export AP and AR invoices at all stages"
      },
      "leave": {
        "name": "Leave Records",
        "description": "Export leave requests, approvals, and balances"
      },
      "accounting": {
        "name": "Accounting Records",
        "description": "Export posted journal entries"
      },
      "masterData": {
        "name": "Master Data",
        "description": "Export vendors, customers, chart of accounts, and more"
      },
      "timesheet": {
        "name": "Timesheets",
        "description": "Export payroll-ready hours, overtime and attendance"
      }
    },
    "sqlGridOptions": {
      "title": "{provider} output",
      "description": "Choose how the grid gets into {provider}.",
      "ariaLabel": "{provider} output format",
      "outputOptions": {
        "tsv": "TSV - copy & paste into {provider} (easiest)",
        "csv": "CSV (pipe) - file for {provider}'s free Import tool",
        "text": "Text Import (.txt, semicolon)"
      },
      "creditAccount": {
        "label": "Credit account (SQL GL code)",
        "placeholder": "e.g. 320-000",
        "help": "Credited on every journal entry - e.g. your staff-claims liability or bank account (like 320-000)",
        "required": "Credit account is required: enter the SQL GL code to credit (e.g. 320-000)."
      },
      "copy": {
        "copying": "Copying...",
        "copied": "Copied - paste into {provider}: {path}",
        "idle": "Copy for {provider}",
        "downloadHint": "Or use Download to save the .txt file.",
        "copiedNoPath": "Copied - paste into {provider}",
        "perInvoiceHint": "Clipboard paste is SQL Account's built-in import (File > Import, no install). The .csv needs SQL's separate Import-from-Excel tool. Or export many at once in <link>Exports > SQL Accounting (AP Invoice)</link>"
      },
      "warnings": {
        "skippedRows": "{count} rows skipped - unmapped; fix in Settings > Categories / Mapping",
        "notPostedClaims": "{count, plural, one {# claim} other {# claims}} left out: only approved or reimbursed claims are booked",
        "notPaidClaims": "{count, plural, one {# claim} other {# claims}} left out: only reimbursed claims are booked as payments"
      }
    },
    "claimsLeftOut": {
      "noAmount": {
        "noHomeFigure": {
          "title": "{count, plural, one {# claim} other {# claims}} left out: no home currency amount on record ({names}{more, plural, =0 {} other { and # more}})",
          "action": "Open the claim and check its exchange rate under Accounting → Chart of Accounts / Exchange rates, or enter it in your accounting system by hand."
        },
        "approvalPostingShared": {
          "title": "{count, plural, one {# claim} other {# claims}} left out: approved in one posting with other claims, so its own amount is not recorded ({names}{more, plural, =0 {} other { and # more}})",
          "action": "Open the claim to see its approved amount, then enter it in your accounting system by hand."
        },
        "paymentNotProvable": {
          "title": "{count, plural, one {# claim} other {# claims}} left out: the amount paid for it cannot be confirmed from its own payment record ({names}{more, plural, =0 {} other { and # more}})",
          "action": "Open the claim to see when and how it was paid, then enter the payment in your accounting system by hand using the amount on your bank statement."
        },
        "noAmount": {
          "title": "{count, plural, one {# claim} other {# claims}} left out: no amount on record ({names}{more, plural, =0 {} other { and # more}})",
          "action": "Open the claim and check its amount."
        },
        "noBilledAmount": {
          "title": "{count, plural, one {# claim} other {# claims}} left out: no bill export on record, so there is no amount to reverse ({names}{more, plural, =0 {} other { and # more}})",
          "action": "Groot reverses the amount it printed on the bill. If you imported a bill for one of these claims, raise the debit note in Master Accounting by hand for the amount on that bill."
        }
      }
    },
    "prebuiltTemplates": {
      "names": {
        "sqlAccountingJournalEntry": "SQL Accounting (Journal Entry)",
        "sqlAccountingGlJournal": "SQL Accounting (GL Journal)",
        "sqlAccountingApInvoice": "SQL Accounting (AP Invoice)",
        "sqlAccountingArInvoice": "SQL Accounting (AR Invoice)",
        "sqlAccountingCreditorsSuppliers": "SQL Accounting Creditors/Suppliers",
        "sqlAccountingDebtorsCustomers": "SQL Accounting Debtors/Customers",
        "sqlAccountingStockGroups": "SQL Accounting Stock Groups",
        "sqlAccountingUnitsOfMeasure": "SQL Accounting Units of Measure",
        "sqlAccountingStockItems": "SQL Accounting Stock Items",
        "sqlAccountingChartOfAccounts": "SQL Accounting Chart of Accounts",
        "sqlAccountingCashBookPayment": "SQL Accounting (Cash Book - Payment Voucher)"
      },
      "descriptions": {
        "sqlAccountingCashBookPayment": "Import at File > Import > GL > Cash Book - Payment Voucher. Requires SQL Account Build 70 or later.",
        "sqlAccountingGlJournal": "Journals with no document of their own in SQL, such as ones keyed by hand. Bills, sales invoices, their payments and refunds, and expense claims are left out."
      }
    },
    "exportErrors": {
      "templateRetired": "This export template has been retired because it didn't match the target system's import format. Pick a current template."
    },
    "timesheetExport": {
      "stepTitle": "Payroll export",
      "stepDescription": "Hand these hours to whoever pays them",
      "templateLabel": "Format",
      "needsDateRange": "Choose a date range to see the pay periods it covers.",
      "unavailable": "Timesheet data is not available for your account. Ask an owner or finance admin to run this export.",
      "generating": "Preparing your file…",
      "blocked": {
        "title": "{count} timesheets are not ready to export",
        "description": "A pay period is exported whole or not at all, so nothing is downloaded until every timesheet below is approved. Exporting part of a period produces a payroll file that looks complete and quietly leaves people out.",
        "columnEmployee": "Employee",
        "columnPeriod": "Pay period",
        "columnStatus": "Status"
      },
      "truncated": {
        "employees": "This business has more employees than one export covers. Some people are missing from this file. Narrow the date range, or contact support.",
        "periods": "Some pay periods are missing from this file because one employee has more of them in this range than an export covers. Narrow the date range.",
        "adjustments": "Some carried-forward adjustments are missing from this file. Narrow the date range."
      },
      "policy": {
        "overtimePaid": "Groot prices overtime for this business, so overtime is already reflected in payroll.",
        "overtimeNotPaid": "Groot does not price overtime for this business. These hours are recorded, not paid. Hand them to whoever pays them.",
        "deductionsApplied": "Groot applies attendance deductions for this business.",
        "deductionsNotApplied": "Groot does not apply attendance deductions. The deduction hours below are reported for your information only.",
        "unweightedNote": "Overtime hours are listed per rate tier with the multiplier that applied. Any total marked \"unweighted\" counts every overtime minute once, so price it from the tiers rather than from that total."
      },
      "downloadFailed": {
        "title": "Export failed",
        "description": "We could not build your file. Please try again."
      }
    },
    "templateUnavailable": "This export template is not available for your workspace. Pick another template or contact support@hellogroot.com.",
    "mergedDocumentsHeldBack": "{count, plural, one {Groot left # supplier bill out of this file.} other {Groot left # supplier bills out of this file.}} A PDF that holds more than one invoice stays out until someone confirms it is a single invoice. Open the bill and confirm that, or upload each invoice as its own file.",
    "documentJournalsLeftOut": "{count, plural, one {Groot left # journal out of this file.} other {Groot left # journals out of this file.}} SQL keeps supplier bills, sales invoices, their payments and refunds, and expense claims as documents of its own, so their journals stay off this card. Send bills, sales invoices and expense claims on their own cards, and record payments and refunds in SQL."
  },
  "statementsReview": {
    "pageTitle": "Statements Review",
    "pageSubtitle": "Review and send debtor statements",
    "backToReports": "Back to Reports",
    "autoSendBanner": {
      "message": "Tired of reviewing every month? Enable auto-send to deliver statements automatically.",
      "settingsButton": "Settings"
    },
    "pendingReviewCount": "{n, plural, one {# statement pending review for {period}} other {# statements pending review for {period}}}",
    "selectAll": "Select All",
    "deselectAll": "Deselect All",
    "sendSelected": "Send Selected ({n})",
    "tableTitle": "Debtor Statements ({period})",
    "emptyState": {
      "title": "No debtor statements for this period",
      "description": "Generate monthly reports to create debtor statements"
    },
    "noEmailCell": "No email",
    "disclaimerBadge": "Disclaimer",
    "table": {
      "debtor": "Debtor",
      "email": "Email",
      "outstanding": "Outstanding",
      "invoices": "Invoices",
      "status": "Status",
      "actions": "Actions"
    },
    "status": {
      "pending": "Pending",
      "sent": "Sent",
      "autoSent": "Auto-Sent",
      "failed": "Failed",
      "noEmail": "No Email"
    },
    "actions": {
      "previewPdf": "Preview PDF"
    },
    "toasts": {
      "sendSuccess": "{n, plural, one {# statement sent successfully} other {# statements sent successfully}}",
      "sendPartialFailure": "{n, plural, one {# statement failed to send} other {# statements failed to send}}"
    },
    "errors": {
      "sendFailed": "Send failed",
      "sendStatementsFailed": "We couldn't send those statements. Please try again; none of them were sent.",
      "previewFailed": "Failed to load preview",
      "noneSelected": "Select at least one statement to send.",
      "sendFailedGeneric": "We couldn't send those statements. Please try again; none of them were sent."
    }
  },
  "financialStatements": {
    "header": {
      "title": "Financial Statements"
    },
    "tabs": {
      "trialBalance": "Trial Balance",
      "profitLoss": "Profit & Loss",
      "balanceSheet": "Balance Sheet",
      "cashFlow": "Cash Flow",
      "accountActivity": "General Ledger",
      "fxGainLoss": "FX gain/loss",
      "equityChanges": "Equity changes"
    },
    "periodSelector": {
      "presets": {
        "thisMonth": "This Month",
        "lastMonth": "Last Month",
        "thisQuarter": "This Quarter",
        "lastQuarter": "Last Quarter",
        "thisFinancialYear": "This Financial Year",
        "lastFinancialYear": "Last Financial Year"
      },
      "asOf": "As of",
      "startDate": "Start date",
      "endDate": "End date",
      "help": {
        "pointInTime": "Trial Balance and Balance Sheet are as-of reports: they include posted balances up to the selected date.",
        "range": "Profit & Loss and Cash Flow include posted activity between the start and end dates."
      }
    },
    "exportButtons": {
      "pdf": "Export PDF",
      "csv": "Export CSV",
      "pdfGenerating": "Preparing the PDF…",
      "pdfDownloadStarted": "Download started. The PDF can take a few seconds to appear in your downloads. If it does not, export again.",
      "pdfFailed": "We couldn't generate the PDF. Please try again.",
      "pdfNoData": "No transactions in the selected period, so there is nothing to export yet."
    }
  },
  "settingsBilling": {
    "header": {
      "title": "Billing",
      "subtitle": "Manage your subscription and usage"
    },
    "celebration": {
      "title": "Welcome to Pro!",
      "subtitle": "Your upgrade is complete"
    },
    "countryDeclaration": {
      "title": "Set Your Business Region",
      "description": "Required to lock your billing currency. This cannot be changed later.",
      "countryLabel": "Region",
      "countryMalaysia": "Malaysia",
      "countrySingapore": "Singapore",
      "countryTaiwan": "Taiwan",
      "regNumberLabel": "Business Registration Number",
      "regNumberPlaceholderSG": "e.g. 200012345X",
      "regNumberPlaceholderMY": "e.g. 1234567-H",
      "regNumberPlaceholderTW": "e.g. 12345675",
      "currencyLockPrefix": "Your billing currency will be locked to",
      "settingUp": "Setting up...",
      "confirmButton": "Confirm Region & Lock Currency",
      "setCountryError": "Failed to set region"
    },
    "successBanner": {
      "title": "Welcome to your new plan!",
      "description": "Your subscription is now active. Enjoy your upgraded features!"
    },
    "canceledBanner": {
      "message": "Checkout was canceled. Your subscription has not changed."
    },
    "error": {
      "loadFailed": "We could not load your subscription details.",
      "retry": "Retry"
    },
    "status": {
      "active": "Active",
      "trial": "Trial",
      "pastDue": "Past Due",
      "canceled": "Canceled"
    },
    "currentPlan": {
      "title": "Current Plan",
      "description": "Your subscription details",
      "planLabel": "Plan",
      "priceLabel": "Price",
      "priceValue": "{currency} {price}/month",
      "trialPeriodLabel": "Trial Period",
      "trialExpired": "Expired",
      "trialDaysLeft": "{days} days left",
      "trialDayProgress": "Day {used}/{total}",
      "nextBillingDateLabel": "Next Billing Date",
      "cancelAtPeriodEnd": "Subscription will cancel at end of period",
      "manageSubscription": "Manage Subscription",
      "upgradePlan": "Upgrade Your Plan",
      "comparePlans": "Compare Plans",
      "portalUnavailable": "We couldn't open the billing portal just now. Please try again in a moment."
    },
    "ocrUsage": {
      "title": "OCR Usage",
      "description": "Document processing credits this month",
      "documentsProcessed": "documents processed",
      "unlimitedEnterprise": "Unlimited OCR scans with your Enterprise plan",
      "scansUsed": "{used} / {limit} scans used",
      "approachingLimit": "You're approaching your OCR limit. Consider upgrading for more scans."
    },
    "planFeatures": {
      "title": "Plan Features",
      "description": "What's included in your {planName} plan",
      "showLess": "Show less",
      "seeAllFeatures": "See all features"
    }
  },
  "settingsBusiness": {
    "header": {
      "title": "Business Profile",
      "subtitle": "Manage your company information and basic settings"
    },
    "backToBusinessSettings": "Back to Business Settings",
    "companyInformation": {
      "heading": "Company Information",
      "description": "Update your business profile and branding"
    },
    "loadingBusinessProfile": "Loading business profile...",
    "invoiceReview": {
      "title": "Supplier invoice review",
      "description": "Choose what happens when an uploaded supplier invoice is read.",
      "onConsequence": "On: each uploaded bill waits as a draft until someone confirms and posts it.",
      "offConsequence": "Off: uploaded bills post automatically, and a bill whose supplier was read incorrectly cannot be relinked afterwards.",
      "toggle": "Require review before posting",
      "loading": "Loading invoice review setting",
      "unavailable": "Invoice review settings are unavailable for this business.",
      "manage": "Manage invoice review",
      "errors": {
        "title": "Invoice review settings error",
        "body": "Something went wrong loading invoice review settings. Your settings are safe.",
        "retry": "Try again",
        "reload": "Reload page",
        "supportHint": "If this keeps happening, contact support."
      },
      "saveFailed": "Groot could not save that change. Please try again.",
      "unknownRefusal": "Groot could not change invoice review. Please refresh and try again.",
      "sqlBridgeRequiresReview": "Pause automatic sending to SQL Account before you turn review off.",
      "autoCountRequiresReview": "Pause automatic sending to AutoCount before you turn review off."
    },
    "integrations": {
      "lark": {
        "title": "Lark Expense Claims",
        "beta": "Beta",
        "description": "Let employees submit receipts and managers review expense claims from a private chat with your own Lark bot.",
        "loading": "Loading Lark integration",
        "status": {
          "provisioning": "Provisioning",
          "awaiting_callbacks": "Setup required",
          "connected": "Connected",
          "degraded": "Needs attention",
          "disabled": "Disabled",
          "revoked": "Revoked",
          "disconnected": "Disconnected"
        },
        "notEnabled": {
          "title": "Lark Beta is not enabled",
          "description": "Ask Groot support to enable the Lark Beta for this business before connecting an app. No credentials have been stored."
        },
        "setup": {
          "title": "Connect your Lark custom app",
          "description": "Complete these steps once for this business. Your app stays under your Lark organisation's control.",
          "create": {
            "title": "Create a custom app and enable its bot",
            "description": "In the Lark Developer Console, create a custom app for your organisation, add the Bot capability, and choose a recognisable bot name and icon.",
            "action": "Open Lark Developer Console"
          },
          "permissions": {
            "title": "Import the required permissions",
            "description": "Open Permissions & Scopes, choose Import scopes, and paste this JSON. The Beta handles private chats only; group-message scopes are included for Lark's bot event compatibility but group conversations are not processed."
          },
          "credentials": {
            "title": "Verify and securely connect the app",
            "description": "Copy the App ID and App Secret from Credentials & Basic Info. Find the Verification Token under Events & Callbacks. The Encrypt Key is optional.",
            "security": "Your credentials are encrypted and stored securely. For your protection, Groot never displays them again after setup."
          },
          "callbacks": {
            "title": "Configure event and card callbacks",
            "description": "After connecting, Groot will generate two unique callback URLs. Follow these steps for each URL; the same guide stays visible after you connect.",
            "events": {
              "title": "Event subscription",
              "open": "In Lark Developer Console, open your app, then Events & Callbacks → Event Configuration.",
              "delivery": "Set the subscription method to Send events to developer server.",
              "url": "Paste Groot's Event subscription URL into Request URL, then save and wait for verification.",
              "add": "Choose Add event, search for Receive message, and add"
            },
            "cards": {
              "title": "Card callback",
              "open": "Open Events & Callbacks → Callback Configuration.",
              "delivery": "Set callbacks to be sent to your developer server.",
              "url": "Paste Groot's Card callback URL into Request URL, then save and wait for verification.",
              "add": "If Lark shows a callback list, add"
            }
          },
          "publish": {
            "title": "Publish the app to your organisation",
            "description": "Once both callbacks are verified, publish the app so your users can find the bot and securely link their Groot accounts.",
            "checklistTitle": "Publish and link users",
            "createVersion": "Open Version Management & Release, create a version, and include the permissions, events, and callbacks you just configured.",
            "availability": "Set the app's availability to include every requester and approver who will use Expense Claims.",
            "approval": "Submit or publish the version. If Lark requests tenant-admin approval, ask an administrator to approve it before continuing.",
            "linkUsers": "Each user opens a private chat with the bot and sends a message. They then follow the one-time Groot link and confirm the correct business."
          }
        },
        "fields": {
          "appId": "App ID",
          "appSecret": "App Secret",
          "verificationToken": "Verification Token",
          "encryptKey": "Encrypt Key (optional)",
          "secretPlaceholder": "Paste from Lark",
          "encryptKeyPlaceholder": "Optional: paste if enabled",
          "helpLabel": "Where to find {field}",
          "appIdHelp": "In Lark Developer Console, open your app and go to Credentials & Basic Info. Copy the App ID shown under App Credentials.",
          "appSecretHelp": "In Lark Developer Console, open your app and go to Credentials & Basic Info. Reveal and copy the App Secret under App Credentials.",
          "verificationTokenHelp": "Open Events & Callbacks → Encryption Strategy. Copy the Verification Token. In some Lark consoles, this appears inside Event Subscriptions or Security settings.",
          "encryptKeyHelp": "Open Events & Callbacks → Encryption Strategy. Copy the Encrypt Key only if callback encryption is enabled. Leave this blank if you are not using encryption."
        },
        "ownerOnly": {
          "title": "Business owner action required",
          "description": "Finance admins can monitor this integration, but only the business owner can connect or disconnect its app."
        },
        "connected": {
          "app": "Lark app",
          "workspacePending": "Workspace details appear after the first verified callback",
          "eventCallback": "Event callback",
          "cardCallback": "Card callback",
          "verified": "Verified",
          "pending": "Pending",
          "notSeen": "No verified callback yet",
          "guide": {
            "title": "Finish setup in Lark",
            "description": "Complete these steps in order. Groot detects each verified callback automatically and shows your progress here.",
            "progressLabel": "Setup progress",
            "progressValue": "{completed} of {total} complete",
            "eventsDescription": "Connect Lark's message events to this Groot business.",
            "cardsDescription": "Connect approval-card actions to the same Groot business.",
            "publishDescription": "Publish the configuration and let each Expense Claims user securely link their own identity.",
            "userLinked": "User linked",
            "ready": "Ready",
            "afterCallbacks": "After callbacks"
          },
          "next": {
            "title": "Finish setup in Lark",
            "description": "Paste both callback URLs below into Lark, subscribe to im.message.receive_v1, and publish a new app version. Callback health will update automatically when Lark verifies or sends an event."
          }
        },
        "callbacks": {
          "title": "Connection-specific callback URLs",
          "description": "These URLs are unique to this Groot business and Lark app. Do not reuse them for another organisation.",
          "events": "Event subscription URL",
          "cards": "Card callback URL"
        },
        "disconnect": {
          "title": "Disconnect Lark?",
          "description": "This immediately stops callbacks, revokes all linked Lark users for this business, and permanently deletes the stored app secrets. Existing Groot expense claims are kept."
        },
        "rotation": {
          "title": "Replace Lark app credentials",
          "description": "Enter the current credential set from Lark. Leave Encrypt Key blank only when callback encryption is also disabled in Lark. Groot validates and stores a new version before switching this connection.",
          "securityTitle": "Callbacks must be verified again",
          "securityDescription": "After replacement, update the Verification Token and Encrypt Key in Lark if they changed, then verify both existing callback URLs. Linked Groot users are kept."
        },
        "actions": {
          "copyJson": "Copy JSON",
          "copy": "Copy",
          "showSecret": "Show secret",
          "hideSecret": "Hide secret",
          "connect": "Verify & connect",
          "connecting": "Verifying…",
          "testBot": "Send test",
          "retry": "Retry failed jobs",
          "revoke": "Revoke",
          "pause": "Pause bot",
          "resume": "Resume bot",
          "disconnect": "Disconnect",
          "replaceCredentials": "Replace credentials",
          "replacing": "Replacing…",
          "cancel": "Cancel"
        },
        "messages": {
          "connected": "Lark app connected",
          "connectFailed": "Could not connect Lark",
          "disconnected": "Lark disconnected",
          "disconnectFailed": "Could not disconnect Lark",
          "copyFailed": "Could not copy to clipboard",
          "testQueued": "Test message queued",
          "testFailed": "Could not send a test message",
          "retried": "Retried {count} failed jobs",
          "retryFailed": "Could not retry failed jobs",
          "linkRevoked": "Lark user link revoked",
          "revokeFailed": "Could not revoke this link",
          "paused": "Lark bot paused",
          "resumed": "Lark bot resumed",
          "pauseFailed": "Could not change the bot status",
          "rotated": "Lark credentials replaced",
          "rotateFailed": "Could not replace Lark credentials"
        },
        "health": {
          "title": "Connection health",
          "description": "Callback activity and durable delivery status for this app.",
          "lastEvent": "Last event",
          "lastDelivery": "Last successful delivery",
          "queue": "Recent queue",
          "queueValue": "{pending} pending · {failed} failed",
          "needsAttention": "Delivery needs attention",
          "deliveryFailed": "A recent job failed after its retries"
        },
        "users": {
          "title": "Linked users",
          "description": "Every person links their own Lark identity. Membership and role are rechecked for every action.",
          "empty": "No users linked yet. Ask a member to send the bot a private message.",
          "person": "Groot user",
          "larkIdentity": "Lark identity",
          "role": "Current role",
          "status": "Status",
          "action": "Action",
          "unknownName": "Lark user",
          "linked": "Linked",
          "revoked": "Revoked"
        },
        "link": {
          "title": "Link Lark to Groot Finance",
          "description": "Confirm that this Lark identity should act as your Groot Finance user for the business below.",
          "business": "Groot business",
          "workspace": "Lark workspace",
          "workspacePending": "Your connected Lark app",
          "expires": "Link expires",
          "security": "This one-time link is bound to the business and Lark identity that messaged the bot. It cannot be used to select another business.",
          "checking": "Checking your secure link…",
          "confirm": "Confirm and link",
          "linking": "Linking…",
          "failed": "This account could not be linked. Message the bot again for a fresh link.",
          "completeTitle": "Lark account linked",
          "completeDescription": "Return to Lark. Groot will continue processing your original message automatically.",
          "return": "Return to personal settings",
          "states": {
            "invalid": {
              "title": "Invalid link",
              "description": "Message the Groot bot in Lark to request a new link."
            },
            "expired": {
              "title": "Link expired",
              "description": "For your security, links expire after 15 minutes. Message the bot again."
            },
            "consumed": {
              "title": "Link already used",
              "description": "This one-time link has already been consumed. Message the bot if you need to link again."
            },
            "revoked": {
              "title": "Link revoked",
              "description": "This link was replaced. Use the latest link sent by the bot."
            },
            "not_a_member": {
              "title": "Business access required",
              "description": "Sign in with a Groot user who is an active member of this business."
            },
            "connection_unavailable": {
              "title": "Lark connection unavailable",
              "description": "Ask your Groot business owner to check the Lark integration."
            }
          }
        },
        "personal": {
          "title": "Lark account",
          "linked": "Linked",
          "notLinked": "Not linked",
          "description": "Your Groot user is linked through {name}.",
          "notLinkedDescription": "Message your business's Groot bot in Lark to receive a secure link.",
          "unlink": "Unlink",
          "unlinked": "Lark account unlinked",
          "unlinkFailed": "Could not unlink Lark account"
        }
      },
      "sqlAccounting": {
        "title": "SQL Accounting",
        "tabs": {
          "sync": "Automatic sync",
          "cloud": "Cloud connection (Beta)",
          "file": "File import & export"
        },
        "beta": {
          "title": "Beta - not yet validated.",
          "body": "The Cloud connection has not yet been verified against a live SQL Account instance, so connecting may not work yet."
        },
        "errors": {
          "connection": "Connection Error",
          "mapping": "Mapping Error",
          "invoiceExport": "SQL invoice export settings error",
          "body": "Something went wrong loading this section. Your settings and data are safe.",
          "retry": "Try again",
          "reload": "Reload page",
          "supportHint": "If this keeps happening, contact support and tell us which tab you were on."
        },
        "connection": {
          "errors": {
            "requiredKeys": "Both Access Key ID and Secret Access Key are required.",
            "connectFailed": "Failed to connect to SQL Accounting.",
            "disconnectFailed": "Failed to disconnect.",
            "keyHint": "Make sure your API keys are valid. You can generate new keys in SQL Account desktop under Tools > API Key Management."
          },
          "connected": {
            "title": "Connected to SQL Accounting",
            "badge": "Connected",
            "companyName": "Company Name",
            "sqlVersion": "SQL Version",
            "lastVerified": "Last Verified",
            "connectionId": "Connection ID",
            "notAvailable": "N/A"
          },
          "form": {
            "title": "Connect to SQL Accounting",
            "description": "Enter your SQL Accounting API credentials to establish a connection. You can generate API keys from the SQL Account desktop application under Tools > API Key Management.",
            "accessKeyId": "Access Key ID",
            "accessKeyIdPlaceholder": "Enter your Access Key ID",
            "secretAccessKey": "Secret Access Key",
            "secretAccessKeyPlaceholder": "Enter your Secret Access Key"
          },
          "actions": {
            "disconnecting": "Disconnecting...",
            "disconnect": "Disconnect",
            "connecting": "Connecting...",
            "testConnect": "Test & Connect"
          }
        },
        "mapping": {
          "title": "GL Account Mapping",
          "description": "Map your Groot Finance expense categories to SQL Accounting GL account codes. Pull accounts from SQL first, then assign each category.",
          "accountsAvailable": "{count} GL accounts available",
          "noAccountsPulled": "No accounts pulled yet",
          "categoryMappingsTitle": "Category Mappings",
          "mappedCount": "{mapped}/{total} Mapped",
          "searchPlaceholder": "Search GL accounts by code or description...",
          "selectGlAccount": "Select GL account...",
          "table": {
            "grootCategory": "Groot Category",
            "sqlGlAccount": "SQL GL Account",
            "status": "Status"
          },
          "status": {
            "mapped": "Mapped",
            "unmapped": "Unmapped"
          },
          "actions": {
            "pulling": "Pulling...",
            "pullAccounts": "Pull Accounts from SQL",
            "saving": "Saving...",
            "saveMappings": "Save Mappings"
          },
          "messages": {
            "pulledAccounts": "Pulled {count} GL accounts from SQL Accounting.",
            "pullFailed": "Failed to pull accounts.",
            "saved": "Account mappings saved successfully.",
            "saveFailed": "Failed to save mappings."
          },
          "defaultCategories": {
            "officeSupplies": "Office Supplies",
            "travel": "Travel",
            "professionalServices": "Professional Services",
            "utilities": "Utilities",
            "mealsEntertainment": "Meals & Entertainment",
            "otherExpenses": "Other Expenses"
          }
        },
        "apInvoiceSettings": {
          "messages": {
            "saved": "Saved.",
            "failedToSave": "Failed to save"
          },
          "export": {
            "title": "SQL Account export",
            "description": "Enable SQL Account downloads on posted invoices (bulk export: Exports page - any version; no API connection needed).",
            "toggle": "Enable SQL Account export"
          },
          "purchaseDetail": {
            "title": "Purchase invoice detail",
            "description": "How purchases land in SQL Account:",
            "expenseLabel": "Expense",
            "expenseBody": "(default) - creditor + expense account. No stock.",
            "itemizedLabel": "Itemized",
            "itemizedBody": "- matches each line to a SQL stock item and raises stock. You review quantity & price first. Needs your SQL item list imported.",
            "itemizedToggle": "Itemized (track stock)",
            "itemizedTooltip": "On: each item line’s quantity is added to your SQL stock. Off: the purchase is recorded as a creditor + expense only, so stock does not change."
          },
          "defaultExpenseAccount": {
            "title": "Default SQL expense account",
            "description": "SQL Account GL code for purchase-invoice lines that aren't matched to a stock item (e.g. 610-000). Required for the Purchase Invoice export to import cleanly."
          }
        },
        "liveApi": {
          "title": "Direct connection is not switched on.",
          "body": "The direct Cloud connection is not switched on for this workspace yet. Contact support@hellogroot.com for help."
        },
        "fileExport": {
          "introduction": "Download SQL Account import files from an invoice or from Import & Export, then import them into SQL Account yourself.",
          "setup": {
            "title": "One-time setup",
            "importCodes": "Import your SQL Account codes once",
            "mapSuppliers": "Map each supplier to its SQL creditor code",
            "download": "Download or copy supplier invoices from the invoice, or from Import & Export"
          }
        },
        "descriptions": {
          "file": "Move supplier invoices to SQL Account by file.",
          "sync_file": "Groot sends supplier invoices to SQL Account for you after you confirm them. File import and export tools are also available.",
          "cloud": "Set up your SQL Account Cloud connection. This connection is in Beta and is not yet available.",
          "cloud_file": "Set up your SQL Account Cloud connection, or move supplier invoices by file. The Cloud connection is in Beta and is not yet available.",
          "sync_cloud_file": "Groot sends supplier invoices to SQL Account for you after you confirm them. File tools and the Beta Cloud connection settings are also available."
        },
        "unavailable": "SQL Account is not switched on for your workspace; contact support@hellogroot.com."
      },
      "autocount": {
        "title": "AutoCount",
        "description": "Bring your AutoCount codes into Groot, then copy posted purchase invoices back out as a grid you paste into AutoCount. Groot only ever reuses codes that came from your own AutoCount.",
        "tabs": {
          "connection": "Connection",
          "importData": "Import",
          "review": "Export"
        },
        "errors": {
          "importData": "Import Error",
          "review": "Export Error",
          "body": "Something went wrong loading this section. Your settings and data are safe.",
          "retry": "Try again",
          "reload": "Reload page",
          "supportHint": "If this keeps happening, contact support and tell us which tab you were on.",
          "connection": "Connection Error",
          "postSettings": "Posting Settings Error",
          "masterSync": "Master Sync Error"
        },
        "connection": {
          "title": "No AutoCount connection is available.",
          "body": "Groot does not talk to AutoCount over an API yet."
        },
        "review": {
          "download": {
            "title": "Export to AutoCount",
            "description": "Copy your posted purchase invoices as a grid and paste them into AutoCount. Only codes imported from your AutoCount are used, and a row that cannot resolve is refused rather than exported with a guess.",
            "copyAction": "Copy for AutoCount",
            "copied": "Copied",
            "failed": "We couldn't prepare the export. Please try again.",
            "action": "Download .tsv",
            "noRows": "No invoices selected to export.",
            "goToExports": "Pick invoices on Import & Export",
            "destination": {
              "title": "Where this goes in AutoCount",
              "dateFormatNote": "Leave the Input Date Format on its default (DDMMYY). Check the Verify grid before you click Import.",
              "docLink": "AutoCount: Import From Excel"
            },
            "blockers": {
              "requires_licensed_plugin": "Itemized purchases, the kind that carry item and unit codes so AutoCount raises stock, need a separately licensed AutoCount import plugin. This export is expense-level."
            },
            "rowBlockers": {
              "missing_supplier_invoice_no": "no supplier invoice number. AutoCount requires one and will reject the row.",
              "unmapped_creditor": "the supplier has no AutoCount creditor code imported.",
              "unmapped_account": "a line has no AutoCount account code imported.",
              "unmapped_tax_code": "a line has a blank tax code.",
              "missing_document_date": "no document date.",
              "no_detail_lines": "no lines to post."
            }
          }
        },
        "howItWorks": {
          "triggerAriaLabel": "About AutoCount export",
          "title": "About AutoCount export",
          "description": "Two of the three tabs move data today. Here is what each one does and what is still missing.",
          "stepsHeading": "How it works",
          "steps": {
            "import": {
              "title": "Bring your AutoCount codes in",
              "description": "Your accounts, suppliers, customers, stock items and item groups come from your own AutoCount. Groot never makes up a code."
            },
            "download": {
              "title": "Copy a grid and paste it into AutoCount",
              "description": "You paste it into AutoCount yourself, on the Import A/P Invoice screen. Groot needs no connection to your computer."
            }
          },
          "statusHeading": "What works today",
          "status": {
            "connection": "Connection: not available. Groot does not talk to AutoCount over an API yet.",
            "importData": "Import: works. Six kinds of records come across, and every row is counted so the totals match your AutoCount.",
            "review": "Export: works for expense-level purchase invoices. Itemized purchases, the kind that raise stock, need a separately licensed AutoCount plugin."
          },
          "tipsHeading": "Worth knowing",
          "tips": {
            "exactHeaders": "AutoCount matches columns by their exact names, so it shows you a verify step before it imports anything. Check that step and fix any row it flags in red.",
            "neverInvent": "The export only reuses codes that came from your AutoCount, and it refuses a row it cannot match rather than guessing.",
            "stockIndependent": "These settings do not change how Groot tracks your stock.",
            "openIssue": "Nothing on these tabs saves a setting. Pick the invoices you want on the Import and Export page."
          }
        },
        "companion": {
          "stranded": {
            "title": "{count, plural, =1 {# invoice is waiting} other {# invoices are waiting}}.",
            "body": "The companion is not checking in, so nothing is being written to AutoCount. Start the companion on the Windows machine, then check back here."
          },
          "status": {
            "heading": "Companion status",
            "loading": "Checking companion status",
            "host": "Windows machine",
            "version": "Companion version",
            "notReported": "Not reported yet",
            "hostUnnamed": "No name has been supplied for this machine. None was typed in when you registered, and the companion has not reported one either. The companion itself is fine. If a name appears in brackets on the Companion version line above, that companion is an older build; reinstall it so it reports its name here.",
            "state": {
              "neverEnrolled": "Not set up",
              "connected": "Connected",
              "stale": "Not responding",
              "revoked": "Revoked"
            },
            "explain": {
              "neverEnrolled": "No companion is set up yet, so Groot cannot write to AutoCount.",
              "connected": "The companion checked in at {at}.",
              "stale": "The companion last checked in at {at} and has gone quiet since. Check that the Windows machine is on and the companion is running.",
              "staleNeverSeen": "A companion is registered but has never checked in. Check that it is installed and running on the Windows machine.",
              "revoked": "Access is revoked. The companion stops the next time it checks in. Register again to give it a new token."
            },
            "graceOpen": "The previous token still works until {at}. Update the companion on the Windows machine before then.",
            "cadence": "Checks for work",
            "cadenceTier": {
              "busy": "Every {seconds} seconds. Invoices you post reach AutoCount within moments.",
              "warm": "Every {seconds} seconds, because this business posted recently.",
              "idle": "Every {minutes} minutes. That is the longest an invoice will wait.",
              "dormant": "Every {minutes} minutes. Nothing has been sent to AutoCount here for a month, so the companion checks less often. The next invoice you post may take up to {minutes} minutes to appear, and after that it speeds up again straight away."
            }
          },
          "update": {
            "heading": "Bridge updates",
            "unknownVersion": "the available version",
            "available": "Version {version} is ready. Schedule it and the running Bridge will install it only after its current AutoCount work has finished.",
            "waitingForIdle": "Update to {version} is scheduled. Groot AutoCount Bridge waits for its current AutoCount work to finish before it installs.",
            "progress": "Groot AutoCount Bridge is preparing version {version}.",
            "current": "No update is waiting on this Windows machine.",
            "failed": "Groot AutoCount Bridge did not install the update. It keeps the current version; check the protected bridge log before requesting another update.",
            "rolledBack": "The update did not pass its health check. Groot AutoCount Bridge restored the previous version.",
            "blockedByMinimumVersion": "This Windows machine needs a newer Groot AutoCount Bridge before it can continue. Schedule the update when the AutoCount work is safe.",
            "request": "Schedule update",
            "requested": "Update requested. Groot AutoCount Bridge will download and install it at its next safe point.",
            "requestFailed": "Groot could not schedule the update. Try again, and contact support if it keeps failing.",
            "state": {
              "current": "Current",
              "updateAvailable": "Update available",
              "downloading": "Downloading",
              "verified": "Verified",
              "waitingForIdle": "Waiting for AutoCount",
              "installing": "Installing",
              "restarted": "Restarted",
              "failed": "Update failed",
              "rolledBack": "Restored previous version",
              "blockedByMinimumVersion": "Update required"
            }
          },
          "token": {
            "heading": "Your enrolment token",
            "shownOnce": "Copy this now. Groot shows it once and cannot show it again, because only a hash is stored. If you lose it, register again for a new one.",
            "copy": "Copy token",
            "dismiss": "I have copied it",
            "use": "Next: on the Windows machine that runs AutoCount, install the companion and paste this token when the install script asks for it. The steps are under Download the companion."
          },
          "download": {
            "heading": "Download the companion",
            "body": "Install this on the Windows PC that runs AutoCount. You need both files: the program itself, and the script that makes it start when you log in.",
            "exe": "Download Groot AutoCount Bridge",
            "script": "Download the autostart script",
            "preparing": "Preparing",
            "version": "Version {version}, build {commit}",
            "loading": "Checking the latest companion release",
            "unavailable": "The latest companion release could not be checked. Your existing Bridge keeps running; check again before downloading.",
            "retryRelease": "Check again",
            "updateAvailable": "Update available: installed {installed}, latest {latest}.",
            "current": "This Windows machine is on the latest published version.",
            "checksum": "SHA-256 {sha256}",
            "checksumHint": "Before you run it, confirm the file matches. In PowerShell: Get-FileHash your-file.exe -Algorithm SHA256",
            "unsigned": "This program is not code signed yet, so Windows warns you the first time you run it. That warning is expected.",
            "failed": "The download could not be prepared. Try again, and contact support if it keeps happening.",
            "manualHeading": "How to update this Windows machine",
            "manualSteps": {
              "locate": "Find where the installed copy is, and remember it for the steps below. Replace that file, not the one in Downloads.",
              "quit": "Quit Groot AutoCount Bridge from the Windows notification area and wait for its icon to disappear.",
              "quitFallback": "Only if it will not quit:",
              "download": "Download both files using the buttons above.",
              "verify": "Check both downloads against the published values. Run this and read the answer:",
              "replace": "Copy the new program over the installed one, using the path step 1 found.",
              "firstInstall": "If step 1 said it is not installed yet, use this instead:",
              "autostart": "Run the downloaded autostart script again. It points at the same path automatically.",
              "start": "Start Groot AutoCount Bridge.",
              "confirm": "Come back to this screen and confirm the connected version reads {version}. That is the proof the running program changed, not just the file on disk.",
              "confirmNoRelease": "Come back to this screen and confirm the connected version changed. That is the proof the running program changed, not just the file on disk.",
              "logHint": "To watch what it does after starting:"
            },
            "manualIntro": "Run these in Windows PowerShell on the AutoCount machine, in the same window and in order. No administrator rights are needed.",
            "copyCommand": "Copy command",
            "tokenPreserved": "Updating these files does not replace the enrolment token or your AutoCount settings."
          },
          "enrol": {
            "body": "The companion runs on the Windows machine that has AutoCount. It only makes outgoing calls, so you do not need to open a port or change a firewall.",
            "notReleased": "The companion program exists and has posted to AutoCount, but it is still set up by hand on the Windows machine and there is no installer yet. Ask Groot support to help you set it up. Registering now is safe: work waits in the queue below until the companion is running, and nothing is lost.",
            "hostLabel": "Name this machine (optional)",
            "hostPlaceholder": "For example, Accounts PC",
            "action": "Register companion",
            "rotate": "Register again and replace the token",
            "revoke": "Revoke access",
            "revokedHint": "Register again to give this companion a new token.",
            "rotateNote": "Rotating gives you a new token and keeps the old one working for 24 hours, so the companion does not stop while you update it.",
            "refused": {
              "sql_bridge_enrolled": "The SQL Bridge is already set up for this business, and a business posts to one accounting program only. Revoke the SQL Bridge first if you want to switch to AutoCount."
            }
          },
          "jobs": {
            "heading": "AutoCount write queue",
            "loading": "Loading the queue",
            "empty": "Nothing is queued for AutoCount.",
            "attempts": "{count, plural, =1 {# attempt} other {# attempts}}",
            "docNo": "AutoCount document {docNo}",
            "totalMismatch": "AutoCount saved a different document total: Groot sent {expected}, AutoCount recorded {posted}. Open that document in AutoCount and check it.",
            "ambiguousHint": "Groot could not confirm whether AutoCount saved this. Search AutoCount for this supplier's invoice number with Find, not the list, because the list hides drafts. Do this before anything else, and do not send it again.",
            "detailToggle": "What AutoCount reported",
            "retry": "Try again",
            "truncated": "Only the most recent items are shown.",
            "state": {
              "queued": "Waiting",
              "leased": "Picked up",
              "writing": "Writing",
              "succeeded": "Saved",
              "failed": "Failed",
              "ambiguous": "Needs checking"
            },
            "probeAbsent": "Groot read all {count, plural, =1 {# invoice} other {# invoices}} AutoCount holds and none matches this supplier's invoice number.",
            "probeInconclusive": "Groot tried to read AutoCount's invoices but could not be sure, so a person still needs to check."
          },
          "resolve": {
            "action": "Record what you found",
            "formHeading": "What did you find in AutoCount?",
            "lookFirst": "Search AutoCount for this supplier's invoice number first. Use Find, not the list, because the list hides drafts. Groot could not read the answer itself, so whatever you record here is taken as what you saw.",
            "docNoLabel": "AutoCount document number (needed only if AutoCount has it)",
            "docNoPlaceholder": "For example, PI-000006",
            "posted": "AutoCount has it",
            "notPosted": "AutoCount does not have it",
            "cancel": "Not now",
            "consequence": "If AutoCount has it, Groot records the document number and stops asking. If it does not, sending it again becomes safe.",
            "recorded": "Checked in AutoCount and recorded on {at}.",
            "errors": {
              "generic": "Groot could not record what you found. Nothing was changed. Please try again.",
              "needsDocNo": "Enter the AutoCount document number you found, so the record shows which document it is.",
              "alreadyResolved": "Someone else has already recorded what happened to this one. Refresh the page to see what they found, and do not send it again.",
              "notAmbiguous": "This one no longer needs checking. Refresh the page to see where it ended up.",
              "jobGone": "This item is no longer in the queue, so there is nothing to record against it. Refresh the page."
            },
            "lookFirstProbed": "Groot already read the invoices AutoCount holds and found no match for this supplier's invoice number. Confirm what you find: you are checking Groot's read, not re-running it."
          },
          "toasts": {
            "enrolled": "Companion registered.",
            "enrolFailed": "Groot could not register the companion. Please try again.",
            "revoked": "Companion access revoked.",
            "revokeFailed": "Groot could not revoke access. Please try again.",
            "retried": "Queued again for AutoCount.",
            "retryFailed": "Groot could not queue it again. Please try again.",
            "recordedPosted": "Recorded: AutoCount has it.",
            "recordedNotPosted": "Recorded: AutoCount does not have it.",
            "copied": "Token copied.",
            "copyFailed": "Groot could not copy it. Select the token and copy it yourself."
          },
          "steps": {
            "heading": "Set up in 2 steps",
            "next": "Next:",
            "register": {
              "title": "Register the companion"
            },
            "install": {
              "title": "Install it on the Windows machine"
            },
            "hint": {
              "register": "Press Register companion. Groot shows a one-time token for you to copy.",
              "install": "On the Windows machine that runs AutoCount, install the companion and paste the token when the install script asks. The steps are below, under Download the companion.",
              "ready": "Setup is done. Turn on posting in the Export tab to start sending supplier invoices to AutoCount."
            },
            "state": {
              "done": "Done",
              "current": "Current step",
              "todo": "Not started"
            }
          }
        },
        "postSettings": {
          "title": "Posting into AutoCount",
          "loading": "Loading AutoCount posting settings",
          "description": "These settings decide whether Groot may post approved supplier invoices into your AutoCount ledger through the companion on your server, under which document number series, and to which expense account. Posting is off for every business until someone turns it on here.",
          "companionNote": "Posting also needs the AutoCount companion connected on your server. See the Connection tab.",
          "unavailable": "We could not load your business, so these posting settings are not available right now. Reload the page, and if it keeps happening, contact support.",
          "post": {
            "toggle": "Post supplier invoices into AutoCount",
            "blockedNoDocNoFormat": "Posting stays off until you enter your AutoCount document number series below. Groot will not pick one for you.",
            "blockedNoExpenseAccount": "Posting stays off until you enter the AutoCount expense account code below, copied from your own chart. Groot will not pick one for you.",
            "refused": {
              "sql_bridge_posting_enabled": "SQL Bridge posting is on for this business, and a business posts to one accounting program only. Turn off SQL Bridge posting first, then turn on AutoCount posting.",
              "unknown": "Groot could not change that setting. Nothing was changed."
            }
          },
          "docNoFormat": {
            "title": "AutoCount document number series",
            "description": "The Doc No. Format AutoCount should use for the bills Groot posts. Type the name exactly as it appears in your own AutoCount setup.",
            "placeholder": "Copy the name from AutoCount",
            "noDefault": "Groot never fills this in for you. A series we invented would either collide with your own running numbers or start a second sequence in your books, and changing this setting later cannot undo either."
          },
          "expenseAccount": {
            "title": "AutoCount expense account",
            "description": "The GL account code AutoCount should post these bills to. Copy it from your own AutoCount chart of accounts. This is an AutoCount code, so a code you see elsewhere in Groot is not the answer here.",
            "placeholder": "Copy the code from AutoCount",
            "noDefault": "Groot never fills this in, and never checks the shape of what you type, because your chart is yours. A code Groot picked would either bounce off your book or post the bill to whatever that code happens to mean in it, which still balances and is easy to miss.",
            "oneAccountNote": "Every line of a posted bill goes to this one account. For rent, utilities and subscriptions that is usually what you want. For a bill that mixes categories, post it and reclassify the lines in AutoCount."
          },
          "settlement": {
            "title": "Where payments get recorded",
            "description": "Which system applies payments to the bills Groot posts.",
            "autocountLabel": "AutoCount",
            "autocountBody": "You settle each bill in AutoCount, where the payable lives. This is the only choice available today.",
            "grootLabel": "Groot",
            "grootBody": "Mark the bills paid in Groot instead.",
            "grootDisabledReason": "Not available yet, because it needs payment sync back into AutoCount. Until that exists, a bill you settled in Groot would stay open in AutoCount and the supplier aging your auditor reads would be wrong."
          }
        },
        "autoSync": {
          "title": "Automatically send new posted invoices",
          "description": "After you enable this, each new supplier invoice posted in Groot is checked and queued for AutoCount. Existing posted invoices are never swept. A blocked or uncertain handoff waits for a person instead of retrying blindly.",
          "loading": "Loading automatic sending settings",
          "on": "Automatic sending on",
          "off": "Automatic sending off",
          "enabledFrom": "Sending invoices posted after {date}",
          "noBacklog": "Earlier invoices stay untouched. Use the invoice's Send to AutoCount action only when you intentionally want to backfill one.",
          "pauseConsequence": "Pausing stops new handoffs. An invoice already accepted for sending continues to its recorded outcome.",
          "pause": "Pause automatic sending",
          "enable": "Enable automatic sending",
          "needsPosting": "Enable and complete the AutoCount posting settings above first.",
          "needsReview": "Turn on supplier invoice review first. Automatic sending never forwards unreviewed uploaded invoices.",
          "acknowledgement": "I understand that new posted invoices will be written into AutoCount, and that an uncertain save must be checked there by a person before any resend.",
          "saveFailed": "Groot could not change automatic sending. Nothing changed. Check the requirements and try again.",
          "activityTitle": "Recent automatic handoffs",
          "empty": "No invoice has entered automatic sending yet.",
          "postedAs": "Posted in AutoCount as {docNo}",
          "needsAttention": "This invoice needs attention",
          "inProgress": "Queued or checking prerequisites",
          "covered": "An existing AutoCount handoff already covers this invoice",
          "resolved": "A person resolved the uncertain AutoCount result",
          "cancelled": "Stopped because the posting safety requirements changed",
          "authorizerNoLongerEligible": "The owner or finance admin who enabled automatic sending no longer has permission. An owner or finance admin must pause it, then enable it again.",
          "dispatchFailed": "Groot could not finish the AutoCount preflight. Open this invoice and use Send to AutoCount when you are ready to try again.",
          "genericReason": "Open the invoice to see what must be fixed. Groot did not retry an uncertain result.",
          "openInvoice": "Open invoice"
        },
        "diagnosticArchive": {
          "title": "Companion diagnostic archive",
          "description": "Send redacted, gzipped Groot AutoCount Bridge diagnostic batches to Groot for support. They are private, retained for 120 days (30 days hot, then Glacier), and never include document numbers, tokens, paths, or unapproved fields.",
          "toggle": "Enable companion diagnostic archive",
          "onLabel": "On",
          "offLabel": "Off",
          "enabled": "Enabled. Turn this off to stop new upload permits immediately.",
          "disabled": "Off by default. No diagnostic batch can be presigned until you enable it.",
          "saveFailed": "We could not update the diagnostic archive setting. Please try again."
        },
        "masterCreation": {
          "title": "Create missing AutoCount masters",
          "description": "Groot can ask the installed Bridge to create missing creditors, item groups, and stock items with their base UOM before sending an A/P invoice. Groot searches AutoCount first and reuses an existing record rather than creating a second one. Existing codes are never overwritten or guessed.",
          "loading": "Loading master-sync settings",
          "toggle": "Automatically create missing master data",
          "safetyNotice": "Import or refresh your AutoCount creditor masters first. Before creating anything, Groot searches AutoCount for a creditor with the same company name and reuses it, so a supplier that is unmapped in Groot does not get a duplicate. If more than one creditor matches, Groot refuses and creates nothing, leaving the choice to you.",
          "requiredSummary": "Enter the creditor control account before automatic creditor creation can be switched on.",
          "itemDefaultsPairRequired": "For itemized invoices, enter both fallbacks, or leave both blank.",
          "runtimeReady": "Bridge support verified",
          "runtimePending": {
            "label": "Runtime verification pending",
            "body": "Automatic creation stays off until the installed Groot AutoCount Bridge checks in and reports support for master sync. Update and restart the Bridge, then return here."
          },
          "creditorControlAccount": {
            "title": "Creditor control account",
            "description": "The AutoCount control account used when allocating a new creditor code.",
            "placeholder": "Copy from AutoCount",
            "required": "Enter the creditor control account from AutoCount."
          },
          "defaultItemGroup": {
            "title": "Item group fallback (optional)",
            "description": "Used only when an item does not name an AutoCount group of its own.",
            "placeholder": "Copy the item group code"
          },
          "defaultBaseUom": {
            "title": "Base UOM fallback (optional)",
            "description": "Used only when neither the invoice line nor the item names a unit.",
            "placeholder": "For example, UNIT"
          },
          "uomIncludedNote": "The two fallbacks must be set together, and each is used only when nothing else names a value. A line's own unit wins, and Groot checks it against AutoCount before creating the item. Base UOM is part of the stock item; Groot does not create a separate UOM master.",
          "reconcileAutoCreate": {
            "title": "Create drafts for new AutoCount items",
            "description": "When Reconcile finds an AutoCount item with no Groot product, create a draft product for it automatically.",
            "toggle": "Create item drafts automatically",
            "safetyNotice": "Off by default. A draft is not sellable and has no guessed tax code or GL account; complete it in Products before use."
          }
        },
        "reconcile": {
          "title": "Reconcile from AutoCount",
          "description": "Groot reads the masters your accountant changed in AutoCount and records which Groot supplier or item each one belongs to, so a supplier you already have is never created twice.",
          "readOnlyNotice": "This only reads AutoCount. Nothing is created, changed or deleted there.",
          "loading": "Loading reconcile history",
          "historyHeading": "Reconcile history",
          "loadMore": "Load older runs",
          "loadingMore": "Loading older runs",
          "empty": "No reconcile has run yet.",
          "reconcileNow": "Reconcile now",
          "schedule": "Runs automatically once a day.",
          "runtimeReady": "Bridge support verified",
          "runtimePending": "Bridge update needed",
          "moreAvailable": "More masters are waiting. Reconcile again to continue where this run stopped.",
          "counts": "Read {scanned} masters. Mapped {mapped}. {unmatched} had no matching Groot record.",
          "state": {
            "queued": "Waiting for the Bridge",
            "leased": "Starting",
            "reading": "Reading AutoCount",
            "succeeded": "Finished",
            "failed": "Did not finish",
            "blocked": "Needs attention"
          },
          "trigger": {
            "scheduled": "Daily run",
            "manual": "Started by you"
          },
          "toast": {
            "queued": "Reconcile queued. The Bridge will pick it up shortly.",
            "alreadyRunning": "A reconcile is already running."
          },
          "refusal": {
            "settings_missing": "Switch on automatic AutoCount master creation first.",
            "companion_unavailable": "Start Groot AutoCount Bridge on the AutoCount machine, then try again.",
            "runtime_unverified": "Update and restart Groot AutoCount Bridge, then try again.",
            "api_shape_unsupported": "This Groot AutoCount Bridge build cannot reconcile. Install a newer one.",
            "unknown": "Reconcile could not be started. Nothing was read. Please try again."
          },
          "failure": {
            "settings_missing": "Automatic AutoCount master creation was switched off while this run was waiting.",
            "companion_unavailable": "Groot AutoCount Bridge was not reachable. Nothing was read.",
            "runtime_unverified": "Update and restart Groot AutoCount Bridge, then reconcile again.",
            "api_shape_unsupported": "This Groot AutoCount Bridge build cannot reconcile. Install a newer one.",
            "operation_failed": "AutoCount could not be read. Nothing was changed there. Reconcile again.",
            "unknown": "The reconcile did not finish. Nothing was written to AutoCount."
          },
          "conflicts": {
            "heading": "{count, plural, =1 {# record needs a person} other {# records need a person}}",
            "reason": {
              "ambiguous_groot_name": "matches more than one record in Groot, so Groot will not choose.",
              "entity_already_mapped_elsewhere": "would move a record that is already mapped to a different AutoCount code.",
              "code_already_mapped_elsewhere": "is already mapped to a different record in Groot.",
              "catalog_scan_truncated": "could exist beyond the catalog scan limit, so Groot will not create or link a product.",
              "mapping_scan_truncated": "could already be mapped beyond the mapping scan limit, so Groot will not change it."
            }
          },
          "unmatchedItems": {
            "heading": "{count, plural, =1 {# new AutoCount item has no Groot product} other {# new AutoCount items have no Groot product}}",
            "safetyNotice": "Add to catalog creates a non-sellable draft. Groot does not guess tax treatment or a GL account.",
            "add": "Add to catalog",
            "added": "Draft added to Products. Complete its tax and GL details before use.",
            "alreadyAdded": "This AutoCount item is already linked to a Groot product.",
            "addFailed": "The item could not be added. Please try again.",
            "mappedExisting": "The AutoCount item was linked to the existing Groot product."
          }
        },
        "masterSync": {
          "baseUomFrom": {
            "line": "Unit {uom}, from this invoice line",
            "catalog_item": "Unit {uom}, from the item record",
            "fallback": "Unit {uom}, from your AutoCount fallback"
          },
          "itemGroupFrom": {
            "line": "Group {group}, from this invoice line",
            "catalog_item": "Group {group}, from the item category",
            "fallback": "Group {group}, from your AutoCount fallback"
          },
          "title": "Master sync runs",
          "description": "See each prerequisite Groot asked the Windows Bridge to confirm before an A/P invoice is queued.",
          "loading": "Loading master sync runs",
          "empty": "No master sync has been needed yet.",
          "invoiceFallback": "Invoice {id}",
          "updatedAt": "Last change {at}",
          "attempts": "{count, plural, =1 {# attempt} other {# attempts}}",
          "loadMore": "Load older runs",
          "loadingMore": "Loading older runs",
          "retry": "Retry master sync",
          "retrying": "Retrying",
          "blockedHeading": "A person must fix this before Groot can continue.",
          "failedHeading": "Nothing was created by this attempt.",
          "allocatedCode": "Allocated {code}; waiting for AutoCount to save it.",
          "createdCode": "Created {code}",
          "existingCode": "Found existing {code}",
          "state": {
            "queued": "Waiting",
            "leased": "Picked up",
            "syncing": "Syncing",
            "ready_to_post": "Ready for A/P",
            "succeeded": "A/P queued",
            "blocked": "Needs action",
            "failed": "Retry available",
            "unknown": "Needs checking"
          },
          "steps": {
            "creditor": {
              "label": "Creditor"
            },
            "item_group": {
              "label": "Item group"
            },
            "stock_item": {
              "label": "Stock item (base UOM included)"
            },
            "ap_invoice": {
              "label": "A/P invoice"
            }
          },
          "stepState": {
            "pending": "Waiting for the earlier step",
            "active": "Checking AutoCount now",
            "allocated": "Code allocated; not saved yet",
            "ready": "Ready to queue the A/P invoice",
            "succeeded": "Confirmed in AutoCount",
            "blocked": "Stopped for a required change",
            "failed": "Stopped before a confirmed save"
          },
          "remedy": {
            "companion_unavailable": "Start or re-enrol Groot AutoCount Bridge on the Windows machine, then retry.",
            "settings_missing": "Complete the automatic master-creation settings on the Export tab, then retry.",
            "creditor_control_account_missing": "Enter the creditor control account from this AutoCount book on the Export tab.",
            "default_item_group_missing": "Enter an existing AutoCount item group code on the Export tab.",
            "default_base_uom_missing": "Enter the base UOM used by this AutoCount book on the Export tab.",
            "item_defaults_missing": "Enter both the default item group and base UOM from this AutoCount book on the Export tab.",
            "allocator_rejected": "Fix the code-allocation format or defaults in AutoCount. Groot will not invent a replacement code.",
            "sdk_unsupported": "Update Groot AutoCount Bridge or use a supported AutoCount build. This installed API does not expose the required operation.",
            "runtime_unverified": "Update and restart Groot AutoCount Bridge so it can report master-sync support before automatic creation is enabled.",
            "code_conflict": "A different AutoCount record already uses this exact code. Map the correct existing record; Groot will not overwrite it.",
            "master_ambiguous": "Two AutoCount records share this name, so Groot will not choose between them. Open AutoCount, decide which record is correct, and map it in Groot; nothing was created.",
            "uom_unknown": "AutoCount does not have this unit of measure. Add it in AutoCount, or correct the unit on the invoice line, then send again.",
            "uom_master_unreadable": "Groot could not read AutoCount's unit-of-measure list, so it would not create a stock item with an unchecked unit. Check the Bridge's AutoCount permissions, then send again.",
            "invoice_preflight_changed": "Fix the newly reported invoice prerequisite, then send the invoice again.",
            "transport_failed": "The attempt stopped before a confirmed local save. Check the connection and retry; Groot will read the exact code first.",
            "report_lost": "The save report was lost. Retry is safe because Groot checks the exact code before creating anything.",
            "operation_failed": "The AutoCount operation stopped before a confirmed save. Check AutoCount and the Bridge log, correct the local issue, then retry.",
            "checkpoint_failed": "Groot could not record the allocated code, so the Bridge did not save it. Check the connection, then retry.",
            "bridge_result_invalid": "The Bridge did not return the exact saved code. Update and restart the Bridge, then retry; Groot has not treated the record as created.",
            "requester_unauthorized": "The original requester's access changed. An owner or finance administrator must use Send Again from the invoice.",
            "invoice_settings": "Complete the current AutoCount posting settings, then use Send Again from the invoice.",
            "invoice_review": "Complete the invoice or tax review in Groot, then use Send Again.",
            "invoice_in_progress": "An A/P job already exists for this invoice. Refresh and wait for that job instead of creating another.",
            "invoice_already_posted": "This invoice is already recorded in AutoCount. Inspect the existing document; do not send it again.",
            "invoice_ambiguous": "Inspect AutoCount and resolve the earlier unknown result before attempting another send.",
            "invoice_duplicate": "Another Groot document has the same creditor and supplier invoice number. Open that record instead of sending a duplicate.",
            "invoice_type": "This document no longer qualifies as a posted A/P invoice. Correct and post it in Groot before sending again.",
            "invoice_tax": "This invoice uses a recoverable input-tax split the current AutoCount lane cannot post. Do not retry; contact Groot support.",
            "unknown": "Open the run after refreshing. If the remedy is still unavailable, contact Groot support with the invoice reference.",
            "item_link_unconfirmed": "Match the invoice line to a confirmed catalog item under Products > Needs review, then use Send Again."
          },
          "toasts": {
            "retried": "Master sync queued again.",
            "retryFailed": "Groot could not retry this master sync. Nothing was changed."
          }
        }
      },
      "ecommerce": {
        "title": "E-commerce",
        "subtitle": "Your online store and marketplaces"
      },
      "woocommerce": {
        "paidOrders": {
          "title": "Paid orders",
          "description": "Paid store orders are invoiced and recorded automatically.",
          "authorise": "Authorise automatic posting of paid orders",
          "receiptSender": "Who sends the buyer's receipt?",
          "store": "Store or gateway",
          "groot": "Groot",
          "receiptHelp": "Store: Groot sends no receipt. Groot: Groot issues the receipt.",
          "gateway": "Payment method",
          "account": "Clearing account",
          "chooseAccount": "Choose an account",
          "accountHelp": "Payments wait here until the gateway pays out.",
          "addGateway": "Add gateway",
          "remove": "Remove",
          "removeGateway": "Remove {gateway}",
          "reason": "Reason for granting or revoking permission",
          "save": "Save paid order settings",
          "saved": "Paid order settings saved.",
          "failed": "Could not save. Check your owner access, account settings and connection, then try again.",
          "indexReady": "Customer email matching is ready.",
          "indexContinue": "More customers remain. Continue preparing matching.",
          "indexNeeded": "Prepare customer email matching before automatic orders can post.",
          "prepareIndex": "Prepare customer matching",
          "ownerOnly": "Only an owner can change automatic posting.",
          "errors": {
            "gatewayInvalid": "Each gateway needs its own ID and an incoming Card or Other clearing account from Payment & posting.",
            "reasonRequired": "Give a reason for granting or revoking automatic posting.",
            "connectionUnavailable": "Connect the store first, then save these settings."
          },
          "since": "Orders paid from {date} post automatically; earlier ones never do.",
          "chooseMethod": "Choose a payment method",
          "methodOff": "{title} (off)",
          "methodsLoading": "Loading the store's payment methods",
          "methodNameLoading": "Loading name",
          "methodsUnavailable": "Could not read the store's payment methods. Enter the method ID from WooCommerce.",
          "noClearingAccount": "No incoming Card or Other account yet.",
          "createClearing": "Create a clearing account",
          "addAllEnabled": "Use for all {count} enabled methods",
          "statusTitle": "Saved settings",
          "statusOff": "Automatic posting is off.",
          "statusMethods": "{count, plural, one {# payment method} other {# payment methods}} → {accounts}",
          "statusNoMethods": "No payment method mapped yet.",
          "addMethod": "Add a payment method",
          "mode": "How it is posted",
          "modeClearing": "Paid through a gateway, waits in a clearing account",
          "modeOpen": "Paid into your bank (open invoice, matched from your bank statement)",
          "modeHelp": "An open invoice has no payment yet. When the transfer shows in Bank / Cash, match it by the invoice number. Groot never emails the buyer.",
          "methodOther": "Other (manual orders)",
          "rowOpen": "{method} → open invoice (matched from your bank statement)",
          "statusOpenMethods": "{count, plural, one {# method} other {# methods}} → open invoice"
        },
        "loading": "Loading your WooCommerce connection",
        "beta": "Beta",
        "description": "Bring your WooCommerce products into Groot. Groot only reads your store and never changes it.",
        "declined": "You declined access in WooCommerce, so nothing was connected. You can try again whenever you are ready.",
        "disconnectedOn": "Disconnected on {date}.",
        "revokeOldKey": "Revoke the old key in WordPress",
        "ownerOnly": "Only the business owner can connect a store.",
        "how": {
          "step1": "Enter your store address.",
          "step2": "WooCommerce asks you to approve read-only access. Click Approve.",
          "step3": "You come back here, connected."
        },
        "storeUrlLabel": "Store address",
        "storeUrlPlaceholder": "yourstore.com",
        "storeUrlHelp": "The address of your WooCommerce store. You can paste any page of it, even a WordPress admin page.",
        "connect": "Connect WooCommerce",
        "status": {
          "connected": "Connected",
          "needsAttention": "Needs attention",
          "pending": "Waiting for approval",
          "disconnected": "Disconnected"
        },
        "messages": {
          "testPassed": "Connection works",
          "connected": "WooCommerce connected",
          "disconnected": "WooCommerce disconnected",
          "revokeReminder": "Groot deleted its copy of the key. Revoke the key in WordPress as well.",
          "webhookReminder": "Delete the Groot webhook in WooCommerce too."
        },
        "disconnectTitle": "Disconnect WooCommerce?",
        "disconnectMessage": "Groot deletes its copy of the key and stops reading your store. Products you already imported stay in Groot.",
        "disconnect": "Disconnect",
        "cancel": "Cancel",
        "facts": {
          "store": "Store",
          "access": "Access",
          "readOnlyKey": "Read-only key ending in {last4}",
          "keyUnverified": "Key permission not verified. Make sure it says Read in WooCommerce > Settings > Advanced > REST API (key ending {last4}).",
          "connected": "Connected",
          "connectedApproval": "{date} by {name}, approved in WooCommerce",
          "connectedManual": "{date} by {name}, with a pasted key",
          "someone": "a team member",
          "lastChecked": "Last checked",
          "notCheckedYet": "Not checked yet",
          "productsInStore": "Products in store",
          "productCount": "{count, plural, one {# product} other {# products}}",
          "unknown": "Not known yet",
          "linked": "Linked in Groot",
          "linkedCount": "{count, plural, one {# product} other {# products}}",
          "linkedCountCapped": "More than {count} products",
          "lastImport": "Last import",
          "lastImportSummary": "{date}: {created} new, {updated} updated",
          "neverImported": "No import yet",
          "content": "Product content",
          "contentImages": "Images",
          "contentNone": "Not brought. Choose it when you import products.",
          "contentLastSynced": "Last brought {date}, {count, plural, one {# product} other {# products}}"
        },
        "importExplainer": "Importing brings in names, SKUs, categories, brands and prices. WooCommerce does not keep barcodes, cost or stock, so those come from your purchases.",
        "importProducts": "Import products",
        "testConnection": "Test connection",
        "pendingExpired": "This approval expired before WooCommerce sent the key.",
        "pendingWaiting": "Waiting for you to approve access in {store}.",
        "pendingStarted": "Started {date} by {name}",
        "startAgain": "Start again",
        "continueToWooCommerce": "Continue to WooCommerce",
        "manual": {
          "toggle": "Store blocks the approval page? Enter a key by hand",
          "hide": "Hide",
          "show": "Show",
          "step1Title": "1. Create a read-only key in WooCommerce",
          "fieldDescription": "Description: Groot Finance",
          "fieldUser": "User: yourself",
          "fieldPermissions": "Permissions: Read",
          "openKeys": "Open WooCommerce keys",
          "enterStoreFirst": "Enter your store address above to open the right page.",
          "step2Title": "2. Paste the key and secret here",
          "consumerKey": "Consumer key",
          "consumerSecret": "Consumer secret",
          "submit": "Test and connect"
        },
        "errors": {
          "WOOCOMMERCE_STORE_URL_INVALID": "Enter your store address, for example yourstore.com.",
          "WOOCOMMERCE_STORE_URL_NOT_HTTPS": "Use the https address of your store. Groot only connects over a secure connection.",
          "WOOCOMMERCE_STORE_URL_NOT_PUBLIC": "Enter your store's public web address.",
          "WOOCOMMERCE_NOT_DETECTED": "This site does not look like a WooCommerce store. Check the address, or make sure WooCommerce is active.",
          "WOOCOMMERCE_REDIRECTED": "Your store sends visitors to a different address. Enter the address your store actually uses.",
          "WOOCOMMERCE_UNREACHABLE": "Groot could not reach your store. Check the address and try again.",
          "WOOCOMMERCE_NOT_JSON": "A security plugin or firewall on your store blocked Groot. Allow requests to the WooCommerce REST API and try again.",
          "WOOCOMMERCE_UNAUTHORIZED": "Your store rejected the key. It may have been revoked or deleted. Disconnect and connect again.",
          "WOOCOMMERCE_API_NOT_FOUND": "Your store's WooCommerce REST API is not available. Check that WooCommerce is active.",
          "WOOCOMMERCE_RATE_LIMITED": "Your store asked Groot to slow down. Wait a minute and try again.",
          "WOOCOMMERCE_STORE_ERROR": "Your store had a problem answering. Try again in a few minutes.",
          "WOOCOMMERCE_KEY_INVALID": "That key does not look right. The key starts with ck_ and the secret with cs_.",
          "WOOCOMMERCE_ALREADY_CONNECTED": "A store is already connected. Disconnect it first.",
          "WOOCOMMERCE_OWNER_REQUIRED": "Only the business owner can do this.",
          "WOOCOMMERCE_NOT_ENABLED": "WooCommerce is not turned on for this business yet.",
          "WOOCOMMERCE_NOT_CONNECTED": "Connect a WooCommerce store first.",
          "WOOCOMMERCE_CREDENTIAL_STORE_FAILED": "Groot could not save the key securely, so nothing was connected. Try again, or contact support if it keeps happening.",
          "WOOCOMMERCE_CREDENTIALS_UNAVAILABLE": "Groot could not read the saved key. Disconnect and connect again.",
          "WOOCOMMERCE_CREDENTIAL_DELETE_FAILED": "Groot could not delete the saved key, so the store is still connected. Try again.",
          "WOOCOMMERCE_NOT_CONFIGURED": "WooCommerce is temporarily unavailable. Contact support if this continues.",
          "WOOCOMMERCE_PAID_ORDERS_NOT_AUTHORISED": "Switch on automatic posting in Paid orders first.",
          "generic": "Something went wrong. Try again, or contact support if it keeps happening.",
          "WOOCOMMERCE_PAST_START_INVALID": "Choose a real start date.",
          "WOOCOMMERCE_PAST_START_NOT_BEFORE_AUTHORISATION": "The start date must be before automatic posting was switched on.",
          "WOOCOMMERCE_PAST_START_ONLY_EARLIER": "The start date can only move earlier.",
          "WOOCOMMERCE_PAST_REASON_REQUIRED": "Give a reason for bringing in past orders.",
          "CONNECTOR_OWNER_AUTHORISATION_REQUIRED": "Switch on automatic posting in Paid orders first.",
          "CONNECTOR_CONNECTION_UNAVAILABLE": "The store connection needs attention. Reconnect the store first.",
          "FEATURE_NOT_ENABLED": "Invoicing is not switched on for this business."
        },
        "webhook": {
          "title": "Order updates",
          "description": "WooCommerce tells Groot each time an order changes. Groot then checks that order with your store and lists it here. When automatic posting is on, a paid order is posted to your books and shown in the last column.",
          "badge": {
            "notSetUp": "Not set up",
            "settingUp": "Setting up",
            "needsFix": "Needs a fix",
            "off": "Turned off in WooCommerce",
            "receiving": "Receiving orders"
          },
          "start": "Set up order updates (4 WooCommerce webhooks)",
          "ownerOnlySetup": "The business owner can set this up.",
          "shared": {
            "heading": "Shared values",
            "hint": "Use these on all four. Click Save webhook on each."
          },
          "cards": {
            "listLabel": "The four webhooks",
            "open": "Open in WooCommerce",
            "openLabel": "Open in WooCommerce, {topic} webhook",
            "test": "Test",
            "testing": "Testing",
            "testLabel": "Test {topic} webhook",
            "openList": "Open WooCommerce webhooks",
            "offInfoLabel": "About a turned-off webhook",
            "pingReceived": "Test call received {date}",
            "checked": "Checked {date}",
            "status": {
              "notSetUp": "Not set up",
              "unread": "Not checked yet",
              "checking": "Checking",
              "active": "Active",
              "couldNotCheck": "Could not check"
            }
          },
          "form": {
            "name": "Name",
            "status": "Status",
            "statusActive": "Active",
            "topicOrderCreated": "Order created",
            "topicOrderUpdated": "Order updated",
            "topicProductCreated": "Product created",
            "topicProductUpdated": "Product updated",
            "deliveryUrl": "Delivery URL",
            "secret": "Secret",
            "secretNote": "Paste this Secret. If the field is left empty, WooCommerce makes up its own and Groot cannot trust the updates.",
            "apiVersion": "API version",
            "apiVersionValue": "WP REST API Integration v3",
            "show": "Show",
            "hide": "Hide",
            "copy": "Copy",
            "copied": "Copied",
            "copyLabel": "Copy {field}",
            "copyFailed": "Could not copy. Select the text and copy it instead.",
            "ownerOnlyValue": "Only the business owner can see this.",
            "loading": "Getting it from Groot",
            "unavailable": "Not available yet",
            "loadFailed": "Groot could not get your Delivery URL and Secret.",
            "retry": "Try again",
            "secretInfoLabel": "About the Secret"
          },
          "checks": {
            "settingsError": "Groot could not read your webhooks. {reason}",
            "delivery": "First order update received",
            "deliveryDone": "Order {order} arrived {date}, signed with your Secret.",
            "deliveryWaiting": "Waiting for the first order update.",
            "deliveryHint": "Open any order and click Update to send one now.",
            "checkFailed": "Groot could not check your webhook. Try again in a minute."
          },
          "fixes": {
            "status": "Change Status to Active. It is {status} now.",
            "deliveryUrl": "Paste the Delivery URL again. The saved one does not match this connection.",
            "apiVersion": "Change API version to WP REST API Integration v3.",
            "duplicate": "{count} webhooks with this Topic send to Groot. Delete the extra ones so each update arrives once.",
            "extraTopic": "Another webhook sends {topic} to Groot. It is not needed. You can delete it."
          },
          "statusWords": {
            "active": "Active",
            "paused": "Paused",
            "disabled": "Disabled",
            "unknown": "unknown"
          },
          "off": {
            "body": "Its updates will not reach Groot until you turn it back on. WooCommerce turns a webhook off after several failed deliveries."
          },
          "log": {
            "title": "Recent order updates",
            "caption": "The latest 20 updates. Groot keeps them for 30 days.",
            "loading": "Loading order updates",
            "empty": "No order updates yet.",
            "order": "Order",
            "status": "Status",
            "received": "Received",
            "signature": "Signature",
            "store": "Confirmed with store",
            "chip": "CHIP payment",
            "topicCreated": "Order created",
            "topicUpdated": "Order updated",
            "topicDeleted": "Order deleted",
            "topicRestored": "Order restored",
            "noStatus": "No status",
            "storeNow": "Store now says {status}",
            "changedInStore": "Changed in store {date}",
            "via": "Webhook {id}, delivery {delivery}",
            "viaNoId": "Delivery {delivery}",
            "verified": "Verified",
            "notVerified": "Not verified",
            "checking": "Checking with store",
            "confirmed": "Confirmed",
            "checkedAt": "Checked {date}",
            "notFound": "Not found in store",
            "notFoundHint": "Your store has no such order, so Groot did not trust this update.",
            "failed": "Could not check",
            "chipYes": "Recorded",
            "chipNo": "None",
            "posting": "Posting",
            "checkedByGroot": "Checked by Groot",
            "topicCatchUp": "Checked from the store",
            "viaCatchUp": "Read from your store when you checked",
            "filter": {
              "label": "Show updates by outcome",
              "all": "All {count}",
              "posted": "Posted {count}",
              "held": "Held {count}"
            },
            "filterEmpty": "No updates in this view."
          },
          "posting": {
            "none": "Not posted",
            "posted": "Posted {invoice}",
            "postedAt": "Recorded {date}",
            "notPaid": "Not paid yet",
            "held": "Held: {reason}",
            "product": "Product {sku}",
            "failed": "Could not post yet",
            "failedHint": "Groot tries again when you check recent orders.",
            "fix": {
              "paidOrders": "Open Paid orders",
              "import": "Import products",
              "products": "Open products",
              "customers": "Open customers",
              "connection": "Open connection settings"
            },
            "hold": {
              "generic": "Groot could not post this order. Contact support if it keeps happening.",
              "CONNECTOR_OWNER_AUTHORISATION_REQUIRED": "An owner needs to switch on automatic posting in Paid orders.",
              "CONNECTOR_GATEWAY_NOT_CONFIGURED": "Choose an account for this payment method in Paid orders, then check again.",
              "CONNECTOR_BUYER_INDEX_NOT_READY": "Prepare customer matching in Paid orders, then check again.",
              "CONNECTOR_BUYER_AMBIGUOUS": "More than one customer has the buyer’s email. Merge the duplicates, then check again.",
              "CONNECTOR_TOTALS_MISMATCH": "The amounts on this order do not add up in Groot (lines, shipping, fees, discounts and tax). Record it by hand.",
              "CONNECTOR_PRODUCT_UNAVAILABLE": "A product on this order is inactive in Groot. Switch it back on, then check again.",
              "CONNECTOR_ORDER_NOT_PAID": "The store has not marked this order as paid yet.",
              "CONNECTOR_CONNECTION_REUSED": "This connection now points to a different store than this order came from. Review the connection.",
              "CONNECTOR_CONNECTION_UNAVAILABLE": "The store connection needs attention. Reconnect the store, then check again.",
              "CONNECTOR_PAID_BEFORE_AUTHORISATION": "Paid before automatic posting was switched on. Record it by hand if it is not in the books yet.",
              "CONNECTOR_FEE_INVALID": "The gateway fee on this order looks wrong. Record it by hand.",
              "FEATURE_NOT_ENABLED": "Invoicing is not switched on for this business.",
              "WOOCOMMERCE_VARIATION_NOT_SUPPORTED": "This order has a product variation, which Groot cannot post yet. Record it by hand.",
              "WOOCOMMERCE_PRODUCT_NOT_IMPORTED": "A product on this order has not been imported yet. Import it, then check again.",
              "WOOCOMMERCE_ORDER_UNREADABLE": "Groot could not read the amounts on this order. Contact support if it keeps happening.",
              "WOOCOMMERCE_NO_PAYMENT_METHOD": "This order has no payment method in your store, so there is no account to post it to. Record it by hand.",
              "PERIOD_CLOSED": "The accounting period for this date is closed. Reopen it, then check again, or record the order by hand.",
              "POSTING_BEFORE_CONVERSION_DATE": "This order is dated before your books start. Record it by hand.",
              "CONNECTOR_ORDER_BEFORE_AUTHORISATION": "Placed before automatic posting was switched on. If it is not in the books yet, post it from Held orders.",
              "CONNECTOR_ORDER_POSTED_PAID": "This order is already in the books as a paid order, so it cannot also post as an open invoice.",
              "CONNECTOR_ORDER_NOT_ACCEPTED": "The store has not accepted this order yet (it must be processing or completed).",
              "WOOCOMMERCE_OPEN_ORDER_HAS_REFUNDS": "This order has a refund in the store, which Groot does not mirror on an open invoice. Record it by hand."
            },
            "postedOpen": "Posted {invoice} · open"
          },
          "refund": {
            "label": "Refunds of order {order}",
            "recorded": "Refund {amount} recorded ({document})",
            "recordedNoDocument": "Refund {amount} recorded",
            "held": "Refund {amount} held: {reason}",
            "failed": "Refund {amount} could not be recorded yet",
            "failedHint": "Groot tries again when this order changes in your store, or when you check recent orders.",
            "hold": {
              "generic": "Groot could not post this refund. Contact support if it keeps happening.",
              "CONNECTOR_REFUND_ORDER_NOT_POSTED": "This order is not in your books yet, so its refund waits. It posts once the order does.",
              "CONNECTOR_OWNER_AUTHORISATION_REQUIRED": "An owner needs to switch on automatic posting in Paid orders.",
              "CONNECTOR_CONNECTION_UNAVAILABLE": "The store connection needs attention. Reconnect the store, then check again.",
              "CONNECTOR_CONNECTION_REUSED": "This connection now points to a different store than this order came from. Review the connection.",
              "CONNECTOR_REFUND_INVALID": "Groot could not read this refund from your store. Record it by hand.",
              "CONNECTOR_REFUND_DATE_INVALID": "Groot could not read the date of this refund. Record it by hand.",
              "FEATURE_NOT_ENABLED": "Invoicing is not switched on for this business.",
              "REFUND_EXCEEDS_PAID": "This refund is more than is left to refund on the order’s invoice. Review the invoice, or record it by hand.",
              "REFUND_INVOICE_NOT_PAID": "The invoice for this order is not paid in Groot, so it cannot be refunded here. Record it by hand.",
              "REFUND_REQUEST_CONFLICT": "Groot already recorded a different refund under this refund’s number. Review the invoice’s history.",
              "REFUND_ALLOCATION_INVALID": "The tax on this invoice does not split cleanly for a refund. Record it by hand.",
              "CUSTOMER_CREDIT_DATE_BEFORE_NOTE": "This refund is dated before its invoice. Record it by hand.",
              "CUSTOMER_CREDIT_FOREIGN_CURRENCY": "This order is in a foreign currency, which Groot cannot refund automatically yet. Record it by hand.",
              "PERIOD_CLOSED": "The accounting period of this refund is closed. Reopen it, then check again, or record the refund by hand.",
              "POSTING_BEFORE_CONVERSION_DATE": "This refund is dated before your books start. Record it by hand."
            }
          },
          "check": {
            "button": "Check recent orders",
            "running": "Checking orders",
            "counts": "Posted {posted} · Held {held} · Already posted {already}",
            "nothing": "No paid orders to post since automatic posting was switched on.",
            "failed": "{count} could not be posted and will be tried again.",
            "more": "There are more orders to check. Check again to continue.",
            "notAuthorised": "Automatic posting is off, so there is nothing to check."
          },
          "orderStatus": {
            "pending": "Pending payment",
            "processing": "Processing",
            "on-hold": "On hold",
            "completed": "Completed",
            "cancelled": "Cancelled",
            "refunded": "Refunded",
            "failed": "Failed",
            "trash": "Deleted",
            "checkout-draft": "Draft"
          },
          "past": {
            "title": "Past orders",
            "description": "Bring in orders that were paid before automatic posting was switched on.",
            "warning": "Only bring in orders that are not already in your books. Groot adds back the stock these sales already took, so your count stays right.",
            "startLabel": "Start date",
            "reasonLabel": "Reason",
            "reasonPlaceholder": "Why are you bringing these in?",
            "previewing": "Checking your store",
            "previewLine": "{orders, plural, one {# order} other {# orders}}, {total} · {willPost} will post · {held} held",
            "alreadyPosted": "{count} already posted",
            "holdItem": "{count, plural, one {# order} other {# orders}}: {reason}",
            "topUp": "Stock added back for these sales: {items}",
            "refunds": "Refunds listed on these orders: {count}. Each posts after its order.",
            "waiting": "{amount} will wait at CHIP until the bank statement for these dates is in Bank / Cash",
            "more": "There are more orders in this range than one check reads. Bring these in, then continue.",
            "nothing": "No paid orders in this range.",
            "button": "Bring in {count, plural, one {# past order} other {# past orders}}",
            "buttonNone": "Nothing to bring in",
            "running": "Bringing in orders",
            "continue": "Continue",
            "moreToDo": "There are more orders to bring in. Continue to carry on.",
            "done": "All orders in this range are in.",
            "consent": "Past orders from {from}, brought in by {name} on {date}",
            "consentNoName": "Past orders from {from}, brought in on {date}",
            "onlyEarlier": "The start date can only move earlier.",
            "notAuthorised": "Automatic posting is off, so past orders cannot be brought in."
          }
        },
        "affiliates": {
          "loading": "Loading affiliates",
          "title": "Affiliates",
          "description": "AffiliateWP commissions become supplier bills, one supplier per affiliate. You pay each bill in Groot, then mark the referral paid in AffiliateWP yourself.",
          "status": {
            "connected": "Connected",
            "needsAttention": "Needs attention",
            "notConnected": "Not connected"
          },
          "ownerOnly": "Only the owner can connect AffiliateWP.",
          "connect": {
            "intro": "Create a read-only API key in AffiliateWP, then paste its public key and token here. Groot only reads.",
            "keysLink": "Open AffiliateWP API keys",
            "publicKey": "Public key",
            "token": "Token",
            "help": "Groot keeps the key in secure storage and never shows it again. You can revoke it in AffiliateWP at any time.",
            "submit": "Connect AffiliateWP"
          },
          "facts": {
            "access": "Access",
            "keyEnding": "Read-only key ending {last4}",
            "verified": "Last tested",
            "notTested": "Not tested yet",
            "connected": "Connected"
          },
          "test": "Test AffiliateWP key",
          "disconnect": "Disconnect AffiliateWP",
          "cancel": "Cancel",
          "disconnectTitle": "Disconnect AffiliateWP?",
          "disconnectMessage": "Groot deletes its copy of the key. Suppliers and bills already posted stay in your books. Revoke the key in AffiliateWP too.",
          "check": {
            "button": "Check referrals",
            "never": "Not checked yet. Referrals are also read whenever a paid order posts.",
            "summary": "Checked {date}: {billed} billed, {waiting} waiting, {notInGroot} with the order not in Groot, {held} held, {rejected} rejected.",
            "truncated": "Only the newest referrals were read. Press Check referrals again for the rest."
          },
          "account": {
            "notReady": "Choose the Affiliate commission account under Chart of Accounts, Payment & posting before commissions can be billed.",
            "open": "Open Payment & posting",
            "create": "Create the Affiliate commission account",
            "createHint": "Groot adds the standard cost of sales account for it, or uses one you already have, and chooses it. Held commissions bill the next time you check referrals."
          },
          "errors": {
            "generic": "Something went wrong. Try again.",
            "AFFILIATE_UNAUTHORIZED": "AffiliateWP rejected the key. Check the public key and token.",
            "AFFILIATE_API_NOT_FOUND": "Groot could not find the AffiliateWP REST API on this store. Check that AffiliateWP is active and its REST API is on.",
            "AFFILIATE_RATE_LIMITED": "AffiliateWP is limiting requests. Try again in a minute.",
            "AFFILIATE_REDIRECTED": "The store redirected the request. Groot never follows a redirect with a key.",
            "AFFILIATE_NOT_JSON": "The store answered with something that is not AffiliateWP data. A firewall may be blocking Groot.",
            "AFFILIATE_STORE_ERROR": "AffiliateWP reported an error. Try again.",
            "AFFILIATE_UNREACHABLE": "Groot could not reach the store.",
            "AFFILIATE_KEY_INVALID": "That does not look like an AffiliateWP public key and token.",
            "AFFILIATE_ALREADY_CONNECTED": "AffiliateWP is already connected.",
            "AFFILIATE_NOT_CONNECTED": "AffiliateWP is not connected.",
            "WOOCOMMERCE_NOT_CONNECTED": "Connect the store first.",
            "WOOCOMMERCE_OWNER_REQUIRED": "Only the owner can do this.",
            "WOOCOMMERCE_FORBIDDEN": "You do not have access to this.",
            "WOOCOMMERCE_CREDENTIAL_STORE_FAILED": "Groot could not store the key securely. Try again.",
            "WOOCOMMERCE_CREDENTIAL_DELETE_FAILED": "Groot could not delete the stored key, so AffiliateWP was not disconnected. Try again.",
            "WOOCOMMERCE_CREDENTIALS_UNAVAILABLE": "Groot no longer holds the key. Disconnect and connect AffiliateWP again.",
            "NETWORK": "Could not reach Groot. Check your connection.",
            "AFFILIATE_ACCOUNT_CODE_OCCUPIED": "Groot could not create the account because its standard account number is already used by another account. Choose the account you use under Payment & posting.",
            "AFFILIATE_ACCOUNT_NOT_USABLE": "The account chosen for Affiliate commission cannot take postings. Choose a cost of sales account under Payment & posting.",
            "AFFILIATE_ACCOUNT_PARENT_IN_USE": "Groot could not create the account here because it would change an account you already use. Choose the account you use under Payment & posting.",
            "AFFILIATE_ACCOUNT_NOT_IN_CATALOGUE": "Groot cannot create this account automatically. Choose the account you use under Payment & posting.",
            "AFFILIATE_ACCOUNT_UNVERIFIED": "Groot prepared the account but this business still posts through a different one. Choose the account you want under Payment & posting."
          },
          "messages": {
            "connected": "AffiliateWP connected.",
            "testPassed": "AffiliateWP key works.",
            "checked": "Referrals checked.",
            "disconnected": "AffiliateWP disconnected.",
            "revokeReminder": "Also revoke the key in AffiliateWP under Tools, API Keys.",
            "accountCreated": "Affiliate commission account created and chosen.",
            "accountReused": "Using your existing account {name} for Affiliate commission.",
            "accountReady": "The Affiliate commission account is already set up.",
            "accountNext": "Press Check referrals to bill the held commissions.",
            "synced": "Affiliates synced",
            "syncedDetail": "{created} new, {updated} updated, {unchanged} unchanged.",
            "syncNeedsDetails": "{count} active affiliates have no name in AffiliateWP, so Groot could not create their suppliers.",
            "syncPartial": "Some affiliates were not synced. Press Sync affiliates again."
          },
          "sync": {
            "button": "Sync affiliates",
            "last": "Last synced {date}",
            "never": "Not synced yet. Affiliates also sync whenever an order arrives."
          },
          "summary": {
            "label": "Affiliate summary",
            "line": "{affiliates, plural, one {# affiliate} other {# affiliates}} · {bills, plural, one {# bill} other {# bills}} · {owed} owed",
            "capped": "Counts cover the first affiliates and the latest bills only.",
            "link": "View affiliate commissions in Purchases"
          }
        },
        "sections": {
          "nav": {
            "label": "WooCommerce sections"
          },
          "segment": {
            "store": "Store",
            "webhooks": "Webhooks",
            "posting": "Posting",
            "orders": "Orders",
            "affiliates": "Affiliates"
          },
          "state": {
            "success": "Working",
            "warning": "Needs attention",
            "muted": "Not active"
          },
          "fact": {
            "connected": "Connected",
            "needsAttention": "Needs attention",
            "webhooksNotSetUp": "Not set up",
            "webhooksChecking": "Checking",
            "webhooksUnreadable": "Could not check",
            "webhooks": "{active}/{total}",
            "postingOn": "On",
            "postingOff": "Off",
            "ordersNone": "No orders yet",
            "orders": "{posted} posted",
            "ordersHeld": "{posted} posted · {held} held",
            "affiliatesNotConnected": "Not connected",
            "affiliatesToBill": "{count} to bill",
            "affiliatesUpToDate": "Up to date"
          },
          "webhooks": {
            "allOn": "All {count} webhooks are on · Checked {date}",
            "showSetup": "Show setup",
            "hideSetup": "Hide setup"
          },
          "orders": {
            "bringIn": "Bring in past orders",
            "needsWebhooks": "Orders show here once the webhooks are set up.",
            "openWebhooks": "Open webhooks"
          },
          "log": {
            "storeStatus": "Store status",
            "checks": "Checks"
          },
          "heldShort": "Held · {reason}",
          "holdInfoLabel": "Why this order is held",
          "shortHold": {
            "CONNECTOR_OWNER_AUTHORISATION_REQUIRED": "Posting is off",
            "CONNECTOR_GATEWAY_NOT_CONFIGURED": "Payment method not set up",
            "CONNECTOR_BUYER_INDEX_NOT_READY": "Customer matching not ready",
            "CONNECTOR_BUYER_AMBIGUOUS": "Duplicate customers",
            "CONNECTOR_TOTALS_MISMATCH": "Amounts do not add up",
            "CONNECTOR_PRODUCT_UNAVAILABLE": "Product inactive",
            "CONNECTOR_ORDER_NOT_PAID": "Not paid yet",
            "CONNECTOR_CONNECTION_REUSED": "Different store",
            "CONNECTOR_CONNECTION_UNAVAILABLE": "Store needs attention",
            "CONNECTOR_PAID_BEFORE_AUTHORISATION": "Paid before posting began",
            "CONNECTOR_FEE_INVALID": "Gateway fee looks wrong",
            "FEATURE_NOT_ENABLED": "Invoicing is off",
            "WOOCOMMERCE_VARIATION_NOT_SUPPORTED": "Has a variation",
            "WOOCOMMERCE_PRODUCT_NOT_IMPORTED": "Product not imported",
            "WOOCOMMERCE_ORDER_UNREADABLE": "Amounts unreadable",
            "WOOCOMMERCE_NO_PAYMENT_METHOD": "No payment method",
            "PERIOD_CLOSED": "Period closed",
            "POSTING_BEFORE_CONVERSION_DATE": "Before go-live",
            "generic": "Could not post",
            "CONNECTOR_ORDER_BEFORE_AUTHORISATION": "Placed before posting began",
            "CONNECTOR_ORDER_POSTED_PAID": "Already posted as paid",
            "CONNECTOR_ORDER_NOT_ACCEPTED": "Store has not accepted it",
            "WOOCOMMERCE_OPEN_ORDER_HAS_REFUNDS": "Has a refund"
          }
        },
        "heldOrders": {
          "title": "Held orders",
          "description": "These orders were held because the store gave them no payment method, or because they were placed before automatic posting began. If your client confirms they were bank transfers, post them as open invoices. The payment is recorded later, when the transfer shows in your bank statement.",
          "listLabel": "Held orders you can post",
          "colOrder": "Order",
          "colCreated": "Created",
          "colTotal": "Total",
          "selectOrder": "Select order {order}",
          "selectAll": "Select all",
          "clearSelection": "Clear selection",
          "selectedCount": "{count} selected",
          "post": "{count, plural, one {Post # as an open invoice} other {Post # as open invoices}}",
          "confirmTitle": "Post as open invoices?",
          "confirmBody": "{count, plural, one {# invoice} other {# invoices}}, {amount}, will wait in receivables until matched from your bank statement. Groot does not email the buyers.",
          "confirmBodyNoTotal": "{count, plural, one {# invoice} other {# invoices}} will wait in receivables until matched from your bank statement. The amounts are read from the store when each order posts. Groot does not email the buyers.",
          "reasonLabel": "Reason (optional)",
          "confirm": "Post invoices",
          "cancel": "Cancel",
          "posting": "Posting",
          "resultPosted": "Posted {count, plural, one {# invoice} other {# invoices}} ({amount}).",
          "resultAlready": "{count} already in the books.",
          "resultHeld": "{count} held. The reason is shown in Recent order updates.",
          "resultNotAccepted": "{count} not accepted by the store yet, so nothing was posted for them.",
          "resultMissing": "{count} no longer in the store.",
          "resultFailed": "{count} could not be posted yet. Try again.",
          "resultMore": "More orders are left in your selection. Continue to post them.",
          "continue": "Continue",
          "errorNotAuthorised": "Switch on automatic posting in Posting first, then try again.",
          "errorForbidden": "Only an owner or a finance admin can post these orders.",
          "errorGeneric": "Could not post these orders. Try again, and contact support if it keeps happening.",
          "needsPosting": "Automatic posting is off. Switch it on in Posting to post these orders.",
          "truncated": "Showing the newest {count} held orders."
        }
      },
      "sqlBridge": {
        "title": "SQL Account on this PC (Bridge)",
        "description": "Groot posts your supplier invoices into SQL Account on the Windows PC that runs it, through a small program called Groot SQL Bridge. The Bridge only makes outgoing calls, so you do not open a port or change a firewall.",
        "status": {
          "heading": "Bridge status",
          "loading": "Checking Bridge status",
          "host": "Windows PC",
          "version": "Bridge version",
          "sqlVersion": "SQL Account version",
          "company": "Company the Bridge is signed in to",
          "database": "Company database",
          "notReported": "Not reported yet",
          "state": {
            "neverEnrolled": "Not set up",
            "connected": "Connected",
            "stale": "Not responding",
            "revoked": "Revoked"
          },
          "explain": {
            "neverEnrolled": "No Bridge is set up yet, so Groot cannot post to SQL Account.",
            "connected": "The Bridge checked in at {at}.",
            "stale": "The Bridge last checked in at {at} and has gone quiet since. Check that the Windows PC is on, that you are logged in to Windows, and that the Bridge icon is in the notification area.",
            "staleNeverSeen": "A Bridge is registered but has never checked in. Check that it is installed and running on the Windows PC.",
            "revoked": "Access is revoked. The Bridge stops the next time it checks in."
          },
          "graceOpen": "The previous token still works until {at}. Install the new token on the Windows PC before then.",
          "cadence": "Checks for work",
          "cadenceTier": {
            "busy": "Every {seconds} seconds. Invoices you post reach SQL Account within moments.",
            "warm": "Every {seconds} seconds, because this business posted recently.",
            "idle": "Every {minutes} minutes. That is the longest an invoice will wait.",
            "dormant": "Every {minutes} minutes. Nothing has been sent to SQL Account here for a month, so the Bridge checks less often. The next invoice you post may take up to {minutes} minutes to appear, and after that it speeds up again straight away."
          }
        },
        "stranded": {
          "title": "{count, plural, =1 {# invoice is waiting} other {# invoices are waiting}}.",
          "body": "The Bridge is not checking in, so nothing is being posted to SQL Account. Start the Bridge on the Windows PC, then check back here."
        },
        "blockedByCompany": {
          "title": "{count, plural, =1 {# invoice is waiting} other {# invoices are waiting}} for the company check.",
          "body": "The Bridge does not pick up work until the SQL Account company below is confirmed. Check it and confirm it, and the waiting invoices go through."
        },
        "company": {
          "heading": "Company check",
          "intro": "A Windows PC can hold several SQL Account companies. Before Groot posts, confirm that the company above is the right one for this business.",
          "nothingReported": "The Bridge has not reported a company yet. It reports one after it signs in to SQL Account. Check that SQL Account is installed on that PC and that you are still logged in to Windows.",
          "unconfirmed": "Check the company name and database above. If they are the right ones for this business, confirm them. Posting stays off until you do.",
          "changed": "Posting is paused because the Bridge now reports a different company than the one you confirmed ({title}, {database}). If the change is expected, confirm the new company. If not, check which company the Bridge is signed in to.",
          "confirmed": "Confirmed by {name} on {at}: {title}, {database}.",
          "confirmedNoName": "Confirmed on {at}: {title}, {database}.",
          "confirm": "Confirm the company and start sending invoices",
          "confirming": "Confirming",
          "errors": {
            "notEnrolled": "There is no active Bridge to confirm a company for. Connect the Bridge first.",
            "nothingReported": "The Bridge has not reported a company yet, so there is nothing to confirm.",
            "generic": "Groot could not confirm the company. Nothing was changed. Please try again."
          },
          "toasts": {
            "confirmed": "Company confirmed.",
            "postingOn": "Posting is on.",
            "postingOff": "Posting is off.",
            "automaticOn": "Automatic sending is on.",
            "automaticOff": "Automatic sending is off.",
            "reviewTurnedOn": "Require review before posting is now on.",
            "postingTurnedOn": "Posting is now on.",
            "automaticTurnedOn": "Automatic sending is now on."
          },
          "consent": "After you confirm, uploaded supplier invoices wait for you to check them. Each one you confirm and post is then sent to this company in SQL Account automatically. This also turns on Require review before posting for your business. If AutoCount posting is on for this business, confirming does not turn any of this on.",
          "reviewForAutomatic": "Automatic sending needs supplier invoice review on. Your choice to turn review off stays unchanged.",
          "defaultReasons": {
            "autocount_posting_enabled": "AutoCount posting is on for this business, and a business posts to one accounting program only. Sending to SQL Account stays off. Turn off AutoCount posting first, then press Resume sending on this page.",
            "review_required": "To send invoices automatically, turn on supplier invoice review under Settings > Business > Invoice review.",
            "not_entitled": "Automatic sync is not switched on for your workspace, so no sending settings were turned on. Contact support@hellogroot.com."
          },
          "uncertainSave": "If SQL Account does not confirm a save, Groot holds the invoice and asks a person to check SQL Account before any resend.",
          "previousChoices": "Posting or automatic sending you previously turned off stays off."
        },
        "token": {
          "heading": "Your enrolment token",
          "shownOnce": "Copy this now. Groot shows it once and cannot show it again, because only a hash is stored. If you lose it, register again for a new one.",
          "use": "Next: on the Windows PC that runs SQL Account, run the install script and paste this token when it asks for it. Open the install guide for the steps.",
          "copy": "Copy token",
          "dismiss": "I have copied it"
        },
        "download": {
          "file": "Download {file}",
          "preparing": "Preparing",
          "version": "Version {version}, build {commit}",
          "loading": "Checking the latest Bridge release",
          "notPublished": "The Bridge has not been published yet, so the download is off. Please check again later, or contact Groot support.",
          "unavailable": "The latest Bridge release could not be checked. An existing Bridge keeps running. Check again before downloading.",
          "retryRelease": "Check again",
          "updateAvailable": "Update available: installed {installed}, latest {latest}.",
          "current": "This Windows PC is on the latest published version.",
          "checksum": "Checksum (SHA-256): {sha256}",
          "checksumHint": "Before you run it, confirm the file matches. In PowerShell: Get-FileHash your-file -Algorithm SHA256",
          "unsigned": "This program is not code signed yet, so Windows warns you the first time you run it. That warning is expected.",
          "failed": "The download could not be prepared. Try again, and contact support if it keeps happening.",
          "releaseChanged": "A newer Bridge release was just published. The details above are refreshed: check the checksums and download again.",
          "copyCommand": "Copy command"
        },
        "enrol": {
          "body": "Use this only with the install script. Registering gives you a one-time token to paste into the script. Groot keeps only a fingerprint of the token.",
          "action": "Register Bridge",
          "rotate": "Register again and replace the token",
          "revoke": "Revoke access",
          "rotateNote": "Registering again gives you a new token and keeps the old one working for 24 hours, so the Bridge does not stop while you update it. It also clears the company confirmation: confirm the company again afterwards.",
          "revokedHint": "To use it again, press \"Connect\" next to this book in the Bridge window. If you use the install script, register again for a new token.",
          "confirmRotate": {
            "title": "Register the Bridge again?",
            "message": "This creates a new token and clears the company confirmation, so posting pauses until you confirm the company again. The old token keeps working for 24 hours.",
            "confirm": "Register again"
          },
          "confirmRevoke": {
            "title": "Revoke the Bridge?",
            "message": "The Bridge stops the next time it checks in, invoices that are waiting fail, and the company confirmation is cleared. Documents already saved in SQL Account are not touched.",
            "confirm": "Revoke"
          },
          "refusals": {
            "autocount_bridge_enrolled": "An AutoCount Bridge is already set up for this business, and a business posts to one accounting program only. Revoke the AutoCount Bridge first if you want to switch to SQL Account.",
            "not_enrolled": "There is no active Bridge to revoke.",
            "already_revoked": "This Bridge is already revoked.",
            "not_entitled": "This feature is not switched on for your workspace. Contact support@hellogroot.com."
          }
        },
        "jobs": {
          "heading": "SQL Account write queue",
          "loading": "Loading the queue",
          "empty": "Nothing has been sent to SQL Account yet.",
          "notPosted": "Not in SQL Account yet",
          "docNo": "SQL Account document {docNo}",
          "amount": "Amount {amount}",
          "attempts": "{count, plural, =1 {# attempt} other {# attempts}}",
          "requestedBy": "Sent by {name}",
          "openInvoice": "Open invoice",
          "retrying": "Checking again automatically (re-check {count} of {max}). Groot looks for the document in SQL Account before it ever saves again.",
          "ambiguousHint": "Groot could not confirm whether SQL Account saved this, even after checking again automatically. Search SQL Account for it before anything else, using the reference under Technical details. Do not send it again until you have recorded what you found.",
          "ambiguousReason": {
            "duplicateDocument": "SQL Account already has an invoice with this number from this supplier, so nothing new was saved. If it is the same bill, choose Record what you found and say SQL Account has it. If it is a different bill, key it into SQL Account by hand under another invoice number, then record that number the same way.",
            "bookChangedDuringSave": "SQL Account switched to another book while this bill was saving, so the bill may be in either book or in neither. Look in both. If it landed in the wrong book, delete it there. Then choose Record what you found and say whether the right book has it."
          },
          "resolvedPosted": "Checked in SQL Account and recorded on {at}: SQL Account has it as document {docNo}.",
          "resolvedNotPosted": "Checked in SQL Account and recorded on {at}: SQL Account does not have it. Sending it again is safe.",
          "technical": {
            "toggle": "Technical details",
            "reference": "Reference written to SQL Account (Reference 4): {key}",
            "internalKey": "SQL Account internal document key: {key}"
          },
          "total": {
            "agrees": "SQL Account recorded the same total Groot sent.",
            "unknown": "Groot could not read back the total SQL Account recorded, so the two amounts have not been compared.",
            "disagrees": "SQL Account saved a different document total: Groot sent {expected}, SQL Account recorded {posted}. Open that document in SQL Account and check it."
          },
          "state": {
            "queued": "Waiting",
            "retrying": "Checking again",
            "leased": "Picked up",
            "writing": "Writing",
            "succeeded": "Saved",
            "failed": "Failed",
            "ambiguous": "Needs checking"
          },
          "retry": "Try again",
          "truncated": "Only the most recent items are shown.",
          "retryRefusal": {
            "not_retryable": "This one cannot be tried again. Refresh the page to see where it stands.",
            "retry_would_duplicate": "Another attempt for this invoice may already have reached SQL Account, so Groot will not send it again. Check that other attempt first."
          },
          "failure": {
            "sql_login_rejected": "SQL Account refused the sign-in the Bridge uses. Nothing was posted. In the Bridge window on that PC, press \"Connect\" next to this book, enter the login again, then press \"Test and save\". If you use the install script, run it with configure and enter the login again.",
            "sql_company_unavailable": "The Bridge could not open the SQL Account company. Nothing was posted. Check that SQL Account is installed, that the company is available on that PC, and that the install script points at the right company.",
            "sql_com_unavailable": "The Bridge could not start SQL Account on the Windows PC. Nothing was posted. Check that SQL Account is installed on that PC, then restart the Bridge.",
            "sql_master_missing": "SQL Account does not have a supplier, account or tax code that this invoice uses. Nothing was posted. Check the code mappings, then try again.",
            "sql_master_missing_supplier": "SQL Account does not have the supplier code mapped for this invoice. Nothing was posted. Correct this supplier's SQL Account creditor code on the Import & Export page (SQL Accounting (AP Invoice) template, Map Codes step), or add the supplier in SQL Account, then try again.",
            "sql_master_missing_account": "SQL Account does not have an account this invoice uses. Nothing was posted. Correct the line's account mapping on Import & Export (Map Codes), or the default expense account on this page, under Where invoices land in SQL Account, or add the account in SQL Account, then try again.",
            "sql_master_missing_tax": "SQL Account does not have a tax code this invoice uses. Nothing was posted. Correct the tax code mapping on the Import & Export page (Map Codes step), or add the tax code in SQL Account, then try again.",
            "companion_unauthorized": "The Bridge could not prove who it was, so Groot turned it away. Nothing was posted. Register the Bridge again and install the new token.",
            "sql_save_refused": "SQL Account refused to save this invoice. A closed period or one of your own SQL Account rules is the usual cause. Check SQL Account before you try again.",
            "sql_dialog_blocked": "A message window in SQL Account blocked the save. Close any open SQL Account windows on that PC, check SQL Account, then try again.",
            "session_lost": "The Bridge lost its SQL Account session part way through. It signs back in on its own. Check SQL Account for this invoice before you try again.",
            "unclassified": "The Bridge could not put a name to this failure. Contact Groot support with this invoice reference.",
            "unknown": "Groot could not tell what went wrong with this one. Contact Groot support with this invoice reference."
          }
        },
        "resolve": {
          "action": "Record what you found",
          "formHeading": "What did you find in SQL Account?",
          "lookFirst": "Search SQL Account for this invoice first, using the reference under Technical details or the supplier's invoice number. Groot could not read the answer itself, so whatever you record here is taken as what you saw.",
          "docNoLabel": "SQL Account document number (needed only if SQL Account has it)",
          "docNoPlaceholder": "Copy it from SQL Account",
          "posted": "SQL Account has it",
          "notPosted": "SQL Account does not have it",
          "cancel": "Not now",
          "consequence": "If SQL Account has it, Groot records the document number and stops asking. If it does not, sending it again becomes safe.",
          "errors": {
            "generic": "Groot could not record what you found. Nothing was changed. Please try again.",
            "needsDocNo": "Enter the SQL Account document number you found, so the record shows which document it is.",
            "alreadyResolved": "Someone else has already recorded what happened to this one. Refresh the page to see what they found, and do not send it again.",
            "notAmbiguous": "This one no longer needs checking. Refresh the page to see where it ended up.",
            "jobGone": "This item is no longer in the queue, so there is nothing to record against it. Refresh the page."
          }
        },
        "toasts": {
          "enrolled": "Bridge registered. Copy the token now.",
          "rotated": "Bridge registered again. The old token works until {at}.",
          "enrolFailed": "Groot could not register the Bridge. Please try again.",
          "revoked": "Bridge access revoked.",
          "revokeFailed": "Groot could not revoke access. Please try again.",
          "retried": "Queued again for SQL Account.",
          "retryFailed": "Groot could not queue it again. Please try again.",
          "recordedPosted": "Recorded: SQL Account has it.",
          "recordedNotPosted": "Recorded: SQL Account does not have it.",
          "copied": "Copied.",
          "copyFailed": "Groot could not copy it. Select the text and copy it yourself."
        },
        "errors": {
          "title": "SQL Bridge error",
          "body": "Something went wrong loading the SQL Bridge. Your settings and your invoices are safe.",
          "retry": "Try again",
          "reload": "Reload page",
          "supportHint": "If this keeps happening, contact support.",
          "notAllowed": "Only an owner or a finance admin can see or change the SQL Bridge."
        },
        "postSettings": {
          "title": "Sending to SQL Account",
          "loading": "Loading posting settings",
          "unavailable": "Posting settings are not available right now.",
          "post": {
            "on": "Sending to SQL Account is on.",
            "off": "Sending to SQL Account is off."
          },
          "blocked": {
            "noBridge": "Connect the Bridge first. Posting cannot be turned on without one.",
            "nothingReported": "Posting stays off until the Bridge reports its SQL Account company and you confirm it above.",
            "unconfirmed": "Posting stays off until you confirm the SQL Account company above.",
            "changed": "Posting is paused because the Bridge reports a different company than the one you confirmed. Confirm the company above again to continue."
          },
          "refusals": {
            "autocount_posting_enabled": "AutoCount posting is on for this business, and a business posts to one accounting program only. Turn off AutoCount posting first, then turn on SQL Account posting.",
            "bridge_not_enrolled": "Connect the Bridge first. Posting cannot be turned on without one.",
            "company_unconfirmed": "Confirm the SQL Account company above first, then turn posting on.",
            "company_changed": "The Bridge reports a different company than the one you confirmed. Confirm the company above again first.",
            "posting_required": "Automatic sending needs posting turned on first.",
            "review_required": "Automatic sending needs supplier invoice review turned on first, under Settings > Business > Invoice review.",
            "auto_sync_requires_posting": "Pause automatic sending before you turn posting off.",
            "unknown": "Groot could not change that setting. Nothing was changed.",
            "not_entitled": "This feature is not switched on for your workspace. Contact support@hellogroot.com."
          },
          "saveFailed": "Groot could not save that change. Nothing was changed. Please try again.",
          "itemizedNotice": "Your business exports itemized purchase invoices. The Bridge posts expense lines only for now. To send through the Bridge, switch the purchase invoice mode to Expense in Settings > Integrations > SQL Accounting > File import & export.",
          "autoSync": {
            "enabledFrom": "On since {date}",
            "noBacklog": "Earlier invoices stay untouched. Use the invoice's Send to SQL Account action only when you intentionally want to send one.",
            "pauseConsequence": "Pausing stops new sends. An invoice already accepted for sending carries on to its recorded outcome.",
            "enable": "Turn on automatic sending",
            "acknowledgement": "I understand that new posted invoices will be written into SQL Account, and that an uncertain save must be checked there by a person before any resend.",
            "activityTitle": "Recent automatic sends",
            "empty": "Nothing has been sent automatically yet.",
            "postedAs": "Saved in SQL Account as document {docNo}",
            "needsAttention": "Needs attention",
            "resolved": "Checked and recorded by a person",
            "covered": "Already covered",
            "cancelled": "Cancelled",
            "inProgress": "In progress",
            "openInvoice": "Open invoice",
            "genericReason": "Groot did not send this invoice. Check its details and SQL Bridge settings before trying again.",
            "authorizerNoLongerEligible": "The person who turned on automatic sending no longer has the access it needs. An owner or finance admin must turn it on again.",
            "dispatchFailed": "Groot could not hand this invoice to the Bridge. The invoice itself is posted and safe. Open it and use Send to SQL Account.",
            "policyInactive": "Automatic sending was off by the time this invoice was handed over, so it was not sent."
          },
          "sending": {
            "manual": "Invoices you post in Groot are sent when you press Send to SQL Account on the invoice.",
            "on": "Supplier invoices you confirm and post in Groot are sent to SQL Account automatically.",
            "paused": "Sending to SQL Account is paused.",
            "inert": "Automatic sending is on but nothing is being sent, because supplier invoice review is off. Turn review on to continue.",
            "notSetUp": "Confirm the SQL Account company to set up sending.",
            "install": "Install the Bridge on the Windows PC that runs SQL Account to set up sending.",
            "blocked": "Sending is blocked until you confirm the SQL Account company again. You can turn sending off below.",
            "connect": "Connect this business to its SQL book in the Bridge window to set up sending."
          },
          "landing": {
            "title": "Where invoices land in SQL Account",
            "description": "The SQL Account code that supplier invoice lines are booked to when a line is not matched to a stock item, for example 610-000.",
            "creditors": "Supplier creditor codes come in when you read the chart from SQL Bridge. If a name is spelled differently in SQL Account, set its code on Import & Export, under SQL Accounting (AP Invoice), Map Codes.",
            "link": "Open Import & Export"
          },
          "pause": "Pause sending",
          "resume": "Resume sending",
          "reviewRequired": "Automatic sending needs supplier invoice review on.",
          "reviewLink": "Settings > Business > Invoice review",
          "turnOff": "Turn off sending"
        },
        "steps": {
          "heading": "Set up in 3 steps",
          "next": "Next:",
          "install": {
            "title": "Install it on the Windows PC"
          },
          "company": {
            "title": "Confirm the company"
          },
          "hint": {
            "install": "On the Windows PC that runs SQL Account, download GrootSqlBridge.exe and double-click it. Open the install guide for the steps.",
            "company": "Check the company name below and confirm it. If no name shows yet, open this book in SQL once, or save its SQL login in the Bridge window, so Groot can read it.",
            "ready": "Setup is done. Supplier invoices you post are sent to SQL Account.",
            "readyPostingOff": "Setup is done. Turn on posting below to start sending supplier invoices to SQL Account.",
            "readyUnknown": "Setup is done. Check the posting settings below to see whether sending is on.",
            "connect": "In the Bridge window on the Windows PC, press \"Connect\" next to the SQL book for this business, then pick this business in your browser. Open the install guide for the steps."
          },
          "state": {
            "done": "Done",
            "current": "Current step",
            "todo": "Not started"
          },
          "connect": {
            "title": "Connect the SQL book"
          }
        },
        "guide": {
          "title": "Install the SQL Bridge",
          "label": "Install guide",
          "close": "Close the install guide",
          "open": "Open the install guide",
          "intro": "You do this once, on the Windows PC that runs SQL Account. It takes a few minutes and needs no administrator rights.",
          "checkFiles": "Check the files (optional)",
          "steps": {
            "download": {
              "title": "Download the Bridge",
              "body": "Do this on the Windows PC that runs SQL Account. If you are reading this on another computer, download the file there and copy it over with a USB drive or by emailing it to yourself."
            },
            "open": {
              "title": "Open it",
              "body": "Double-click GrootSqlBridge.exe. It installs itself, so you do not need administrator rights, and it starts by itself each time you sign in to Windows. A window opens with the SQL books on this PC. If an older Bridge is already running, the new one asks you to quit the old one from its tray icon first."
            },
            "connect": {
              "title": "Connect the SQL book",
              "body": "In the Bridge window, press \"Connect\" next to the SQL book for this business. The Bridge asks for that book's SQL login. Use the login you already use in SQL Account. Saving it is optional: press \"Test and save\" to let bills go across while the book is closed, or press \"Skip\". Without a saved login, a bill goes across whenever someone opens that book in SQL."
            },
            "signIn": {
              "title": "Sign in to Groot and pick this business",
              "body": "Your browser opens Groot. Sign in if it asks, then pick this business. Only an owner or a finance admin can do this. The page shows a code: check that it matches the code in the Bridge window."
            },
            "done": {
              "title": "Come back here",
              "body": "This card shows Connected. When the Bridge could read the company name from the book, connecting also confirms the company. If it could not, the card asks you to confirm the company first. Connecting does not switch posting on. You control that in Groot."
            }
          },
          "running": {
            "title": "Keep it running",
            "body": "The Bridge works only while this Windows user is signed in and the PC is on. Bills wait in Groot until it is back."
          },
          "upgrade": "After SQL Account updates itself, each book asks to upgrade the first time you open it. Open the book once in SQL Account and answer SQL's question. Until then the Bridge shows SQL's own words and the bill waits.",
          "safe": {
            "title": "Where is the SQL password kept?",
            "body": "Only on that Windows PC, encrypted for your Windows user. Groot does not receive it. The Bridge asks for it only in its own window. You can remove a saved login in the Bridge window, under \"Manage\"."
          },
          "help": {
            "title": "Stuck?",
            "body": "Close this guide any time and open it again from the status card. If a step fails, contact Groot support and say which step."
          },
          "script": {
            "summary": "Set up with the install script instead",
            "intro": "Use this route only if the exe cannot run on that PC, or if Groot support asks for it. The script sets up one SQL book and needs a token. Press Register Bridge on the status card to get one.",
            "steps": {
              "files": {
                "title": "Get the script",
                "body": "Download the script here. You also need GrootSqlBridge.exe from the first step above. Work on the Windows PC that runs SQL Account, or copy both files to it with a USB drive."
              },
              "folder": {
                "title": "Put them in one folder",
                "body": "Create a folder called GrootSqlBridge on the C: drive and move both files into it. Keep the folder: the program runs from it."
              },
              "shell": {
                "title": "Open PowerShell in that folder",
                "body": "Open the folder in File Explorer. Click the address bar at the top, type powershell and press Enter. A window with a prompt opens. You do not need administrator rights."
              },
              "run": {
                "title": "Run the installer",
                "body": "Copy the line below, click inside the PowerShell window, right-click to paste, then press Enter."
              },
              "answer": {
                "title": "Answer its questions",
                "intro": "It asks four things, one at a time.",
                "url": "Groot web address: paste this one.",
                "urlMissing": "Groot support will give you the Groot web address.",
                "token": "Enrolment token: paste the token you copied from Groot. Nothing appears as you paste. That is normal: it is hidden for your safety.",
                "company": "Which company: type the number next to your company's name and press Enter. If more than one looks right, ask your accountant. Do not guess.",
                "user": "SQL Account user and password: use the login you already use in SQL Account."
              },
              "start": {
                "title": "Start the Bridge",
                "body": "The installer signs in to SQL Account once as a test and only finishes if that works. Then sign out of Windows and back in, or double-click GrootSqlBridge.exe. A small icon appears near the clock. Keep this Windows user signed in: the Bridge only works while you are."
              }
            }
          }
        },
        "notEntitledNotice": "SQL Account automatic sync is not switched on for your workspace. Groot is not sending invoices to SQL Account. Contact support@hellogroot.com.",
        "chartImport": {
          "title": "Chart of accounts from SQL Bridge",
          "description": "Read the chart straight from SQL Account through the Bridge. Nothing is written until you review it and confirm.",
          "read": "Read chart from SQL Bridge",
          "reading": "Reading the chart from SQL Bridge. This can take a few minutes.",
          "queued": "Waiting for the SQL Bridge to pick up the read.",
          "readReady": "The chart is read and ready for your review.",
          "readFailed": "The chart could not be read from SQL Bridge. Check that the Bridge is running, then read it again.",
          "review": "Review chart",
          "cancelRead": "Cancel read",
          "applied": "The chart was imported from SQL Bridge.",
          "appliedAuto": "The chart was imported automatically from SQL Bridge.",
          "skipped": "{count} SQL accounts were left out because their type or code is not recognised.",
          "auto": {
            "title": "Import automatically every week",
            "description": "When on, Groot reads the chart each Monday. It imports on its own only when your chart is empty and nothing needs an answer, or when it refreshes a chart already imported from SQL Bridge with nothing to archive. Anything else waits here for your review."
          },
          "held": {
            "title": "Waiting for your review",
            "decisionsRequired": "The import needs an answer for the posting accounts or the expense categories first.",
            "archivesPending": "The new chart would archive accounts, so it needs your review.",
            "existingChart": "Your chart already has accounts of its own. Review the import before it changes anything.",
            "tooLarge": "This chart has more accounts than one import can write, so it needs a review.",
            "notEntitled": "Your plan does not include the SQL Bridge, so the chart was not imported.",
            "cancelled": "The import was cancelled.",
            "unknown": "This import is waiting for your review."
          },
          "errors": {
            "generic": "Something went wrong. Try again in a moment.",
            "forbidden": "Only the owner or a finance admin can read or import the chart.",
            "notEntitled": "Your plan does not include the SQL Bridge.",
            "companionUnavailable": "The SQL Bridge is not connected to this business.",
            "bridgeUpdateRequired": "Update the SQL Bridge before reading the chart.",
            "companyChanged": "The company open in SQL Account has changed. Confirm the company on the SQL Bridge settings first.",
            "companyUnconfirmed": "Confirm the SQL Account company in the SQL Bridge settings before reading the chart.",
            "alreadyRunning": "A chart read is already in progress or waiting for review.",
            "readNotReady": "This read is no longer available. Read the chart again.",
            "tooLarge": "This chart has more accounts than one import can write. Nothing was changed.",
            "autoSaveFailed": "The setting could not be saved. Try again."
          },
          "suppliers": {
            "willImport": "This also brings in the creditor codes of your {count, plural, one {# supplier} other {# suppliers}} in SQL Account, so you won't need to type them in Map Codes. Any code you already typed stays as it is.",
            "running": "Bringing in your supplier codes from SQL Account.",
            "written": "{count, plural, =0 {No new supplier codes came in from SQL Account.} one {# supplier code came in from SQL Account.} other {# supplier codes came in from SQL Account.}}",
            "alreadySet": "{count, plural, one {# supplier already had its code.} other {# suppliers already had their codes.}}",
            "sharedName": "{count, plural, one {# supplier shares} other {# suppliers share}} a name with another supplier in SQL Account, so these codes did not come in: {names}. Set them in Map Codes.",
            "failed": "The chart came in, but some supplier codes did not. Read the chart again to bring them in."
          }
        },
        "bookState": {
          "bookInUse": "Waiting. {book} is open somewhere else right now. Bills go across when it closes.",
          "loginNeeded": "Waiting. Bills go across when someone opens {book} in SQL on {pc}. Save its SQL login in the Bridge to send them without opening it.",
          "loginRefused": "Stopped. SQL refused the saved login for {book}. Open the Bridge on {pc} and enter it again.",
          "bookMissing": "Waiting. SQL cannot open {book} on {pc}. Load it in SQL, or connect it again from the Bridge.",
          "licenceRefused": "Waiting. SQL has no free user right now. Bills go across when someone logs out.",
          "sqlUnavailable": "Waiting. The Bridge could not start SQL on {pc}.",
          "needsAttention": "Stopped. SQL is showing a message the Bridge cannot answer: {detail}",
          "needsAttentionNoDetail": "Stopped. SQL is showing a message the Bridge cannot answer. Look at SQL on {pc}.",
          "reportedAt": "Reported {at}.",
          "bookFallback": "the book",
          "pcFallback": "the Windows PC"
        }
      }
    }
  },
  "inventoryUI": {
    "header": {
      "title": "Inventory",
      "subtitle": "Stock management across locations"
    },
    "overview": {
      "heading": "Inventory Overview",
      "description": "Track stock levels, movements, and low-stock alerts across all locations."
    },
    "summary": {
      "itemsTracked": "Items Tracked",
      "activeLocations": "Active Locations",
      "lowStock": "Low Stock"
    },
    "movementType": {
      "stockIn": "Stock In",
      "stockOut": "Stock Out",
      "adjustment": "Adjustment",
      "transfer": "Transfer"
    },
    "movementReason": {
      "deliveryOrderPost": "Delivery Order posted",
      "deliveryOrderVoid": "Voided Delivery Order reversal",
      "openingBalance": "Opening balance",
      "manualAdjustment": "Manual adjustment",
      "restockable": "Returned to sellable stock",
      "damaged": "Returned damaged",
      "productionComponentIssue": "Production component issue",
      "productionFinishedGood": "Production finished good",
      "productionCorrectionComponentReturn": "Production correction component return",
      "productionCorrectionFinishedRemoval": "Production correction finished goods removal",
      "transferOut": "Moved to {location}",
      "transferIn": "Moved from {location}",
      "supplierReturn": "Returned to supplier",
      "supplierReturnDamaged": "Damaged, returned to supplier",
      "supplierCreditNoteVoid": "Supplier credit note voided, back in stock",
      "creditNoteVoid": "Credit note voided, taken back out",
      "saleAssemblyPartIssue": "Part used to assemble for a sale",
      "saleAssemblyFinishedGood": "Assembled at the sale",
      "costingSwitchOpening": "Opening layer at the costing method switch"
    },
    "sourceType": {
      "salesInvoice": "Sales Invoice",
      "creditNote": "Credit Note",
      "deliveryOrder": "Delivery Order",
      "apInvoice": "AP Invoice",
      "productionRun": "Production Run",
      "manual": "Manual",
      "openingBalance": "Opening Balance",
      "productionRunCorrection": "Production Correction",
      "stockTransfer": "Stock transfer",
      "supplierCreditNote": "Supplier credit note",
      "saleAssembly": "Sale assembly",
      "costingSwitch": "Costing method switch"
    },
    "lowStockAlerts": {
      "title": "Low Stock Alerts",
      "columns": {
        "item": "Item",
        "location": "Location",
        "onHand": "On Hand",
        "reorderLevel": "Reorder Level"
      }
    },
    "recentMovements": {
      "title": "Recent Movements",
      "filter": {
        "allTypes": "All types",
        "fromPlaceholder": "From",
        "toPlaceholder": "To"
      },
      "columns": {
        "date": "Date",
        "type": "Type",
        "item": "Item",
        "location": "Location",
        "sourceType": "Source type",
        "source": "Source",
        "qty": "Qty",
        "actions": "Actions"
      },
      "emptyFiltered": "No movements match the current filters.",
      "emptyNoData": "No movements yet. Stock-in from an AP invoice to get started.",
      "packSnapshot": {
        "sourcePack": "Source pack: {value}",
        "conversion": "Snapshot: {value}",
        "baseUnitCost": "Net base cost: {cost}/{baseUom}"
      },
      "correctPackConversion": "Correct pack"
    },
    "howItWorks": {
      "title": "How Inventory Tracking Works",
      "intro": "Track what you buy, where you store it, and what you sell. It all connects to your accounting.",
      "step1Title": "Set up locations",
      "step1Body": "Create warehouses, offices, or retail outlets where you store stock.",
      "step2Title": "Receive from AP invoices",
      "step2Body": "When you review a purchase invoice, click \"Receive to Inventory\" to stock in items at a location.",
      "step3Title": "Track stock levels",
      "step3Body": "See current quantities per product per location, with low-stock alerts.",
      "step4Title": "Auto-deduct on sales",
      "step4Body": "When you issue a sales invoice, stock is automatically deducted from the selected location.",
      "step5Title": "Adjust for discrepancies",
      "step5Body": "Manual adjustments for damaged goods, stocktake corrections, or samples.",
      "movementTypesTitle": "Movement Types",
      "stockInDesc": "Goods received from purchase",
      "stockOutDesc": "Goods sold via sales invoice",
      "adjustmentDesc": "Manual correction (damage, stocktake)",
      "tipsTitle": "Tips",
      "tip1": "Start with one default location. You can add more later.",
      "tip2": "Service items are automatically excluded from inventory tracking.",
      "tip3": "Draft sales invoices don't affect stock. Only issued invoices do.",
      "tip4": "Voiding an invoice automatically reverses the stock deduction."
    },
    "packCorrection": {
      "title": "Correct pack conversion",
      "description": "Replace how this receipt counted the packs it received. The posted quantities are reversed and reposted at the corrected conversion, and the change is recorded in the audit trail.",
      "loading": "Reading the receipt",
      "asPosted": "As posted",
      "correctTo": "Correct to",
      "received": "Received",
      "costPerBaseUnit": "Cost per base unit",
      "packAndBase": "{source} (counted as {base})",
      "optionSummary": "{source} (counted as {base})",
      "optionCost": "{cost} per {baseUom}",
      "optionsLegend": "Supplier pack alternatives",
      "reasonLabel": "Reason",
      "reasonPlaceholder": "For example: the supplier changed the pack size to 30 pieces",
      "reasonHint": "Recorded in the audit trail. At least three characters.",
      "confirm": "Apply correction",
      "cancel": "Cancel",
      "blockedRoute": "Open stock adjustments",
      "errors": {
        "generic": "The correction could not be applied. Refresh and try again.",
        "notFound": "This receipt is not available for correction in this business."
      },
      "blocked": {
        "period_locked": "The accounting period for this receipt is closed, so it cannot be corrected.",
        "downstream_dependency": "Stock has already moved for this item since this receipt, so the conversion cannot be replaced here.",
        "unsupported_dependency": "This receipt has dependencies that could not be verified. Refresh and try again.",
        "not_groot_managed": "Groot does not keep the stock ledger for this business, so pack conversions are corrected in your own system.",
        "no_active_alternative": "No other pack conversion is confirmed for this supplier item yet. Confirm the pack first, then come back.",
        "evidence_unavailable": "The supplier line this receipt came from can no longer be read, so the conversion cannot be corrected here."
      }
    },
    "activity": {
      "heading": "Stock activity",
      "description": "Track stock movements and low-stock alerts across all locations.",
      "figuresLink": "View stock figures"
    },
    "activityHelp": {
      "title": "How stock activity works",
      "intro": "Activity shows recorded stock increases and decreases, and the documents they came from.",
      "figuresTitle": "Looking for stock value or product costs?",
      "figuresBody": "Open {view} for current stock value, inventory in the books and product costs. Its month selector changes only the monthly platform results.",
      "correctionsTitle": "Fix a stock record",
      "packBody": "If a receipt counted the wrong number of units in a pack, choose {action} on that row. Review a confirmed supplier pack size. The dialog checks whether the change is allowed and explains the next step if it is blocked.",
      "quantityTitle": "Change a stock quantity",
      "quantityBody": "When Groot manages your stock, use {action} to record an increase or decrease, for example damaged or missing goods. This adds a new movement and keeps the original history. If another system manages your stock, make the change there.",
      "cancelTitle": "Cancel the original transaction",
      "cancelBody": "Open the original invoice, delivery order or production record and check its available correction or cancellation action. The options depend on that record and any later stock movements.",
      "stockInBody": "Stock added, such as a purchase receipt or a return.",
      "stockOutBody": "Stock removed, such as a delivery or stock used in production.",
      "adjustmentBody": "A recorded increase or decrease to correct the stock quantity."
    }
  },
  "inventoryLocations": {
    "pageTitle": "Inventory Locations",
    "pageSubtitle": "Manage your warehouses, offices, and retail outlets",
    "heading": "Locations",
    "description": "Manage warehouses, offices, and retail outlets where you store inventory.",
    "addLocation": "Add Location",
    "emptyTitle": "No locations yet",
    "emptyDescription": "Create your first location to start tracking inventory.",
    "createFirstLocation": "Create First Location",
    "defaultBadge": "Default",
    "confirm": "Confirm",
    "cancel": "Cancel",
    "editLocation": "Edit location",
    "deactivateLocation": "Deactivate location",
    "reactivateLocation": "Reactivate location",
    "type": {
      "warehouse": "Warehouse",
      "office": "Office",
      "retail": "Retail",
      "other": "Other"
    },
    "status": {
      "active": "active",
      "inactive": "inactive"
    },
    "table": {
      "name": "Name",
      "type": "Type",
      "address": "Address",
      "status": "Status",
      "actions": "Actions"
    },
    "deactivateError": "Location could not be deactivated. Check the location status and try again.",
    "reactivateError": "Location could not be reactivated. Check the location status and try again.",
    "form": {
      "editTitle": "Edit Location",
      "addTitle": "Add Location",
      "nameLabel": "Name *",
      "namePlaceholder": "e.g., HQ, Warehouse A, Johor Branch",
      "addressLabel": "Address",
      "addressPlaceholder": "Physical address (optional)",
      "typeLabel": "Type",
      "defaultLabel": "Default Location",
      "defaultHelp": "Auto-selected when receiving inventory",
      "saveError": "Location could not be saved. Check the details and try again.",
      "saving": "Saving...",
      "update": "Update",
      "create": "Create"
    }
  },
  "salesInvoiceEditor": {
    "correction": {
      "headerTitle": "Correct invoice",
      "title": "Correct posted invoice",
      "intro": "This invoice keeps its number and its journal entry. What you change, and the reason you give, are recorded in its change history.",
      "identityRefresh": {
        "title": "Current business and customer details will be applied",
        "description": "These details changed since this invoice was issued. Saving updates the current document; the earlier values stay in Change history.",
        "mint": "This invoice predates saved seller details. Saving captures the current business details for this version.",
        "business": "Business",
        "customer": "Customer",
        "fieldLabel": "{party}: {field}",
        "notSet": "Not set",
        "yes": "Yes",
        "no": "No"
      },
      "reasonLabel": "Reason for change",
      "reasonPlaceholder": "Explain why this invoice needs correcting",
      "reasonHint": "Finance reviewers see this reason in the audit trail. Between 3 and 500 characters.",
      "reasonTooShort": "Give at least 3 characters so the audit trail explains itself.",
      "noChangesYet": "Nothing has changed yet, so there is nothing to correct.",
      "changedFields": "{count, plural, one {# field will be corrected} other {# fields will be corrected}}",
      "save": "Save correction",
      "saving": "Saving...",
      "cancel": "Cancel",
      "savedTitle": "Correction saved",
      "savedDescription": "The invoice and its change history are up to date.",
      "errorTitle": "Correction not saved",
      "errorGeneric": "The correction could not be saved. Reload the invoice and try again.",
      "locked": {
        "currency": "Currency stays as issued. Changing it would restate the exchange rate this invoice posted at.",
        "inventory": "Stock fulfilment is a stock movement, not a document correction. Use the inventory flow.",
        "saleType": "Cash or credit stays as issued. It decides which accounts this invoice posted to.",
        "invoiceNumber": "The invoice number is fixed once the invoice is issued.",
        "reportingDimensions": "Sales agent, project, department and location are reporting attribution, not document content. Change them from Attribution on the invoice, where no reissue is needed."
      },
      "errors": {
        "lineTotalMismatch": "A line total does not match its quantity, price, discount and tax. Check the lines and try again.",
        "invalidDueDate": "The due date cannot be earlier than the issue date."
      }
    },
    "awaitingCustomerInfo": "Awaiting customer info",
    "taiwanEinvoice": {
      "title": "Taiwan e-Invoice",
      "description": "Issue Taiwan government uniform e-invoices (電子發票) for your sales. Coming soon. Register your interest below."
    },
    "peppol": {
      "description": "Transmit invoices to Singapore recipients via the Peppol network. Be among the first to try it: request early access below."
    },
    "detail": {
      "reopen": {
        "action": "Reopen to edit",
        "actionHint": "Reverse this invoice's postings and return it to a draft you can edit",
        "confirmTitle": "Reopen this invoice for editing?",
        "confirmMessage": "This reverses the invoice's journal entries and returns it to a draft you can edit. You can re-issue it afterwards.",
        "confirmMessagePaid": "This invoice has a recorded payment. Reopening reverses that payment and returns the invoice to a draft, and any bank reconciliation for the payment must be redone. Continue?",
        "confirmAction": "Reopen for editing",
        "confirmCancel": "Cancel",
        "successTitle": "Invoice reopened",
        "successDescription": "Returned to draft. {payments} payment(s) reversed, {bankTransactions} bank transaction(s) unmatched.",
        "failTitle": "Could not reopen invoice",
        "failDescription": "Something went wrong reopening this invoice. Please try again."
      },
      "headerTitle": "Invoice Details",
      "notFound": "Invoice not found.",
      "backToInvoices": "Back to Invoices",
      "defaultCompanyName": "Our Company",
      "adjustmentNoteNotIssuable": "This is a credit note, not an invoice. It is already in the books from the moment it was raised, so there is nothing to issue. Use Void to cancel it.",
      "actions": {
        "back": "Back",
        "pdf": "PDF",
        "downloadEInvoice": "Download E-Invoice (LHDN)",
        "edit": "Edit",
        "send": "Send",
        "resendEmail": "Resend Email",
        "recordPayment": "Record Payment",
        "void": "Void",
        "delete": "Delete",
        "createCreditNote": "Create Credit Note",
        "createDebitNote": "Create Debit Note"
      },
      "toast": {
        "invoiceSentTitle": "Invoice sent",
        "invoicePostedTitle": "Invoice posted",
        "invoicePostedDescription": "Recorded in your books. No email was sent.",
        "emailSentDescription": "Email sent to {email}",
        "emailSentTitle": "Email sent",
        "emailResentDescription": "Invoice email resent to {email}",
        "emailFailedTitle": "Failed to send email",
        "emailFailedDescription": "Please try again later",
        "voidFailedTitle": "Invoice could not be voided",
        "voidFailedDescription": "Review the invoice status and try again.",
        "creditNoteCreatedTitle": "Credit note created",
        "creditNoteCreatedDescription": "Credit note saved as draft",
        "debitNoteCreatedTitle": "Debit note created",
        "debitNoteCreatedDescription": "Debit note saved as draft",
        "deleteFailedTitle": "Delete failed",
        "deleteFailedDescription": "This invoice could not be deleted. Refresh and try again.",
        "emailFailedDeliveryDescription": "The invoice is saved, but we couldn't deliver it to {email}. Our team has been notified, so please don't keep retrying.",
        "emailUnconfirmedDescription": "We couldn't confirm whether {email} received this. Don't resend yet, or they may get it twice. We're checking.",
        "emailBlockedDescription": "An earlier send to {email} is still being checked. We'll finish that first, so nothing is sent twice."
      },
      "lhdnReview": {
        "titleRejected": "LHDN e-Invoice Rejected by Buyer: Review Required",
        "titleCancelled": "LHDN e-Invoice Cancelled by Buyer: Review Required",
        "reason": "Reason: {reason}",
        "defaultMessage": "The buyer has taken action on this e-invoice. Review the journal entry and take corrective action.",
        "rejectedAt": "Rejected at: {date}"
      },
      "voidConfirm": {
        "title": "Are you sure you want to void this invoice?",
        "description": "This will cancel the invoice and remove its journal entries from your books. The invoice stays in your list, marked Void. A credit or debit note is reversed with an opposite entry instead. This action cannot be undone.",
        "voiding": "Voiding...",
        "confirm": "Yes, Void Invoice",
        "cancel": "Cancel"
      },
      "deleteConfirm": {
        "title": "Are you sure you want to delete this draft invoice?",
        "description": "This will permanently delete the invoice. This action cannot be undone.",
        "deleting": "Deleting...",
        "confirm": "Yes, Delete",
        "cancel": "Cancel"
      },
      "summary": {
        "title": "Invoice Details",
        "creditNoteTitle": "Credit note details",
        "debitNoteTitle": "Debit note details",
        "noteDate": "Note date",
        "invoiceDate": "Invoice Date",
        "dueDate": "Due Date",
        "currency": "Currency",
        "taxMode": "Tax Mode",
        "subtotal": "Subtotal",
        "tax": "Tax",
        "total": "Total",
        "paid": "Paid",
        "balanceDue": "Balance Due"
      },
      "cashSaleBadge": "Cash sale",
      "cashSaleReceivedInto": "Cash sale into {account}",
      "voidedReadOnly": "This invoice has been voided. It stays here as a record and can no longer be changed."
    },
    "edit": {
      "onlyDraftEditable": "Only draft invoices can be edited.",
      "viewInvoice": "View Invoice"
    },
    "header": {
      "closeEditor": "Close editor",
      "createTitle": "Create invoice",
      "editTitle": "Edit invoice",
      "saving": "Saving...",
      "draftSavedAt": "Draft saved at {time}",
      "saveFailed": "Not saved",
      "notSavedYet": "Not saved yet",
      "hidePreview": "Hide preview",
      "showPreview": "Show preview",
      "reviewInvoice": "Review invoice"
    },
    "layout": {
      "toast": {
        "emailDeliveryFailedTitle": "Invoice saved but email delivery failed",
        "emailDeliveryFailedDescription": "Could not send email to {email}. You can resend from the invoice details page.",
        "emailDeliveryNetworkError": "A network error occurred while sending the email. You can resend later.",
        "sendFailedTitle": "Failed to send invoice",
        "sendFailedDescription": "An unexpected error occurred. Please try again.",
        "draftSaveFailedTitle": "Couldn't save draft",
        "draftSaveFailedDescription": "Your draft was not saved. Please try again.",
        "invoiceNumberRejected": "This invoice number cannot be used. Try another one.",
        "pdfArchiveFailedTitle": "Invoice saved, PDF copy not filed",
        "pdfArchiveFailedDescription": "The invoice is recorded in your books. We could not file its PDF, so a resend from the invoice list will go out without the PDF attached. Open the invoice and send it again to file a copy.",
        "invoiceNumberReferenceClash": "This number would print the same payment reference as invoice {existing}, so bank transfers could not be told apart. Change the number.",
        "invoiceNumberReferenceUnverified": "We could not yet confirm this number is free of payment reference clashes with older invoices. Use the automatic number, or try again later."
      },
      "negativeStock": {
        "title": "Available stock will go negative",
        "description": "This invoice will leave one or more stock locations below zero. The current policy is Warn, so confirm before sending.",
        "lineFallback": "Invoice line",
        "review": "Review invoice",
        "continue": "Send anyway"
      },
      "sendErrors": {
        "cannotIssueAdjustmentNote": "This is a credit or debit note, not an invoice, so it cannot be issued. A note is already in the books from the moment it is raised. To cancel it, void it instead.",
        "notDraft": "Only a draft invoice can be issued. This one has already been issued or voided. Refresh the page to see its current status.",
        "zeroTotal": "The invoice total must be greater than zero. Check the quantity and price on each line.",
        "taxExceedsTotal": "This invoice's tax is more than its total, so it cannot be posted to the ledger. Check the tax rate and the discount on each line.",
        "unidentifiableCustomer": "This invoice has no customer name and no email address, so it cannot be recorded against a debtor. Add the customer's name, or pick an existing customer, before issuing.",
        "ambiguousCustomerName": "That customer name matches more than one customer on file, and this invoice has no email address to tell them apart. Pick the right customer on the invoice before issuing.",
        "sourceLocationRequired": "Choose a source location for every stock tracked line before issuing this invoice.",
        "sourceLocationInvalid": "The source location on one of the stock tracked lines is no longer active. Pick a current location before issuing.",
        "insufficientStock": "There is not enough available stock for one or more lines, and your inventory policy blocks negative stock. Receive more stock, or reduce the quantity, before issuing.",
        "negativeStockNeedsConfirmation": "Issuing this invoice would take one or more stock locations below zero. Open it in the invoice editor to review the lines and confirm.",
        "customerHeldStockDisabled": "Customer held stock is switched off for this business. Turn it on in Inventory settings before issuing this invoice.",
        "customerHeldStockNeedsTrackedLines": "A customer held stock invoice needs at least one stock tracked line. Add a tracked item, or switch this invoice back to standard fulfilment.",
        "customerHeldFormulaUnsupported": "Customer-held stock can hold finished Stock Items only. This invoice line uses a sales formula that deducts components, so switch to standard fulfilment or sell the finished Stock Item directly.",
        "salesFormulaCustomerHeldComponentBackflushRefused": "Customer-held stock can hold one finished Stock Item per invoice line. This product has a formula with more than one part, so switch to standard fulfilment or give the finished Stock Item its own formula of one part.",
        "salesFormulaRequired": "This invoice line needs a formula before stock can move. Open Products → Formulas, add a formula for this product, then issue again.",
        "invoiceLimitReached": "You have reached this month's sales invoice limit on your current plan. Upgrade in Settings to issue more.",
        "invoiceNumberUnallocatable": "We could not allocate an invoice number, because too many numbers in the sequence are already taken. Check your invoice number settings.",
        "stockReliefDuplicateLink": "This invoice uses a Sales Product with more than one active stock relief link. Open Products and keep one active link to the Stock Item before issuing.",
        "salesFormulaSetupInvalid": "This invoice uses a Sales Product with a sales formula that needs attention. Open Products, fix the formula components, then issue again.",
        "stockReliefQuantityRequired": "One Sales Product has a missing or invalid stock relief quantity. Open Products, edit the relief link, and enter a positive quantity that fits the Stock Item base unit.",
        "stockReliefItemUnavailable": "A Sales Product or linked Stock Item on this invoice is inactive, archived, or unavailable. Open Products and choose active items before issuing.",
        "stockReliefTargetNotStock": "A relief link points to an item that is not set up as Stock. Open Products and enable Stock on the target item, or choose a Stock Item.",
        "stockReliefBaseUnitRequired": "A Stock Item used for relief needs one active base unit before stock can move. Open Products, add or fix the base unit, then issue again.",
        "stockReliefSalesRoleRequired": "An invoice line no longer points to an active Sales Product. Open Products and enable Sales for the item, or replace the line before issuing.",
        "cashSaleAccountNotMoney": "That account can't receive a cash sale. Pick a bank account or the cash till and try again.",
        "assemblyPartLimit": "This sale needs more stock assembled than one invoice can hold. Make part of it ahead of time, or split the sale, then issue again.",
        "stockCostPlanMismatch": "The stock that moved did not cost what was planned, so nothing was posted. Refresh and issue again; if it repeats, review the stock movements for this invoice.",
        "fxRateUnresolved": "There is no exchange rate for this invoice's date, so it cannot be issued yet. Type the rate on the invoice, or add one under Accounting → Chart of Accounts → Currencies & rates.",
        "fxRateInvalid": "The exchange rate must be a positive number.",
        "lineDescriptionRequired": "Line {line} has no description. Describe it, or pick a product from the catalogue, then send again.",
        "accountIsHeading": "This invoice could not be posted because an account it posts to has sub-accounts. If the customer was typed in by hand, add them to the Customer Directory first (or choose them there) and post again. Otherwise check Payment & posting in Chart of Accounts."
      }
    },
    "review": {
      "backToEditing": "Back to editing",
      "title": "Review invoice",
      "sending": "Sending...",
      "sendInvoice": "Send invoice",
      "posting": "Posting...",
      "postInvoice": "Post invoice",
      "postAndSend": "Post and send",
      "noCustomerEmail": "Add a customer email address to send this invoice",
      "summaryTitle": "Invoice Summary",
      "invoicePreview": "Invoice preview",
      "summary": {
        "invoiceNumber": "Invoice number",
        "totalAmount": "Total amount",
        "customer": "Customer",
        "dueDate": "Due date",
        "invoiceDate": "Invoice date",
        "lineItems": "Line items",
        "lineItemsCount": "{count, plural, one {# item} other {# items}}"
      },
      "totals": {
        "subtotal": "Subtotal",
        "discount": "Discount",
        "tax": "Tax",
        "total": "Total"
      },
      "openInEditor": "Open in editor"
    },
    "form": {
      "backToEdit": "Back to Edit",
      "newSalesInvoice": "New Sales Invoice",
      "preview": "Preview",
      "saveDraft": "Save Draft",
      "saving": "Saving...",
      "billTo": "Bill To",
      "lineItems": "Line Items",
      "addLineItem": "Add Line Item",
      "additionalInformation": "Additional Information",
      "notes": "Notes",
      "notesPlaceholder": "Additional notes for the customer...",
      "paymentInstructions": "Payment Instructions",
      "paymentInstructionsPlaceholder": "Bank account details, payment methods...",
      "signatureName": "Signature Name",
      "signatureNamePlaceholder": "e.g. John Smith",
      "invoiceDetails": "Invoice Details",
      "invoiceDate": "Invoice Date",
      "paymentTerms": "Payment Terms",
      "dueDate": "Due Date",
      "currency": "Currency",
      "taxMode": "Tax Mode",
      "taxExclusive": "Tax Exclusive",
      "taxInclusive": "Tax Inclusive",
      "template": "Template",
      "templateModern": "Modern",
      "templateClassic": "Classic",
      "summary": "Summary",
      "subtotal": "Subtotal",
      "discount": "Discount",
      "tax": "Tax",
      "total": "Total",
      "location": {
        "selectPlaceholder": "Select",
        "onlyAvailable": "Only {count} available"
      },
      "table": {
        "itemCode": "Item Code",
        "description": "Description",
        "qty": "Qty",
        "location": "Location",
        "unitPrice": "Unit Price",
        "taxPercent": "Tax %",
        "amount": "Amount",
        "price": "Price",
        "skuPlaceholder": "SKU",
        "descriptionPlaceholder": "Item description"
      },
      "templates": {
        "add": "+ Add",
        "noteLabelPlaceholder": "Label (e.g. Refund policy)",
        "paymentLabelPlaceholder": "Label (e.g. PayPal)",
        "textPlaceholder": "Template text...",
        "cancel": "Cancel",
        "save": "Save"
      }
    },
    "lineItems": {
      "searchSkuPlaceholder": "Search SKU, code or barcode",
      "findOrAddPlaceholder": "Find, scan or add an item",
      "clearCatalogItem": "Clear catalog item",
      "useAsCustomItem": "Or use \"{value}\" as a custom line, with no product",
      "enterCustomItemName": "Enter a custom item name",
      "oneTimeItemHint": "No stock leaves and no cost of goods is recorded for a custom line. If this is stock, pick the product above.",
      "noMatchingItems": "No matching catalog items",
      "billing": {
        "monthly": "Monthly",
        "yearly": "Yearly",
        "oneTime": "One-time"
      },
      "catalogHintPrefix": "Add single, one-time items or products from your",
      "catalogHintLink": "product catalog",
      "catalogHintSuffix": "to this invoice.",
      "untitledItem": "Untitled item",
      "editItem": "Edit item",
      "removeItem": "Remove item",
      "itemDetails": "Item details",
      "itemLabel": "Item",
      "qtyLabel": "Qty",
      "savingToCatalog": "Saving to catalog...",
      "saveToCatalog": "Save to product catalog",
      "saveToCatalogHint": "Add “{name}” as a reusable catalog item",
      "linkedToCatalog": "Linked to product catalog",
      "shipFromLabel": "Ship from",
      "shipFromPlaceholder": "Select location",
      "shipFromAvailable": "{count} available",
      "shipFromInsufficient": "Only {count} available at this location",
      "shipFromNoLocations": "Create an inventory location before sending this stock-tracked product.",
      "shipFromMissing": "Choose a ship-from location before sending.",
      "shipFromSummary": "Ship from {location} · {available} available",
      "formulaComponentsTitle": "This Sales Product deducts formula components:",
      "formulaComponentLine": "{item}: {quantity} {unit} needed · {available} available",
      "descriptionLabel": "Description",
      "descriptionPlaceholder": "Brief description shown on invoice",
      "unitPriceLabel": "Unit price",
      "uomLabel": "UoM",
      "subtotalLabel": "Subtotal",
      "itemCodeLabel": "Item code / SKU (optional)",
      "remove": "Remove",
      "cancel": "Cancel",
      "saveAndAddAnother": "Save and add another",
      "save": "Save",
      "emptyState": "No items yet. Add an item to get started.",
      "addItem": "Add item",
      "taxHintPrefix": "Prices are",
      "taxModeExclusive": "tax-exclusive",
      "taxModeInclusive": "tax-inclusive",
      "taxHintSuffix": ". Tax percentages are entered as whole numbers (e.g. 7 for 7%).",
      "defaultTier": "Default",
      "priceTierBadge": "Price tier: {tier}",
      "catalogDefaultBadge": "Catalog default",
      "manualPriceBadge": "Manual price",
      "priceNeedsReviewBadge": "Review price",
      "overrideReasonSummary": "Override: {reason}",
      "resolvedPrice": "Resolved price: {price}",
      "priceNeedsReviewMessage": "The current effective price for {date} is {price}. Apply it only if this invoice should use the new price.",
      "applyCurrentPrice": "Apply current price",
      "overrideReasonLabel": "Override reason",
      "overrideReasonPlaceholder": "Why is this invoice using a different price?",
      "overrideReasonHelp": "This line differs from the resolved price of {price}. The reason is saved for audit history.",
      "itemRequired": "Enter an item name",
      "qtyRequired": "Enter a quantity above 0",
      "barcodeMatch": "Barcode {code}",
      "searchingCatalog": "Searching products…",
      "searchUnavailable": "Product search is unavailable right now. You can still add a one-time item, or try again in a moment.",
      "noCodeMatch": "No product has the code \"{value}\". This line stays a one-time item.",
      "noCodeMatchIncomplete": "No product found with the code \"{value}\", but Groot could not check every product's barcode aliases. Search by name if you expected a match.",
      "ambiguousCodeMatch": "{count} products use the code \"{value}\". Pick the right one from the list.",
      "browseMoreHint": "Showing the first products only. Type a name, SKU or barcode to search the whole catalog.",
      "narrowSearchHint": "More products match. Keep typing to narrow the list.",
      "shipFromRequired": "Choose a ship-from location",
      "shipFromChooseHint": "Choose where this ships from. Groot only picks for you when your default location has enough stock for this quantity, or when just one location does.",
      "shipFromMissingSummary": "{count, plural, one {One stock line needs a ship-from location.} other {# stock lines need a ship-from location.}} Choose it on each marked line.",
      "promoBadge": "Promo",
      "enterPicksFirst": "Press Enter to pick {name}",
      "catalogueMatchOnTabAway": "This looks like \"{name}\" in your catalogue. Pick it so stock leaves and its cost is recorded, or keep what you typed as a custom line.",
      "deliveryLocked": "These lines are what was delivered, so their quantity, unit and item cannot be changed here. You can still change the price and the wording. To bill another quantity, delete this draft and raise the delivery again."
    },
    "statusIssued": "Issued",
    "needsExchangeRate": "Needs an exchange rate",
    "statusVoid": "Void",
    "statusDraft": "Draft",
    "statusPosted": "Posted",
    "statusPartiallyPaid": "Partially Paid",
    "statusPaid": "Paid",
    "statusOverdue": "Overdue",
    "managerDraft": {
      "notAvailable": "This draft invoice is not available. You can open only draft invoices you created by converting a sales order.",
      "backToOrders": "Back to sales orders",
      "viewOrder": "Back to the sales order",
      "note": "Only an owner or finance admin can post or send this invoice. You can delete this draft, and the sales order goes back to Accepted so it can be converted again.",
      "deleteConfirmDescription": "This permanently deletes the draft. The sales order goes back to Accepted so you can convert it again. This action cannot be undone.",
      "deletedTitle": "Draft invoice deleted",
      "deletedDescription": "The sales order is back to Accepted and can be converted again."
    },
    "customerPo": {
      "label": "Customer PO number",
      "placeholder": "For example PO-01264",
      "hint": "The buyer's own purchase order number. It is printed on the invoice as \"Your PO\" so their accounts payable can match it."
    },
    "billedDeliveries": {
      "label": "Delivery:",
      "released": "(released)"
    }
  },
  "salesInvoicePayment": {
    "bankAccountErrors": {
      "notFound": "That bank account is not in your chart of accounts. Pick one from the list, or add it in Accounting → Chart of Accounts.",
      "inactive": "That bank account is archived. Pick an active one.",
      "wrongType": "That account can't hold money. Pick a bank or cash account.",
      "isHeading": "That account is a heading with sub-accounts. Pick one of its sub-accounts instead.",
      "notApplicableForClearance": "A post-dated cheque or GIRO stays in the clearing account until the bank takes it. Choose the receiving bank when you mark it cleared.",
      "required": "Choose the account this payment uses before recording it.",
      "notAllowed": "That account is not available for this payment method. Choose one from the list."
    },
    "postingAccountErrors": {
      "notConfigured": "Your chart of accounts is missing an account this posting needs. Add or designate it on Accounting → Chart of Accounts, then try again."
    },
    "pageTitle": "Record Payment",
    "back": "Back",
    "backToInvoices": "Back to Invoices",
    "invoiceNotFound": "Invoice not found.",
    "invoiceTotal": "Invoice Total",
    "balanceDue": "Balance Due",
    "recordPaymentTitle": "Record Payment",
    "paymentRecordedTitle": "Payment Recorded",
    "paymentAppliedMessage": "{amount} has been applied to this invoice.",
    "amountLabel": "Amount",
    "recordFullPayment": "Record Full Payment",
    "amountExceedsBalance": "Amount cannot exceed {balance}",
    "amountInvalid": "Enter a valid amount greater than 0",
    "paymentDateLabel": "Payment Date",
    "paymentMethodLabel": "Payment Method",
    "selectMethodPlaceholder": "Select method",
    "methodBankTransfer": "Bank Transfer",
    "methodCash": "Cash",
    "methodCard": "Card",
    "methodCheque": "Cheque",
    "methodChequeCleared": "Cheque / GIRO - cleared",
    "methodPostDatedChequeGiro": "Post-dated cheque / GIRO - pending clearance",
    "methodOther": "Other",
    "instrumentDateLabel": "Instrument Date",
    "expectedClearanceDateLabel": "Expected Clearance Date",
    "referenceNotesLabel": "Reference / Notes",
    "referencePlaceholder": "e.g. Transaction ID, cheque number",
    "recordPaymentButton": "Record Payment",
    "recording": "Recording...",
    "cancel": "Cancel",
    "recordPaymentError": "Failed to record payment",
    "loyalty": {
      "title": "Loyalty points",
      "currencyMismatch": "Invoice currency does not match the loyalty points currency.",
      "suggestedAward": "Suggested award: {points} points",
      "finalPoints": "Final points",
      "overrideReason": "Override reason",
      "overrideReasonPlaceholder": "Why should this invoice award a different number of points?",
      "previewReason": {
        "not_fully_paid": "Points are awarded only when the invoice becomes fully paid.",
        "settings_disabled": "Loyalty points are disabled for this business.",
        "already_awarded": "Points have already been awarded for this invoice.",
        "not_available": "No loyalty points will be awarded for this payment.",
        "feature_unavailable": "Loyalty points are not enabled for this business."
      }
    },
    "allocate": {
      "serverErrors": {
        "tooManyAllocations": "That is too many invoices for one receipt. Split it into smaller receipts.",
        "duplicateAllocation": "The same invoice was selected twice. Refresh and try again.",
        "openingRequestInvalid": "This carried-forward receipt could not be identified safely. Refresh and try again.",
        "openingRequestConflict": "This receipt request was already used with different details. Refresh and try again.",
        "duplicateOpeningItem": "The same carried-forward invoice was selected twice. Refresh and try again.",
        "invoiceLedgerBasisMissing": "A selected invoice has no posted receivable balance that can be cleared safely. Refresh the invoice and contact support if it remains unavailable.",
        "invoiceLedgerBasisMismatch": "A selected invoice does not match its posted receivable balance. Refresh the invoice and contact support before recording this receipt.",
        "invoiceLedgerLineCap": "A selected invoice has too many journal lines to verify its receivable balance safely. Contact support before recording this receipt.",
        "openingItemAlreadySettled": "A carried-forward invoice was already settled. Refresh before recording this receipt.",
        "openingItemContra": "This carried-forward item is a customer credit, so it cannot be collected as a receipt."
      },
      "pageTitle": "Record customer receipt",
      "unknownCustomer": "Customer",
      "openBalanceLabel": "Open balance ({currency})",
      "openInvoiceCount": "Open invoices: {count}",
      "customerUnavailable": "This customer's invoices are not available to you. Ask an owner or finance admin to record the receipt.",
      "backToCustomer": "Back to customer",
      "receiptAmountLabel": "Receipt amount",
      "receiptAmountHelp": "The total the customer sent, before you decide which invoices it settles.",
      "currencyLabel": "Receipt currency",
      "currencyHelp": "One receipt settles invoices in a single currency. Record a separate receipt for each currency.",
      "tableTitle": "Allocate to invoices",
      "tableHelp": "Tick an invoice to settle it in full, or type a part amount.",
      "autoAllocate": "Allocate oldest first",
      "noOpenInvoices": "This customer has no open invoices in this currency.",
      "colInvoice": "Invoice",
      "colBalance": "Balance due",
      "colAllocate": "Allocate",
      "selectInvoiceAria": "Allocate the full balance of invoice {invoice}",
      "allocateToAria": "Amount allocated to invoice {invoice}",
      "dueOn": "Due {date}",
      "overdue": "Overdue",
      "otherCurrenciesNote": "{count} more open invoices are in other currencies ({currencies}). Switch the receipt currency to allocate them.",
      "summaryReceipt": "Receipt",
      "summaryAllocated": "Allocated",
      "summaryUnallocated": "Unallocated",
      "overpaymentExplainer": "This receipt is larger than everything the customer still owes ({balance}). Groot cannot hold the difference as a credit yet, so record what the invoices cover and handle the rest separately.",
      "matchReceiptToAllocated": "Set the receipt to {amount}",
      "matchReceiptWarning": "{amount} will not be recorded anywhere.",
      "appliedToManyMessage": "{amount} has been applied across {count} invoices.",
      "loyaltyAutoNote": "This receipt settles {count} invoices. Loyalty points are awarded automatically for each one at the suggested rate.",
      "errors": {
        "amountNotPositive": "Enter the amount the customer sent.",
        "nothingAllocated": "Choose at least one invoice this receipt settles.",
        "underAllocated": "{amount} of this receipt is not allocated to any invoice.",
        "overAllocated": "You have allocated {amount} more than the receipt.",
        "rowNotPositive": "The amount for invoice {invoice} must be greater than zero.",
        "exceedsBalance": "Invoice {invoice} only has {balance} outstanding.",
        "currencyMismatch": "Invoice {invoice} is in {currency}. Change the receipt currency or leave it out.",
        "notPayable": "Invoice {invoice} cannot take a payment yet.",
        "unknownInvoice": "One of the allocations points at an invoice that is no longer open. Reload the page."
      }
    },
    "verifiedOrLabel": "Issue an Official Receipt with verified payment evidence",
    "evidenceDepositLabel": "Imported bank deposit",
    "evidencePlaceholder": "Choose the matching statement line",
    "evidenceUnavailable": "Choose a linked, active bank account before selecting statement evidence.",
    "evidenceEmpty": "No matching imported deposit is available. Import the statement before choosing verified issuance.",
    "evidencePrevious": "Previous",
    "evidenceMore": "More deposits",
    "fx": {
      "homeAmountLabel": "Amount received in {currency}",
      "homeAmountHelp": "The amount that reached your bank, before any fees. It sets the exchange rate and the gain or loss.",
      "estimatedBadge": "Estimated",
      "estimatedBnm": "Estimated at the Bank Negara buying rate for the payment date. Type the amount on your bank statement to replace it.",
      "estimatedManual": "Estimated at your saved rate for the payment date. Type the amount on your bank statement to replace it.",
      "useEstimate": "Use the estimate",
      "rateLine": "1 {currency} = {rate} {home}",
      "carriedLine": "The books carry {amount} for what this receipt settles.",
      "gain": "{amount} realised gain",
      "loss": "{amount} realised loss",
      "none": "No exchange difference",
      "foreignBankNote": "This account is in {currency}, so nothing is converted at the bank. The difference against the books is still recognised.",
      "errors": {
        "rateUnresolvedNoAddon": "There is no exchange rate for this payment date. Type the amount your bank received.",
        "rateUnresolved": "There is no exchange rate for this payment date. Type the amount your bank received, or add a rate under Accounting → Chart of Accounts → Currencies & rates.",
        "homeAmountInvalid": "Enter the amount your bank received as a positive amount with at most two decimals.",
        "homeAmountNotApplicable": "An amount in your home currency does not apply to this receipt. Clear that field and try again.",
        "bankCurrencyMismatch": "The selected bank account is in a different currency from this receipt. Choose a home-currency account or one in the invoice currency.",
        "allocationExceedsBalance": "An amount is higher than what is still owed on its invoice. Reduce it to the balance and try again.",
        "generic": "We could not work out the exchange difference for this receipt. Check the amounts and the bank account, then try again.",
        "convertedRouteUnsupported": "A post-dated cheque cannot be recorded against an invoice in a foreign currency yet, because its exchange difference is only known when it clears. Record the receipt once the cheque has cleared.",
        "convertedOpeningItems": "A receipt that also settles carried-forward items cannot be priced against an invoice in a foreign currency. Record the receipt for this invoice on its own, without the carried-forward items.",
        "convertedNotPriceable": "A receipt cannot be recorded against this foreign-currency invoice, because a credit note, debit note or refund on it cannot be priced against its converted amount. Contact support, or ask your accountant to record the receipt as a journal entry.",
        "convertedUnpricedNoAddon": "This receipt cannot be priced against its foreign-currency invoice, usually because there is no exchange rate for the payment date. Record the receipt from Receive payment with the amount your bank received.",
        "convertedUnpriced": "This receipt cannot be priced against its foreign-currency invoice, usually because there is no exchange rate for the payment date. Add one under Accounting → Chart of Accounts → Currencies & rates, or record the receipt from Receive payment with the amount your bank received."
      },
      "history": {
        "received": "Received {cash} at {rate}",
        "carried": "Books carried {cleared}"
      }
    }
  },
  "salesInvoiceCatalog": {
    "page": {
      "title": "Product Catalog",
      "subtitle": "Manage your products and services"
    },
    "detailPage": {
      "title": "Catalog Item",
      "subtitle": "Price history and margin analysis"
    },
    "status": {
      "active": "Active",
      "inactive": "Inactive"
    },
    "billing": {
      "monthly": "Monthly",
      "yearly": "Yearly",
      "weekly": "Weekly",
      "daily": "Daily",
      "oneTime": "One-time",
      "abbr": {
        "month": "mo",
        "year": "yr",
        "week": "wk",
        "day": "day"
      }
    },
    "actions": {
      "edit": "Edit",
      "deactivate": "Deactivate",
      "reactivate": "Reactivate",
      "restoreFromStripe": "Restore from Stripe"
    },
    "sync": {
      "failedTitle": "Sync Failed",
      "errors": {
        "alreadyRunning": "A sync is already running for this business. Wait for it to finish, then try again.",
        "notConnected": "Stripe is no longer connected. Reconnect it in Settings, then sync again.",
        "stripeUnreachable": "We couldn't reach Stripe just now, so nothing was changed. Please try again in a moment.",
        "generic": "We couldn't sync your Stripe catalog. Nothing was changed. Please try again in a moment."
      }
    },
    "stock": {
      "loading": "Loading...",
      "byLocation": "Stock by Location",
      "noStockData": "No stock data",
      "low": "Low",
      "recentMovements": "Recent Movements",
      "noMovements": "No movements yet"
    },
    "table": {
      "name": "Name",
      "sku": "SKU",
      "glCode": "GL Code",
      "price": "Price",
      "taxRate": "Tax Rate",
      "stock": "Stock",
      "status": "Status",
      "actions": "Actions"
    },
    "list": {
      "searchPlaceholder": "Search items by name, SKU, or description...",
      "addItem": "Add Item",
      "sourceLabel": "Source:",
      "sourceAll": "All",
      "sourceManual": "Manual",
      "loading": "Loading catalog items...",
      "priceVariants": "{count} price {count, plural, one {variant} other {variants}}",
      "pricesCount": "{count} prices",
      "syncedAt": "Synced: {date}",
      "empty": {
        "noResultsTitle": "No items found",
        "noItemsTitle": "No catalog items yet",
        "noResultsDescription": "Try adjusting your search terms.",
        "noItemsDescription": "Start by adding your first catalog item."
      }
    },
    "form": {
      "title": {
        "create": "Add Catalog Item",
        "edit": "Edit Catalog Item"
      },
      "fields": {
        "name": {
          "label": "Name",
          "placeholder": "e.g. Consulting Services"
        },
        "description": {
          "label": "Description",
          "placeholder": "Brief description of the item"
        },
        "sku": {
          "label": "SKU",
          "placeholder": "e.g. SVC-001"
        },
        "glCode": {
          "label": "GL Account Code",
          "placeholder": "e.g. 4100",
          "help": "Revenue account code for accounting export (IFRS 4xxx)"
        },
        "category": {
          "label": "Category",
          "placeholder": "e.g. SVC, HW, SW",
          "help": "Product category code for stock item grouping in accounting export"
        },
        "reorderLevel": {
          "label": "Reorder Level",
          "placeholder": "e.g. 10",
          "help": "Low stock alert threshold (inventory tracking)"
        },
        "trackInventory": {
          "label": "Track inventory",
          "help": "Enable stock tracking for this item. Stock quantities are managed from Inventory by location."
        },
        "unitPrice": {
          "label": "Unit Price"
        },
        "currency": {
          "label": "Currency",
          "placeholder": "Select currency"
        },
        "unitMeasurement": {
          "label": "Unit of Measurement",
          "placeholder": "e.g. hours, pcs, kg"
        },
        "taxRate": {
          "label": "Tax Rate (%)",
          "placeholder": "e.g. 7"
        }
      },
      "validation": {
        "nameRequired": "Item name is required",
        "unitPriceRequired": "Unit price is required",
        "priceNonNegative": "Price must be non-negative",
        "currencyRequired": "Currency is required",
        "taxRateNumber": "Tax rate must be a number",
        "taxRateRange": "Tax rate must be between 0 and 100"
      },
      "actions": {
        "addItem": "Add Item",
        "saveChanges": "Save Changes",
        "cancel": "Cancel"
      }
    },
    "detail": {
      "notFound": "Catalog item not found",
      "backToCatalog": "Back to Catalog",
      "tabs": {
        "sales": "Sales History",
        "purchase": "Purchase History",
        "comparison": "Price Comparison",
        "overview": "Overview"
      },
      "meta": {
        "sku": "SKU: {sku}",
        "category": "Category: {category}",
        "currentPrice": "Current Price: {price}"
      },
      "overview": {
        "heading": "Item Details",
        "name": "Name",
        "description": "Description",
        "sku": "SKU",
        "unitPrice": "Unit Price",
        "taxRate": "Tax Rate",
        "category": "Category",
        "glCode": "GL Code",
        "source": "Source",
        "sourceManual": "Manual"
      }
    },
    "errors": {
      "staleRoleVersion": "This product changed while you were reviewing it. Refresh the list and try again.",
      "reactivateFailed": "The product could not be reactivated. Refresh the list, check its Product and Stock setup, then try again."
    }
  },
  "salesInvoiceCustomers": {
    "pageTitle": "Customer Directory",
    "pageSubtitle": "Manage your customer contacts",
    "searchPlaceholder": "Search customers by name, email, or phone...",
    "addCustomer": "Add Customer",
    "loadingCustomers": "Loading customers...",
    "statusActive": "Active",
    "statusInactive": "Inactive",
    "emptyNoResultsTitle": "No customers found",
    "emptyNoCustomersTitle": "No customers yet",
    "emptyNoResultsDescription": "Try adjusting your search terms.",
    "emptyNoCustomersDescription": "Start by adding your first customer.",
    "columnBusinessName": "Business Name",
    "columnContactPerson": "Contact Person",
    "columnEmail": "Email",
    "columnPhone": "Phone",
    "columnStatus": "Status",
    "columnActions": "Actions",
    "actionEdit": "Edit",
    "actionDeactivate": "Deactivate",
    "actionReactivate": "Reactivate",
    "formTitleCreate": "Add Customer",
    "formTitleEdit": "Edit Customer",
    "labelBusinessName": "Business Name",
    "placeholderBusinessName": "e.g. Acme Pte Ltd",
    "labelContactPerson": "Contact Person",
    "placeholderContactPerson": "e.g. John Doe",
    "labelEmail": "Email",
    "placeholderEmail": "customer@example.com",
    "labelPhone": "Phone",
    "sectionTaxRegistration": "Tax & Registration",
    "labelTin": "TIN (Tax Identification Number)",
    "labelBrn": "Business Registration Number (BRN)",
    "placeholderBrn": "e.g. 202001234567",
    "labelSstRegistration": "SST Registration",
    "placeholderSstRegistration": "e.g. B10-1234-56789012",
    "labelPeppolParticipantId": "Peppol Participant ID",
    "sectionAddress": "Address",
    "labelAddressLine1": "Address Line 1",
    "placeholderAddressLine1": "Street address",
    "labelAddressLine2": "Address Line 2",
    "placeholderAddressLine2": "Unit, building, floor",
    "labelAddressLine3": "Address Line 3",
    "placeholderAddressLine3": "Additional address info",
    "labelCity": "City",
    "placeholderCity": "e.g. Kuala Lumpur",
    "labelPostalCode": "Postal Code",
    "placeholderPostalCode": "e.g. 50000",
    "labelState": "State",
    "selectStatePlaceholder": "Select state...",
    "placeholderStateProvince": "State / Province",
    "labelCountry": "Region",
    "submitCreate": "Add Customer",
    "submitSave": "Save Changes",
    "cancel": "Cancel",
    "errorBusinessNameRequired": "Business name is required",
    "errorEmailRequired": "Email is required",
    "errorEmailInvalid": "Please enter a valid email address",
    "errorTinInvalid": "TIN must start with IG (individual) or C, CS, D, F, FA, PT, TA, TC, TN, TR, TP, J or LE, followed by digits, 14 characters at most (e.g. C21638015020)",
    "masterSearchPlaceholder": "Search customers by name or code...",
    "filterAllStatuses": "All Statuses",
    "masterEmptyHint": "Customers appear here after they're imported or created.",
    "columnCustomerCode": "Customer Code",
    "columnPaymentTerms": "Payment Terms",
    "columnOutstanding": "Outstanding",
    "columnTin": "TIN",
    "columnBrn": "BRN",
    "columnCreditLimit": "Credit Limit",
    "columnCurrency": "Currency",
    "masterTotalCount": "{count} customer{count, plural, one {} other {s}} total",
    "masterFilteredCount": "Showing {shown} of {total} customers",
    "errorTaxIdInvalid": "Check the format: it should look like {example}",
    "columnSalesAgent": "Sales agent",
    "filterAllAgents": "All sales agents",
    "salesAgentUnassigned": "Unassigned",
    "salesAgentRetired": "retired",
    "salesAgentUnknown": "Unknown agent",
    "selectAllShown": "Select all customers shown",
    "selectRow": "Select {name}",
    "assign": {
      "action": "Assign sales agent",
      "title": "Assign sales agent",
      "description": "Choose the sales agent for the selected customers ({count}).",
      "hint": "Choose Unassigned to remove the sales agent from these customers.",
      "cancel": "Cancel",
      "confirm": "Assign",
      "confirmRemove": "Remove sales agent",
      "toastAssigned": "Assigned {agent}. Customers updated: {count}.",
      "toastRemoved": "Removed the sales agent. Customers updated: {count}.",
      "toastUnchanged": "Those customers already had this setting. Nothing was changed.",
      "toastPartial": "Updated {done} of {total} selected customers. The rest were not changed. {reason}",
      "toastNone": "No customers were changed. {reason}",
      "refusal": {
        "AGENT_NOT_AVAILABLE": "That sales agent is not available. Pick a current one.",
        "AGENT_RETIRED": "That sales agent is no longer active. Pick a current one.",
        "CUSTOMER_NOT_AVAILABLE": "One of the selected customers is no longer available. Refresh the list and try again.",
        "NOT_ALLOWED": "Only an owner or finance admin can assign sales agents.",
        "FAILED": "Something went wrong. Please try again."
      }
    }
  },
  "salesInvoiceRecurring": {
    "page": {
      "title": "Recurring Invoices",
      "subtitle": "Manage automated invoice schedules"
    },
    "status": {
      "active": "Active",
      "paused": "Paused"
    },
    "frequency": {
      "weekly": "Weekly",
      "monthly": "Monthly",
      "quarterly": "Quarterly",
      "yearly": "Yearly"
    },
    "daysOfWeek": {
      "monday": "Monday",
      "tuesday": "Tuesday",
      "wednesday": "Wednesday",
      "thursday": "Thursday",
      "friday": "Friday",
      "saturday": "Saturday",
      "sunday": "Sunday"
    },
    "confirm": {
      "delete": "Are you sure you want to delete this recurring schedule?"
    },
    "list": {
      "heading": "Recurring Schedules",
      "noneConfigured": "No schedules configured",
      "count": "{count, plural, one {# schedule} other {# schedules}}",
      "newSchedule": "New Schedule"
    },
    "empty": {
      "title": "No recurring schedules yet",
      "description": "Set up recurring invoice schedules to automatically generate invoices for your regular customers on a weekly, monthly, quarterly, or yearly basis.",
      "createFirst": "Create Your First Schedule"
    },
    "table": {
      "customer": "Customer",
      "sourceInvoice": "Source invoice",
      "frequency": "Frequency",
      "nextDue": "Next Due",
      "generated": "Generated",
      "status": "Status",
      "actions": "Actions",
      "provenance": "Traceability",
      "provenanceExpand": "Show source invoice and generated invoices",
      "provenanceCollapse": "Hide source invoice and generated invoices"
    },
    "provenance": {
      "readError": "Could not read this schedule's details. It may have been deleted, or it belongs to another business.",
      "sourceInvoiceUnavailable": "Source invoice no longer available",
      "generatedNone": "No invoices generated yet",
      "inactiveReason": "This schedule stopped because its source invoice is no longer available. Invoices it already generated are unchanged."
    },
    "invoiceProvenance": {
      "heading": "From a recurring schedule",
      "viewSchedule": "View schedule"
    },
    "actions": {
      "edit": "Edit",
      "pause": "Pause",
      "resume": "Resume",
      "delete": "Delete"
    },
    "form": {
      "titleCreate": "Create Recurring Schedule",
      "titleEdit": "Edit Recurring Schedule",
      "cancel": "Cancel",
      "submitCreate": "Create Schedule",
      "submitSave": "Save Changes",
      "customerSection": "Customer",
      "customerNameLabel": "Customer Name *",
      "customerNamePlaceholder": "Business name",
      "emailLabel": "Email *",
      "sourceInvoiceSection": "Source Invoice",
      "sourceInvoiceLabel": "Repeat invoice *",
      "sourceInvoicePlaceholder": "Choose an invoice to repeat",
      "sourceInvoiceHelper": "Each generated invoice is a copy of this one, including its customer and line items.",
      "sourceInvoiceLockedHelper": "The source invoice of a schedule cannot be changed after creation.",
      "sourceInvoiceEmpty": "This business has no invoices to repeat yet. Issue an invoice first, then come back.",
      "sourceInvoiceLoading": "Loading invoices...",
      "invoiceDateLabel": "Invoice date"
    },
    "lineItems": {
      "title": "Template Line Items",
      "addItem": "Add Item",
      "description": "Description",
      "qty": "Qty",
      "unitPrice": "Unit Price",
      "taxPercent": "Tax %",
      "amount": "Amount",
      "price": "Price",
      "descriptionPlaceholder": "Item description",
      "estimatedTotal": "Estimated Total per Invoice"
    },
    "additional": {
      "title": "Additional Information",
      "notesLabel": "Notes",
      "notesPlaceholder": "Notes to include on each generated invoice...",
      "paymentInstructionsLabel": "Payment Instructions",
      "paymentInstructionsPlaceholder": "Bank account details, payment methods..."
    },
    "schedule": {
      "title": "Schedule",
      "frequencyLabel": "Frequency",
      "dayOfMonthLabel": "Day of Month",
      "dayOfMonthHelper": "Invoice generated on this day each period",
      "dayOfWeekLabel": "Day of Week",
      "startDateLabel": "Start Date *",
      "endDateLabel": "End Date (optional)",
      "endDateHelper": "Leave blank for indefinite recurrence",
      "nextGenerationHelper": "First invoice generates on this date"
    },
    "defaults": {
      "title": "Invoice Defaults",
      "currencyLabel": "Currency",
      "taxModeLabel": "Tax Mode",
      "taxExclusive": "Tax Exclusive",
      "taxInclusive": "Tax Inclusive",
      "paymentTermsLabel": "Payment Terms"
    },
    "validation": {
      "customerNameRequired": "Customer name is required",
      "customerEmailRequired": "Customer email is required",
      "startDateRequired": "Start date is required",
      "endDateAfterStart": "End date must be after start date",
      "lineItemRequired": "At least one valid line item is required",
      "sourceInvoiceRequired": "Choose the invoice this schedule should repeat"
    },
    "errors": {
      "title": "Schedule change failed",
      "generic": "We could not save the recurring schedule. Please try again."
    }
  },
  "salesInvoiceSettings": {
    "page": {
      "title": "Invoice Settings",
      "subtitle": "Configure invoice defaults and numbering"
    },
    "header": {
      "backToSalesInvoices": "Back to Sales Invoices",
      "title": "Invoice Configuration",
      "subtitle": "Set default values for new sales invoices",
      "saving": "Saving...",
      "saved": "Saved",
      "saveSettings": "Save Settings"
    },
    "numbering": {
      "title": "Invoice Numbering",
      "prefixLabel": "Invoice Prefix",
      "prefixHelp": "Prefix used in invoice numbers (e.g., INV, SI, SALE)",
      "nextNumberLabel": "Next Invoice Number",
      "nextNumberHelp": "Sequence number for the next invoice",
      "formatLabel": "Number Format",
      "formatOptions": {
        "prefix_year_seq": "Year only ({prefix}26001)",
        "prefix_year_month_seq": "Year and month ({prefix}2608001)",
        "custom": "Custom"
      },
      "formatHelp": {
        "prefix_year_seq": "Restarts at 001 each January.",
        "prefix_year_month_seq": "Restarts at 001 each month.",
        "custom": "Pick a shape below."
      },
      "custom": {
        "formatColumn": "Format",
        "sampleColumn": "Sample",
        "monthNote": "Including the month restarts the count at 001 each month instead of each year."
      },
      "tooLongTitle": "That number would be too long",
      "tooLongHelp": "An invoice number must stay under {max} characters, including the CN- prefix on a credit note. Shorten the prefix or drop a segment.",
      "aboutFormat": "About invoice numbering",
      "formatTooltipProspective": "Only new invoices use this. Existing ones keep their numbers.",
      "formatTooltipIssuance": "The date in the number is the day you issue it, so backdating an invoice does not renumber it."
    },
    "defaults": {
      "title": "Default Values",
      "currencyLabel": "Default Currency",
      "paymentTermsLabel": "Payment Terms",
      "taxModeLabel": "Tax Mode",
      "taxExclusive": "Tax Exclusive",
      "taxInclusive": "Tax Inclusive",
      "templateLabel": "Default Template",
      "templateModern": "Modern",
      "templateClassic": "Classic",
      "templateHelp": "Default template applied to new invoices"
    },
    "loyalty": {
      "title": "Loyalty point suggestions",
      "description": "Set the business-level formula used to suggest points when a sales invoice becomes fully paid.",
      "enabledLabel": "Enable loyalty points",
      "enabledHelp": "When disabled, customer balances and history remain visible but new point changes are blocked.",
      "amountPerPointLabel": "Amount per point",
      "pointsPerAmountLabel": "Points per amount",
      "currencyLabel": "Currency",
      "preview": "{amount} {currency} = {points} point(s)",
      "previewHelp": "This is only the suggested award. Finance users can override the final points while recording payment.",
      "saveButton": "Save formula",
      "saved": "Loyalty formula saved",
      "saveFailed": "Failed to save loyalty formula",
      "historyTitle": "Formula history",
      "errors": {
        "amountPerPoint": "Amount per point must be greater than 0",
        "pointsPerAmount": "Points per amount must be greater than 0"
      }
    },
    "paymentMethods": {
      "title": "Accepted Payment Methods",
      "description": "Enable the payment methods your business accepts. Add account details and QR codes, which will be shown on invoices.",
      "emptyState": "No payment methods enabled, so invoices will not show payment details.",
      "detailsLabel": "Payment Details",
      "detailsHelp": "Shown on the invoice under this payment method",
      "qrCodeLabel": "QR Code",
      "qrCodeAlt": "{method} QR Code",
      "qrUploaded": "QR code uploaded",
      "qrRemove": "Remove",
      "qrUploading": "Uploading...",
      "qrUploadButton": "Upload QR Code",
      "qrUploadHelp": "PNG or JPG, max 2MB. Will be displayed on the invoice.",
      "methods": {
        "bank_transfer": {
          "label": "Bank Transfer",
          "placeholder": "Bank: DBS Bank\nAccount Name: Company Pte Ltd\nAccount Number: 123-456789-0\nSwift: DBSSSGSG"
        },
        "credit_card": {
          "label": "Credit Card",
          "placeholder": "Visa, Mastercard accepted"
        },
        "paynow": {
          "label": "PayNow (SG)",
          "placeholder": "PayNow UEN: 202012345A"
        },
        "duitnow": {
          "label": "DuitNow (MY)",
          "placeholder": "DuitNow ID: 123456789012"
        },
        "promptpay": {
          "label": "PromptPay (TH)",
          "placeholder": "PromptPay ID: 0812345678"
        },
        "gcash": {
          "label": "GCash (PH)",
          "placeholder": "GCash Number: 0917 123 4567"
        },
        "grabpay": {
          "label": "GrabPay",
          "placeholder": "GrabPay Number: +65 9123 4567"
        },
        "paypal": {
          "label": "PayPal",
          "placeholder": "PayPal: payments@company.com"
        },
        "cheque": {
          "label": "Cheque",
          "placeholder": "Payable to: Company Name"
        },
        "cash": {
          "label": "Cash",
          "placeholder": "Cash payment accepted"
        }
      },
      "qrPaysTo": "Pays to: {label}",
      "qrUnverified": "Could not verify who this QR pays. Check it before you send invoices.",
      "errorDuplicate": "Each payment method can be listed only once. Remove the repeated method and save again.",
      "errorQrUnverified": "This DuitNow QR could not be read, so it was not saved. Upload it again and choose Use anyway if you want to keep it."
    },
    "email": {
      "title": "Email Settings",
      "bccLabel": "Send me a copy of outgoing invoice emails",
      "bccHelpWithEmail": "A BCC copy will be sent to {email}",
      "bccHelpNoEmail": "Set a contact email in your business profile to receive copies",
      "debtorQrLabel": "Show debtor self-service QR code on invoices",
      "debtorQrHelp": "Debtors can scan the QR code to update their business details for e-invoice compliance"
    },
    "einvoice": {
      "title": "LHDN e-Invoice",
      "description": "Configure how validated e-invoices are delivered to buyers.",
      "autoDeliveryLabel": "Auto-deliver validated e-invoices to buyers",
      "autoDeliveryHelp": "Automatically send the LHDN-validated PDF to the buyer's email when an e-invoice is validated.",
      "buyerNotificationsLabel": "Send buyer notification emails",
      "buyerNotificationsHelp": "Notify buyers by email when e-invoices are validated, cancelled, or when rejection requests are confirmed."
    },
    "customerFields": {
      "title": "Customer Fields on Invoice",
      "description": "Choose which customer details appear on generated invoices. Business name is always shown.",
      "fields": {
        "contactPerson": "Contact Person",
        "email": "Email",
        "phone": "Phone",
        "address": "Address",
        "tin": "TIN (Tax Identification No)",
        "brn": "BRN (Business Registration No)",
        "sstRegistration": "SST Registration No",
        "gstRegistration": "GST Registration No",
        "idType": "ID Type"
      }
    },
    "defaultText": {
      "title": "Default Text",
      "paymentInstructionsLabel": "Payment Instructions",
      "paymentInstructionsPlaceholder": "Bank account details, payment methods, QR codes...",
      "paymentInstructionsHelp": "Automatically added to every new invoice",
      "notesLabel": "Default Notes",
      "notesPlaceholder": "Thank you for your business! Terms and conditions apply...",
      "notesHelp": "Default notes section for new invoices"
    },
    "preview": {
      "title": "Live Preview",
      "nextInvoiceNumber": "Next Invoice Number",
      "previewSequence": "Preview Sequence",
      "resetYearly": "The sequence restarts at 001 on 1 January.",
      "resetMonthly": "The sequence restarts at 001 on the first day of each month.",
      "formatShape": "Format: {shape}"
    },
    "summary": {
      "title": "Current Defaults",
      "currency": "Currency",
      "paymentTerms": "Payment Terms",
      "taxMode": "Tax Mode",
      "template": "Template",
      "hasInstructions": "Has Instructions",
      "hasNotes": "Has Notes",
      "paymentMethods": "Payment Methods",
      "bccEmails": "BCC Emails",
      "yes": "Yes",
      "no": "No",
      "on": "On",
      "off": "Off"
    },
    "toast": {
      "invalidFileType": {
        "title": "Invalid file type",
        "description": "Please upload an image file (PNG, JPG, etc.)"
      },
      "fileTooLarge": {
        "title": "File too large",
        "description": "QR code image must be under 2MB"
      },
      "qrUploaded": {
        "title": "QR code uploaded"
      },
      "qrUploadFailed": {
        "title": "Failed to upload QR code"
      },
      "settingsSaved": {
        "title": "Invoice settings saved"
      },
      "saveFailed": {
        "title": "Failed to save settings",
        "descriptionFallback": "Please try again."
      },
      "qrUnverified": {
        "title": "QR uploaded but not verified",
        "description": "We could not check who it pays. It will print on your invoices as it is."
      },
      "qrInvalid": {
        "title": "This is not a valid payment QR",
        "description": "The QR is damaged or is not a DuitNow or bank payment QR. Download it again from your banking app."
      }
    },
    "qrConfirm": {
      "title": "Confirm who this QR pays",
      "message": "This QR pays to: {label}. Is this your business?",
      "confirm": "Yes, use this QR",
      "cancel": "Cancel"
    },
    "qrUnreadable": {
      "title": "We could not read this QR",
      "message": "We could not read this as a DuitNow QR. Use it anyway? It will print on your invoices as it is, and we cannot check who it pays.",
      "confirm": "Use anyway",
      "cancel": "Choose another image"
    }
  },
  "salesInvoiceLists": {
    "header": {
      "title": "Sales Invoices",
      "totalCount": "{count, plural, one {# invoice total} other {# invoices total}}",
      "invoiceSettings": "Invoice Settings",
      "newInvoice": "New Invoice",
      "newCashSale": "Cash Sale"
    },
    "summary": {
      "draft": "Draft",
      "sent": "Posted",
      "overdue": "Overdue",
      "paid": "Paid",
      "outstanding": "Outstanding"
    },
    "tabs": {
      "all": "All",
      "draft": "Draft",
      "sent": "Posted",
      "overdue": "Overdue",
      "paid": "Paid",
      "void": "Void"
    },
    "batch": {
      "selectedCount": "{count, plural, one {# invoice selected} other {# invoices selected}}",
      "clear": "Clear",
      "submitToLhdn": "Submit to LHDN"
    },
    "table": {
      "selectAllEligible": "Select all eligible invoices",
      "invoiceNumber": "Invoice #",
      "customer": "Customer",
      "date": "Date",
      "dueDate": "Due Date",
      "amount": "Amount",
      "status": "Status",
      "eInvoice": "e-Invoice",
      "delivery": "Delivery",
      "actions": "Actions"
    },
    "badge": {
      "reviewRequired": "Review Required"
    },
    "delivery": {
      "delivered": "Delivered",
      "failed": "Failed",
      "pending": "Pending"
    },
    "actions": {
      "view": "View",
      "edit": "Edit",
      "send": "Send",
      "recordPayment": "Record Payment",
      "pay": "Pay",
      "void": "Void",
      "delete": "Delete",
      "deleteDraft": "Delete draft"
    },
    "deleteConfirm": {
      "prefix": "Delete",
      "suffix": "? This draft will be permanently removed.",
      "cancel": "Cancel",
      "confirm": "Delete"
    },
    "empty": {
      "allMessage": "No invoices yet. Create your first invoice to get started.",
      "filteredMessage": "No {status} invoices found.",
      "createInvoice": "Create Invoice"
    },
    "toast": {
      "batchSubmitted": "Batch submitted: {accepted} accepted, {rejected} rejected",
      "batchSubmissionFailed": "Batch submission failed",
      "voidFailedTitle": "Invoice could not be voided",
      "voidFailedDescription": "Review the invoice status and try again.",
      "deleteFailedTitle": "Delete failed",
      "deleteFailedDescription": "This invoice could not be deleted. Refresh and try again.",
      "deleteHasDeliveryDescription": "This draft still has a delivery order that is not cancelled, so deleting it would strand that delivery. Cancel or void the delivery order first, or issue the invoice instead of deleting it.",
      "batchUnconfirmed": "Not confirmed by LHDN: {count}. These invoices stay Pending and may already be with LHDN, so do not submit them again. Groot is checking with LHDN and will update each status by itself, which can take up to an hour. If they are still Pending after a day, contact support."
    },
    "adjustments": {
      "title": "Adjustments ({count})",
      "creditNoteAbbr": "CN",
      "refundNoteAbbr": "RN",
      "debitNoteAbbr": "DN",
      "lhdnStatus": "LHDN: {status}"
    },
    "netSummary": {
      "originalAmount": "Original Amount",
      "totalCredited": "Total Credited",
      "totalDebited": "Total Debited",
      "adjustedTotal": "Adjusted Total"
    }
  },
  "coaEligibility": {
    "loading": "Loading accounts…",
    "importCta": "Import Chart of Accounts",
    "saveError": "Couldn't save your change. Please try again."
  },
  "coaImport": {
    "title": "Import Chart of Accounts",
    "coaOnlyNote": "Only account codes and names are imported (no transactions or balances).",
    "pasteLabel": "Paste accounts",
    "pastePlaceholder": "Code,Name\n5100,Office Supplies\n5200,Travel",
    "uploadLabel": "Upload CSV or XLSX",
    "noRows": "No accounts found in that file.",
    "parseFailed": "Couldn't read that file. Check the format and try again.",
    "duplicatesWarning": "Duplicate codes were skipped: {codes}",
    "previewHeading": "Preview ({count, plural, one {# account} other {# accounts}})",
    "colCode": "Code",
    "colName": "Name",
    "colType": "Type",
    "importCta": "{count, plural, one {Import # account} other {Import # accounts}}",
    "importing": "Importing…",
    "successToast": "Imported {created} new and updated {updated} accounts.",
    "dupError": "Duplicate codes in your file: {codes}",
    "genericError": "Couldn't import your accounts. Please try again."
  },
  "chatUI": {
    "header": {
      "closeAriaLabel": "Close"
    },
    "funMessages": {
      "summoningAgent": "Summoning your financial agent...",
      "crunchingNumbers": "Crunching the numbers...",
      "consultingLedger": "Consulting the ledger spirits...",
      "warmingUp": "Warming up the calculators...",
      "brewingInsights": "Brewing some insights...",
      "balancingBooks": "Balancing the books...",
      "countingBeans": "Almost there, counting beans..."
    },
    "input": {
      "placeholder": "Ask about expenses, compliance, vendors...",
      "placeholderWithAttachment": "Add a note (optional)...",
      "stopGenerationAriaLabel": "Stop generation",
      "sendMessageAriaLabel": "Send message",
      "connecting": "Connecting securely… Your message is ready to send.",
      "disclaimer": "AI may make mistakes. Verify important information."
    },
    "upload": {
      "failed": "Upload failed",
      "failedForFile": "Upload failed for {filename}"
    },
    "errors": {
      "sendFailedRetry": "Message failed to send. Please try again.",
      "noBusinessContext": "No business is selected right now. Refresh the page, then try again.",
      "responseTimedOut": "The assistant took too long to reply. Send your message again.",
      "tooManyAttachments": "A message can carry up to {receipts} receipts, or up to {documents} files when it includes a statement or another document. Nothing was recorded. Send the rest in another message.",
      "attachmentNotRecognised": "I could not safely sort these attachments, so nothing was recorded. Send receipts, bills and statements in separate messages, and check that each file opens normally.",
      "rateLimited": "You have reached the hourly limit for messages. Try again in about {minutes} min.",
      "usageLimitReached": "You have used this month's AI messages for your plan. Buy a credit pack or upgrade your plan to keep chatting.",
      "grabCaptureNotSaved": "I could not save the Grab order draft. Your uploads are still available, so try again in a moment."
    },
    "emptyState": {
      "heading": "What do you need help with?",
      "subtitle": "Select a topic or type your question below."
    },
    "suggestions": {
      "analyzeCashFlow": "Analyze my cash flow runway",
      "showRecentInvoices": "Show my recent invoices",
      "gstRequirements": "GST requirements for Singapore",
      "findUnusualSpending": "Find unusual spending patterns",
      "compareVendorCosts": "Compare my vendor costs",
      "summarizeExpenses": "Summarize my expenses this month",
      "showTeamSpending": "Show team spending",
      "checkPendingApprovals": "Check pending approvals",
      "showMyExpenseClaims": "Show my expense claims"
    },
    "voice": {
      "start": "Start voice input",
      "stop": "Stop recording",
      "listening": "Listening…",
      "transcribing": "Transcribing…",
      "permissionDenied": "Microphone access is blocked. Enable it in your browser or device settings.",
      "noSpeech": "No speech detected. Please try again.",
      "unavailable": "Voice input is temporarily unavailable. Please type instead.",
      "limitReached": "Reached the 60-second limit.",
      "network": "Couldn't reach the transcription service. Check your connection.",
      "error": "Something went wrong with voice input."
    },
    "memory": {
      "remembered": "Remembered",
      "askTitle": "Remember this?",
      "updateTitle": "Update what I remember?",
      "insteadOf": "Instead of: {note}",
      "undo": "Undo",
      "remember": "Remember",
      "update": "Update",
      "notNow": "Not now",
      "manage": "Manage memory",
      "dismiss": "Dismiss",
      "forgotten": "Forgotten",
      "failed": "Couldn't update memory. Try again."
    }
  },
  "actionCenter": {
    "header": {
      "title": {
        "cfoBrief": "CFO Brief",
        "needsAttention": "Needs Your Attention"
      },
      "newBadge": "{count} new",
      "criticalCount": "{count} critical",
      "highPriorityCount": "{count} high priority",
      "noUrgentItems": "No urgent items"
    },
    "markAllRead": "Mark all read",
    "tabs": {
      "new": "New ({count})",
      "critical": "Critical ({count})",
      "reviewed": "Reviewed ({count})"
    },
    "loadingInsights": "Loading insights...",
    "empty": {
      "all": "All caught up! No new insights.",
      "critical": "No critical issues detected.",
      "reviewed": "No reviewed insights yet."
    },
    "showLess": "Show less",
    "showMore": "Show {count} more insights",
    "summary": {
      "total": "Total: {count}",
      "actioned": "Actioned: {count}",
      "dismissed": "Dismissed: {count}",
      "actionableRate": "Actionable rate: {rate}%"
    },
    "category": {
      "anomaly": "Anomaly",
      "compliance": "Compliance",
      "deadline": "Deadline",
      "cashflow": "Cash Flow",
      "optimization": "Optimization",
      "categorization": "Categorization"
    },
    "priority": {
      "critical": "critical",
      "high": "high",
      "medium": "medium",
      "low": "low"
    },
    "status": {
      "new": "new",
      "reviewed": "reviewed",
      "dismissed": "dismissed",
      "actioned": "actioned"
    },
    "actions": {
      "askAi": "Ask AI",
      "done": "Done",
      "dismiss": "Dismiss",
      "resolve": "Resolve",
      "resolveDraftMessage": "Help me resolve: \"{title}\". Recommended action: {recommendedAction}. Walk me through it and take the next step.",
      "open": "Open"
    },
    "countdown": {
      "left": "{hours}h {minutes}m left",
      "minutesLeft": "{minutes}m left",
      "closed": "The window has closed"
    },
    "detail": {
      "close": "Close",
      "recommendedAction": "Recommended Action",
      "detected": "Detected: {date}",
      "status": "Status: {status}"
    },
    "dismissDialog": {
      "title": "Dismiss Insight",
      "subtitle": "Help Groot learn. Why is this not useful?",
      "placeholder": "e.g., This is a regular quarterly payment...",
      "submit": "Submit & Dismiss",
      "skip": "Skip"
    },
    "askAi": {
      "draftMessage": "Tell me more about: \"{title}\". What data supports this finding and what should I do?"
    },
    "chips": {
      "anomaly": {
        "transactionDetails": "Show me the transaction details",
        "recurringPattern": "Is this a recurring pattern?",
        "financialImpact": "What's the financial impact?"
      },
      "cashflow": {
        "projectedRunway": "What's my projected runway?",
        "incomeVsExpenses": "Show me recent income vs expenses",
        "overdueInvoices": "Which invoices are overdue?"
      },
      "optimization": {
        "suppliersAffected": "Which suppliers are affected?",
        "alternatives": "What are my alternatives?",
        "spendingTrend": "Show me the spending trend"
      },
      "compliance": {
        "riskFactors": "What are the risk factors?",
        "missingInformation": "What information is missing?",
        "howToResolve": "How do I resolve this?"
      },
      "deadline": {
        "paymentDetails": "Show me the payment details",
        "whatIfMissed": "What happens if I miss this?",
        "schedulePayment": "Can I schedule this payment?"
      },
      "default": {
        "dataSupport": "What data supports this?",
        "nextStep": "What should I do next?",
        "financialImpact": "What's the financial impact?"
      }
    },
    "insights": {
      "expenseExceedingIncome": {
        "noIncome": {
          "title": "Expenses with no income recorded",
          "description": "You have {totalExpenses} in expenses but no income recorded in the last {periodDays, number} days.",
          "recommendedAction": "Record your income transactions or review if all expenses are legitimate."
        },
        "exceedsIncome": {
          "title": "Expenses exceeding income this month",
          "description": "Your expenses ({totalExpenses}) are {excessPercent, number}% higher than income ({totalIncome}) over the last {periodDays, number} days.",
          "recommendedAction": "Review your recent expenses and consider cost-cutting measures or increasing revenue."
        },
        "noPositiveIncome": {
          "title": "Net loss with no positive income",
          "description": "Recorded income is {totalIncome} and expenses are {totalExpenses}, producing a loss of {netLoss} over the last {periodDays, number} days. There is no positive income to compare as a percentage.",
          "recommendedAction": "Review sales refunds, income postings and expenses for this period."
        }
      },
      "anomalyExpense": {
        "title": "Unusual expense detected in \"{categoryDisplayName}\"",
        "description": "An expense of {amount} in \"{categoryDisplayName}\" is {deviation}σ above your average of {mean}.",
        "recommendedAction": "Review this transaction to ensure it's legitimate and correctly categorized."
      },
      "uncategorized": {
        "title": "{count, plural, one {# transaction needs} other {# transactions need}} categorization",
        "description": "{percent, number}% of your expense transactions are uncategorized. Proper categorization improves financial insights and reporting accuracy.",
        "recommendedAction": "Review and categorize your uncategorized transactions for better financial tracking."
      },
      "vendorPriceAnomaly": {
        "title": "{vendorName}: {count, plural, one {# price anomaly} other {# price anomalies}} detected",
        "description": "Price increases up to {maxChange, number}% detected for {vendorName}. Review in Vendor Intelligence.",
        "recommendedAction": "Review these price changes in Vendor Intelligence."
      },
      "supplierConcentration": {
        "title": "Supplier concentration risk: {count, plural, one {# supplier} other {# suppliers}} above {threshold, number}%",
        "description": "{supplierList}. High reliance on few suppliers exposes the business to supply-chain risk if any face issues or increase prices.",
        "recommendedAction": "Diversify supplier base to reduce dependency. Negotiate better terms with current suppliers and identify alternatives."
      },
      "supplierSpendingChanges": {
        "title": "Supplier spending changes: {count, plural, one {# supplier} other {# suppliers}} with significant shifts",
        "description": "{changeList}. Review supplier relationships for cost optimization opportunities.",
        "recommendedAction": "Review recent invoices from affected suppliers. Negotiate terms or explore alternatives where costs have increased."
      },
      "supplierRisk": {
        "title": "High-risk supplier: {vendorName}",
        "description": "{vendorName} has a risk score of {riskScore, number}/100. Issues: {factors}.",
        "recommendedAction": "Review and update supplier information for {vendorName}."
      },
      "paymentDue": {
        "title": "Payment due in {days, plural, one {# day} other {# days}}: {amount}",
        "description": "Invoice from {vendorName} of {amount} is due on {dueDate}.",
        "recommendedAction": "{urgent, select, yes {Urgent: Process this payment immediately.} other {Schedule this payment before {dueDate}.}}"
      },
      "negativeCash": {
        "title": "Cash is negative",
        "description": "Your registered bank and cash accounts total {balance} as at {asAt}, so a runway cannot be worked out.",
        "recommendedAction": "Check the Bank / Cash accounts and record any missing receipts."
      },
      "lowRunway": {
        "title": "Low cash runway: {days, plural, one {# day} other {# days}}",
        "description": "Your cash balance is falling by {burnRate}/month, so the cash you hold lasts approximately {days, plural, one {# day} other {# days}}.",
        "recommendedAction": "{critical, select, yes {Critical: Review expenses and prioritize collections immediately.} other {Review cash flow and consider reducing non-essential expenses.}}"
      },
      "potentialDuplicate": {
        "title": "Potential duplicate: {count, plural, one {# entry} other {# entries}} of {amount}",
        "description": "Found {count, plural, one {# journal entry} other {# journal entries}} with same amount and date. These may be duplicates.",
        "recommendedAction": "Review these entries to confirm they are not duplicates."
      },
      "stalePayables": {
        "title": "{count, plural, one {# unpaid bill} other {# unpaid bills}} aging {daysOld, number}+ days",
        "description": "{count, plural, one {# payable} other {# payables}} totaling {totalAmount} have no due date set and have been pending for {daysOld, number}+ days. Set due dates or record payments.",
        "recommendedAction": "Set due dates on these payables and schedule payments. Bills without due dates are easy to forget."
      },
      "splitClaims": {
        "title": "Potential split claims: {count, plural, one {# instance} other {# instances}} detected",
        "description": "{summary}. Multiple small claims on the same day may indicate split submissions to stay under approval thresholds.",
        "recommendedAction": "Review these claims to verify they are legitimate separate expenses and not split to avoid approval limits."
      },
      "employeeExpenseSpike": {
        "title": "Employee expense spike: {count, plural, one {# employee} other {# employees}} with unusual increase",
        "description": "{summary}. Sudden increases in employee claims may warrant review to verify legitimacy.",
        "recommendedAction": "Review recent expense claims from these employees. Verify the increase is due to legitimate business activity (e.g., travel, events)."
      },
      "monthlyAgingReport": {
        "title": "{hasRecon, select, yes {{periodMonth} Aging Reports Ready (Review Needed)} other {{periodMonth} Aging Reports Ready}}",
        "description": "{hasRecon, select, yes {Your monthly AP and AR aging reports for {periodMonth} are ready to generate. ⚠ {reconCount, plural, one {# bank transaction} other {# bank transactions}} may match outstanding invoices. Review before sending statements. Visit the Reports page to generate consolidated reports and debtor statements.} other {Your monthly AP and AR aging reports for {periodMonth} are ready to generate. Visit the Reports page to generate consolidated reports and debtor statements.}}",
        "recommendedAction": "{hasRecon, select, yes {Review {reconCount, plural, one {# potential bank match} other {# potential bank matches}} before generating statements to ensure accuracy.} other {Generate your {periodMonth} aging reports and review debtor statements before sending.}}"
      },
      "einvoiceRejectWindow": {
        "title": "E-invoice from {supplier, select, none {a supplier} other {{supplier}}} can still be rejected",
        "description": "{supplier, select, none {A supplier} other {{supplier}}} sent you e-invoice {number}{amount, select, none {} other { for {amount}}}. You can reject it at LHDN for 72 hours after LHDN validated it. If it is correct, you do not need to do anything.",
        "recommendedAction": "Open the e-invoice and check it against what you bought. Reject it only if it is wrong."
      },
      "overdueReceivablesBatch": {
        "title": "{count, plural, one {# invoice} other {# invoices}} overdue{aged, select, yes { ({daysOverdue, number}+ days)} other {}}",
        "description": "{count, plural, one {# unpaid invoice} other {# unpaid invoices}} totaling {totalOutstanding} {count, plural, one {is} other {are}} overdue. Follow up with customers to collect payment.",
        "recommendedAction": "{urgent, select, yes {Urgent: Send final payment reminders and consider escalation for invoices 30+ days overdue.} other {Send payment reminders to customers with overdue invoices.}}"
      },
      "overdueReceivablesBatchPartial": {
        "title": "{count, plural, one {# invoice} other {# invoices}} overdue{aged, select, yes { ({daysOverdue, number}+ days)} other {}}",
        "description": "{count, plural, one {# unpaid invoice is} other {# unpaid invoices are}} overdue. {homeCount, plural, =0 {} other {{totalOutstanding} is owed on # of them in the business currency. }}{otherCount, plural, one {# is} other {# are}} in another or unknown currency and not added up. Follow up with customers to collect payment.",
        "recommendedAction": "{urgent, select, yes {Urgent: Send final payment reminders and consider escalation for invoices 30+ days overdue.} other {Send payment reminders to customers with overdue invoices.}}"
      },
      "stalePayablesPartial": {
        "title": "{count, plural, one {# unpaid bill} other {# unpaid bills}} aging {daysOld, number}+ days",
        "description": "{count, plural, one {# payable has} other {# payables have}} no due date set and been pending for {daysOld, number}+ days. {homeCount, plural, =0 {} other {{totalAmount} is owed on # of them in the business currency. }}{otherCount, plural, one {# is} other {# are}} in another or unknown currency and not added up. Set due dates or record payments.",
        "recommendedAction": "Set due dates on these payables and schedule payments. Bills without due dates are easy to forget."
      }
    },
    "alreadyResolved": "Another team member already resolved this insight."
  },
  "debtorDetail": {
    "statusActive": "Active",
    "statusInactive": "Inactive",
    "header": {
      "subtitle": "Customer profile, invoice defaults, contact details, and account information.",
      "primaryEmail": "Primary email",
      "primaryPhone": "Primary phone",
      "customerCode": "Customer code",
      "priceTier": "Price tier"
    },
    "editDialog": {
      "title": "Edit customer details",
      "description": "Update invoice defaults, contact details, tax registration, address, and internal notes."
    },
    "sectionAccount": "Account Defaults",
    "sectionIdentity": "Identity & Tax",
    "sectionContact": "Contact",
    "sectionAddress": "Billing Address",
    "sectionNotes": "Internal Notes",
    "back": "Back",
    "editDetails": "Edit Details",
    "cancel": "Cancel",
    "save": "Save",
    "customerNotFound": "Customer not found",
    "generateStatement": "Generate Statement",
    "requestInfo": {
      "button": "Request Info Update",
      "noEmailTooltip": "No email address on file. Add an email first.",
      "sendTooltip": "Send email requesting customer to update their info",
      "resendConfirm": "An email was sent {hours, plural, one {# hour} other {# hours}} ago. Send again?",
      "sendSuccess": "Email sent successfully!",
      "sendFailedRetry": "Failed to send email. Please try again.",
      "sendFailed": "Failed to send email.",
      "dialogTitle": "Request info update",
      "dialogDescription": "Ask {name} to review and update their own business details. Choose how to reach them.",
      "emailLabel": "Send via email",
      "emailHint": "We'll email a secure update link to {email}.",
      "emailDisabledNoAddress": "No email address on file. Add one in Edit Details first, or use the QR code.",
      "emailLastSent": "Last sent {hours, plural, one {# hour} other {# hours}} ago.",
      "emailCta": "Send email",
      "emailSending": "Sending…",
      "qrLabel": "Show QR code",
      "qrHint": "Display a QR code and link to share, print, or screenshot.",
      "qrCta": "Show QR code",
      "toastSuccess": "Update request sent to {email}.",
      "toastFailed": "Couldn't send the email. Please try again.",
      "close": "Close",
      "confirmTitle": "Send update request?",
      "confirmBody": "We'll email a secure update link to {email}. They can review and update their own business details.",
      "confirmCta": "Send email",
      "cancel": "Cancel"
    },
    "toast": {
      "noActiveBusiness": "No active business. Please refresh and try again",
      "noChanges": "No changes to save",
      "customerUpdated": "Customer updated ({count, plural, one {# field} other {# fields}} changed)",
      "saveFailed": "Failed to save customer details. Please try again"
    },
    "summary": {
      "totalInvoiced": "Total Invoiced",
      "totalPaid": "Total Paid",
      "outstanding": "Outstanding",
      "overdueInvoices": "Overdue Invoices"
    },
    "particulars": {
      "title": "Customer Particulars",
      "subtitle": "Details used for invoicing, statements, tax documents, and customer follow-up."
    },
    "fields": {
      "emailPrimary": "Email (Primary)",
      "contactPerson": "Contact Person",
      "position": "Position / Title",
      "phonePrimary": "Phone (Primary)",
      "phoneSecondary": "Phone (Secondary)",
      "fax": "Fax",
      "emailSecondary": "Email (Secondary)",
      "website": "Website",
      "customerCode": "Customer Code",
      "businessNature": "Business Nature",
      "defaultCurrency": "Default Currency",
      "paymentTerms": "Payment Terms",
      "creditLimit": "Credit Limit",
      "idType": "ID Type",
      "tin": "TIN",
      "brn": "BRN / Registration No",
      "sstRegistration": "SST Registration",
      "addressLine1": "Address Line 1",
      "addressLine2": "Address Line 2",
      "addressLine3": "Address Line 3",
      "city": "City",
      "postalCode": "Postal Code",
      "state": "State",
      "country": "Region",
      "notes": "Notes",
      "defaultPriceTier": "Default price tier",
      "defaultSalesAgent": "Default sales agent"
    },
    "placeholders": {
      "contactPerson": "Contact name",
      "position": "e.g. Accounts Manager",
      "fax": "Fax number",
      "businessNature": "e.g. Trading, Manufacturing",
      "selectTerms": "Select terms",
      "selectIdType": "Select ID type",
      "tin": "Tax Identification Number",
      "brn": "Business Registration No",
      "sstRegistration": "SST Registration No",
      "addressLine1": "Street address",
      "addressLine2": "Suite, floor, etc.",
      "addressLine3": "Area / District",
      "city": "City",
      "postalCode": "Postal code",
      "state": "State code",
      "notes": "Internal notes about this customer",
      "selectPriceTier": "Select price tier",
      "selectSalesAgent": "Select a sales agent"
    },
    "paymentTermsOptions": {
      "COD": "Cash on Delivery",
      "NET7": "Net 7 Days",
      "NET14": "Net 14 Days",
      "NET30": "Net 30 Days",
      "NET45": "Net 45 Days",
      "NET60": "Net 60 Days",
      "NET90": "Net 90 Days"
    },
    "idTypeOptions": {
      "BRN": "Business Registration No (BRN)",
      "NRIC": "NRIC",
      "PASSPORT": "Passport",
      "ARMY": "Army ID"
    },
    "selfService": {
      "title": "Self-Service Updates",
      "changeHistory": "Change History"
    },
    "token": {
      "loading": "Loading token...",
      "linkTitle": "Self-Service Link",
      "active": "Active",
      "expired": "Expired",
      "createdExpires": "Created {created} · Expires {expires}",
      "copy": "Copy",
      "copied": "Copied!",
      "regenerate": "Regenerate Link",
      "noLink": "No self-service link generated yet.",
      "generate": "Generate Link"
    },
    "invoiceHistory": {
      "title": "Invoice History ({count})",
      "empty": "No invoices found",
      "due": "Due {date}",
      "balanceDue": "Due: {amount}",
      "payments": "Payments"
    },
    "status": {
      "draft": "draft",
      "sent": "sent",
      "overdue": "overdue",
      "partially_paid": "partially paid",
      "paid": "paid",
      "void": "void"
    },
    "paymentType": {
      "invoice": "invoice",
      "payment": "payment",
      "reversal": "reversal"
    },
    "runningBalance": {
      "title": "Running Balance",
      "date": "Date",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "balance": "Balance"
    },
    "readOnly": {
      "customerCode": "Customer Code",
      "email": "Email",
      "contactPerson": "Contact Person",
      "position": "Position",
      "phone": "Phone",
      "phone2": "Phone (2)",
      "fax": "Fax",
      "email2": "Email (2)",
      "website": "Website",
      "businessNature": "Business Nature",
      "defaultCurrency": "Default Currency",
      "paymentTerms": "Payment Terms",
      "creditLimit": "Credit Limit",
      "idType": "ID Type",
      "tin": "TIN",
      "brn": "BRN",
      "sstRegistration": "SST Registration",
      "address": "Address",
      "notes": "Notes",
      "notSet": "Not set",
      "noCreditLimit": "No limit set",
      "noNotes": "No internal notes recorded.",
      "empty": "No additional details recorded. Click \"Edit Details\" to add customer information.",
      "defaultPriceTier": "Default Price Tier"
    },
    "statement": {
      "backToDetail": "Back to Detail",
      "title": "Statement of Account",
      "from": "From",
      "to": "To",
      "downloadPdf": "Download PDF",
      "businessFallback": "Business",
      "registration": "Reg: {number}",
      "billTo": "Bill To",
      "openingBalance": "Opening Balance",
      "date": "Date",
      "reference": "Reference",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "balance": "Balance",
      "noTransactions": "No transactions in this period",
      "totalDebits": "Total Debits",
      "totalCredits": "Total Credits",
      "closingBalance": "Closing Balance",
      "selectDateRange": "Select a date range to generate statement"
    },
    "priceTier": {
      "businessDefault": "Business default tier: {tier}",
      "defaultTier": "Default",
      "defaultBadge": "default"
    },
    "loyalty": {
      "loading": "Loading loyalty points...",
      "title": "Loyalty points",
      "subtitle": "Track customer points with an auditable ledger. Points have no journal entries.",
      "currentBalance": "Current balance",
      "currentBalanceShort": "Current",
      "changePreview": "Change",
      "finalBalance": "Final",
      "redeemAction": "Redeem",
      "adjustAction": "Adjust",
      "enabled": "Enabled",
      "amountPerPoint": "Amount per point",
      "pointsPerAmount": "Points per amount",
      "currency": "Currency",
      "saveSettings": "Save settings",
      "settingsSaved": "Loyalty settings saved.",
      "saveFailed": "Could not save loyalty points changes.",
      "disabledReadOnly": "Loyalty points are disabled. History stays visible, but point changes are blocked.",
      "redeemTitle": "Redeem points",
      "redeemDescription": "Deduct points used by this customer. Redemptions cannot take the balance below zero.",
      "adjustTitle": "Manual adjustment",
      "adjustDescription": "Record a correction or one-off change. Adjustments can increase or decrease the balance.",
      "pointsLabel": "Points",
      "deltaLabel": "Point change",
      "reasonLabel": "Reason",
      "pointsPlaceholder": "Points",
      "deltaPlaceholder": "+/- points",
      "reasonPlaceholder": "Reason",
      "cancel": "Cancel",
      "record": "Record",
      "recordRedemption": "Record redemption",
      "recordAdjustment": "Record adjustment",
      "redemptionTooHigh": "This redemption would take the balance below zero.",
      "adjustmentTooLow": "This adjustment would take the balance below zero.",
      "redeemSaved": "Redemption recorded.",
      "adjustSaved": "Adjustment recorded.",
      "ledgerHistory": "Points ledger",
      "settingsHistory": "Settings history",
      "noLedger": "No point history yet.",
      "noSettingsHistory": "No settings changes yet.",
      "balanceAfter": "Balance {balance}",
      "historyType": "Type",
      "historyDate": "Date",
      "historyReason": "Reason",
      "historyPoints": "Points",
      "historyBalance": "Balance",
      "ledgerType": {
        "earn": "Earned",
        "redeem": "Redeemed",
        "adjustment": "Adjustment",
        "reversal_adjustment": "Reversal adjustment"
      },
      "errors": {
        "disabled": "Loyalty points are switched off for this business. Turn them on in Settings before adjusting a balance.",
        "invalidPoints": "Enter a points amount that isn't zero."
      }
    },
    "delete": {
      "button": "Delete Customer",
      "confirmTitle": "Delete this customer?",
      "confirmBody": "This permanently deletes {name} and can't be undone. Customers with linked invoices or transactions can't be deleted. Deactivate them instead.",
      "blockedToast": "This customer can't be deleted because it has linked invoices or transactions. Deactivate it instead.",
      "success": "Customer deleted",
      "errors": {
        "ownerOnly": "Only an owner can permanently delete a customer.",
        "hasLinkedRecords": "This customer has invoices or accounting entries against them, so they can't be deleted. Removing them would break your audit trail. Mark them inactive instead."
      }
    },
    "recordReceipt": "Record receipt",
    "errors": {
      "customerNotFound": "We couldn't find this customer. They may have been removed. Go back to the customer list and refresh.",
      "priceTierNotFound": "That price tier no longer exists. Pick a current one.",
      "saveFailedGeneric": "We couldn't save your changes to this customer. Nothing was changed, so please try again.",
      "salesAgentRestricted": "Only an owner or finance admin can change a customer's sales agent. Nothing was changed.",
      "salesAgentUnavailable": "That sales agent is no longer available. Pick a current one."
    },
    "salesAgent": {
      "noDefault": "No default agent",
      "retired": "retired",
      "hint": "Prefilled on new invoices for this customer. It can be changed on each invoice.",
      "ownerOnly": "Only an owner or finance admin can change the sales agent.",
      "unknown": "Unknown agent"
    }
  },
  "agingReports": {
    "arTitle": "AR Aging Report",
    "apTitle": "AP Aging Report",
    "backToCustomers": "Back to Customers",
    "backToInvoices": "Back to Invoices",
    "asOf": "As of",
    "asOfColon": "As of:",
    "exportCsv": "Export CSV",
    "bucketCurrent": "Current",
    "bucket1To30Days": "1-30 Days",
    "bucket31To60Days": "31-60 Days",
    "bucket61To90Days": "61-90 Days",
    "bucket90PlusDays": "90+ Days",
    "total": "Total",
    "totalOutstanding": "Total Outstanding",
    "vendorBreakdown": "Vendor Breakdown",
    "noOutstandingPayables": "No outstanding payables",
    "noOutstandingReceivables": "No Outstanding Receivables",
    "allInvoicesPaidAsOf": "All invoices are paid as of {date}",
    "perCustomerBreakdown": "Per-Customer Breakdown ({count})",
    "colVendor": "Vendor",
    "colOutstanding": "Outstanding",
    "colCustomer": "Customer",
    "colCurrent": "Current",
    "col1To30": "1-30",
    "col31To60": "31-60",
    "col61To90": "61-90",
    "col90Plus": "90+",
    "colTotal": "Total",
    "totalRow": "TOTAL",
    "controlTie": {
      "ap": {
        "tied": "Payables aging {amount} ties to {account} as at {date}.",
        "differs": "Payables aging {amount} differs from {account} ({ledger}) as at {date} by {difference}.",
        "differsHint": "Bills not yet posted, opening balances and payments recorded without a bill can account for a difference.",
        "unavailable": "The payable account could not be read for this date, so the aging was not checked against it."
      },
      "otherCurrencies": "Amounts in other currencies are not in this comparison; it covers {currency} only.",
      "ar": {
        "tied": "Receivables aging {amount} ties to {account} as at {date}.",
        "differs": "Receivables aging {amount} differs from {account} ({ledger}) as at {date} by {difference}.",
        "differsHint": "Credit refunded or applied to customers, invoices not yet posted and opening balances can account for a difference.",
        "unavailable": "The receivable account could not be read for this date, so the aging was not checked against it."
      }
    },
    "asAtApproximate": "This business has more receipts than one as-at read can restate, so these are today's balances aged to {date}, not the balances on that date."
  },
  "x_applocale_0": {
    "dashboard_title": "Dashboard",
    "payables_title": "Payables",
    "accounting_title": "Accounting",
    "leave_management_title": "Leave Management",
    "manager_approvals_title": "Manager Approvals"
  },
  "x_applocale_1": {
    "teamsTitle": "Teams",
    "categoriesTitle": "Categories",
    "expenseClaimsTitle": "Expense Claims",
    "invoicesTitle": "Invoices"
  },
  "x_applocale_2": {
    "settings_loading_title": "Settings",
    "pricing_loading_title": "Pricing",
    "reporting_loading_title": "Reporting & Exports",
    "mcp_docs_loading_title": "MCP Documentation",
    "pricing_metadata_title": "Pricing - Groot Finance",
    "pricing_metadata_description": "Choose the right plan for your business",
    "pricing_header_title": "Pricing",
    "pricing_header_subtitle": "Choose the plan that fits your business needs",
    "pricing_back_to_billing": "Back to Billing",
    "pricing_section_heading": "Pricing",
    "pricing_section_tagline": "Start free, upgrade as you grow.",
    "pricing_footer_currency_note": "Prices shown in your local currency. Billed monthly.",
    "pricing_footer_custom_plan": "Need a custom plan?",
    "pricing_footer_contact_us": "Contact us"
  },
  "x_applocale_3": {
    "actionCenterTitle": "AI Action Center",
    "leaveTitle": "Leave",
    "businessSettingsTitle": "Business Settings",
    "referralProgramTitle": "Referral Program",
    "metaTitle": "MCP Server Documentation - Groot Finance",
    "metaDescription": "Documentation for Groot Finance MCP Server - Connect Claude Desktop, Cursor, or any MCP-compatible client to your financial data.",
    "backToApiKeys": "Back to API Keys",
    "mcpDocumentation": "MCP Documentation",
    "heroTitle": "Groot Finance MCP Server",
    "heroDescription": "Financial intelligence tools for AI assistants via the Model Context Protocol. Connect Claude Desktop, Cursor, or any MCP-compatible client to your business data.",
    "quickStart": "Quick Start",
    "step1Title": "Get Your API Key",
    "step1Description": "Go to Settings → API Keys in your Groot Finance dashboard, create a new key, and select the tools you want to enable.",
    "manageApiKeys": "Manage API Keys",
    "step2Title": "Configure Your MCP Client",
    "step2Description": "Add the Groot Finance server to your MCP client configuration.",
    "addTo": "Add to",
    "step3Title": "Test Connection",
    "availableTools": "Available Tools",
    "readOnlyToolsTitle": "Read-Only Intelligence Tools",
    "readOnlyToolsDescription": "These tools analyze your financial data without making changes.",
    "detectAnomaliesDesc": "Detect unusual financial transactions using statistical outlier analysis. Returns transactions with spending patterns significantly different from historical norms.",
    "paramDateRange": "Start/end dates (defaults to last 30 days)",
    "paramCategoryFilter": "Filter to specific categories",
    "paramSensitivity": "low (3σ), medium (2σ), high (1.5σ)",
    "forecastCashFlowDesc": "Project future cash balance based on historical income/expense patterns. Provides alerts for potential cash flow issues.",
    "paramHorizonDays": "7-90 days forecast (default: 30)",
    "paramScenario": "conservative, moderate, optimistic",
    "paramIncludeRecurring": "Factor in recurring transactions",
    "analyzeVendorRiskDesc": "Analyze vendor concentration, spending changes, and risk factors. Identifies suppliers with high dependency risk.",
    "paramVendorFilter": "Filter to specific vendors",
    "paramAnalysisPeriodDays": "7-365 days lookback",
    "paramIncludeConcentration": "Include concentration risk",
    "proposalToolsTitle": "Proposal Tools (Human-in-the-Loop)",
    "proposalToolsWarning": "These tools enable AI-assisted write operations with human approval. Proposals expire after 15 minutes to prevent stale approvals.",
    "createProposalDesc": "Create a proposal for a write operation that requires human approval. Returns a proposal_id that must be confirmed before the action executes.",
    "paramActionType": "approve_expense, reject_expense, categorize_expense, update_vendor",
    "paramTargetId": "ID of the target entity",
    "paramSummary": "Human-readable summary (10-500 chars)",
    "confirmProposalDesc": "Confirm and execute a pending proposal. This is the human approval step that triggers the actual write operation.",
    "paramProposalIdConfirm": "The proposal ID from create_proposal",
    "cancelProposalDesc": "Cancel a pending proposal without executing it.",
    "paramProposalIdCancel": "The proposal ID to cancel",
    "paramReason": "Optional cancellation reason",
    "errorCodes": "Error Codes",
    "errorColCode": "Code",
    "errorColDescription": "Description",
    "errorColSolution": "Solution",
    "errorUnauthorizedDesc": "Invalid or missing API key",
    "errorUnauthorizedSolution": "Check your API key in Settings",
    "errorInvalidInputDesc": "Request parameters failed validation",
    "errorInvalidInputSolution": "Check parameter types and required fields",
    "errorInsufficientDataDesc": "Not enough data to complete analysis",
    "errorInsufficientDataSolution": "Expand date range or add more transactions",
    "errorRateLimitedDesc": "Too many requests",
    "errorRateLimitedSolution": "Wait and retry. Default: 60 req/min",
    "errorConvexDesc": "Database operation failed",
    "errorConvexSolution": "Retry or contact support",
    "errorInternalDesc": "Unexpected server error",
    "errorInternalSolution": "Retry or contact support",
    "security": "Security",
    "securityApiKeysHashedTerm": "API keys are hashed",
    "securityApiKeysHashedDesc": "- only the prefix is stored, never the full key",
    "securityBusinessIsolationTerm": "Business isolation",
    "securityBusinessIsolationDesc": "- each key is scoped to one business",
    "securityPermissionAccessTerm": "Permission-based access",
    "securityPermissionAccessDesc": "- keys can be limited to specific tools",
    "securityExpirationTerm": "Expiration support",
    "securityExpirationDesc": "- set keys to auto-expire after 30, 90, or 365 days",
    "securityAuditLoggingTerm": "Audit logging",
    "securityAuditLoggingDesc": "- all tool calls are logged with timestamps",
    "protocolDetails": "Protocol Details",
    "protocolEndpoint": "Endpoint",
    "protocolSupportedMethods": "Supported Methods",
    "protocolAuthentication": "Authentication",
    "protocolBearerToken": "Bearer token in",
    "protocolHeader": "header",
    "learnMoreAboutMcp": "Learn more about MCP"
  },
  "x_applocale_4": {
    "loadingReferralProgram": "Loading referral program...",
    "teamCalendarTitle": "Team Calendar",
    "salesInvoicesTitle": "Sales Invoices",
    "journalEntriesTitle": "Journal Entries",
    "chartOfAccountsTitle": "Chart of Accounts"
  },
  "x_applocale_5": {
    "loading": "Loading...",
    "redirecting": "Redirecting...",
    "referredByPrefix": "Referred by",
    "duplicateReport": {
      "title": "Duplicate Report",
      "subtitle": "Audit potential duplicate expense claims"
    },
    "agingReport": {
      "title": "Aging Report"
    },
    "businessSettings": {
      "title": "Business Settings"
    }
  },
  "x_applocale_6": {
    "billing": {
      "skeletonTitle": "Billing"
    },
    "adminSetup": {
      "skeletonTitle": "Admin Setup",
      "accessDenied": {
        "title": "Access Denied",
        "body": "This page is for Groot platform staff only. If you believe this is an error, contact your administrator."
      },
      "header": {
        "title": "Admin Setup",
        "subtitle": "Assign business admin privileges"
      }
    },
    "catalog": {
      "skeletonTitle": "Product Catalog"
    },
    "dspyObservability": {
      "accessDenied": {
        "title": "Access Denied",
        "body": "This dashboard is for Groot team members only. If you believe this is an error, please contact your administrator."
      },
      "header": {
        "title": "DSPy Observability",
        "subtitle": "Self-improvement metrics for all DSPy tools"
      }
    },
    "pulse": {
      "trialBundle": {
        "trigger": "Apply trial bundle",
        "title": "Apply a trial bundle",
        "description": "Grant a curated, auto-expiring feature preset to this account. Billing is never affected.",
        "bundleLabel": "Bundle",
        "bundlePlaceholder": "Select a bundle",
        "durationLabel": "Duration (days)",
        "durationHint": "Up to {max} days.",
        "enables": "Enables",
        "noBundles": "No active trial bundles are configured.",
        "next": "Review",
        "back": "Back",
        "cancel": "Cancel",
        "confirmTitle": "Confirm trial bundle",
        "confirmBody": "Apply {bundle} to {account}. {count} feature(s) will be enabled until {expiry}, then auto-revert. Billing is unaffected.",
        "confirm": "Apply bundle",
        "applying": "Applying…",
        "success": "Trial bundle applied. It expires {expiry}.",
        "error": "Couldn't apply the trial bundle. Please try again.",
        "thisAccount": "this account"
      },
      "workspace": {
        "title": "Pulse",
        "subtitle": "Staff workspace",
        "backToApp": "Back to app"
      },
      "modeToggle": {
        "customer": "Customer",
        "staff": "Staff",
        "customerAria": "Switch to the customer app",
        "staffAria": "Switch to the Pulse staff console",
        "groupAria": "Workspace mode",
        "navError": "Couldn't switch modes. Please try again."
      },
      "nav": {
        "home": "Pulse Home",
        "featureAccess": "Feature Access",
        "dspyObservability": "DSPy Observability",
        "featureRequests": "Feature Requests",
        "pipeline": "Pipeline",
        "tasks": "Tasks",
        "playbooks": "Playbooks",
        "staffRoles": "Staff Roles",
        "leads": "Solo Leads"
      },
      "roles": {
        "sales": "Sales (Account Manager)",
        "support": "Support",
        "product": "Product",
        "engineering": "Engineering",
        "super": "Super Admin"
      },
      "accessDenied": {
        "title": "Access Denied",
        "body": "This workspace is for Groot platform staff only. If you believe this is an error, contact your administrator."
      },
      "home": {
        "title": "Pulse",
        "subtitle": "Your staff console for internal tooling.",
        "roleLabel": "Role",
        "tools": {
          "featureAccess": {
            "title": "Feature Access",
            "description": "Manage per-business feature entitlements."
          },
          "dspyObservability": {
            "title": "DSPy Observability",
            "description": "Inspect self-improvement metrics across all DSPy tools."
          }
        }
      },
      "account360": {
        "trialDay": "Trial day {x} of {y}",
        "topBlocker": "Top blocker",
        "pqaScore": "Qualification score",
        "health": {
          "insufficient": "Insufficient data",
          "band": {
            "red": "At risk",
            "yellow": "Watch",
            "green": "Healthy",
            "insufficient_data": "Insufficient data"
          },
          "trend": {
            "up": "Trending up",
            "down": "Trending down",
            "flat": "Steady",
            "new": "New"
          }
        },
        "usage": {
          "title": "Usage",
          "receiptsPerWeek": "Receipts / week",
          "chatPerWeek": "Chat messages / week",
          "recordsPosted": "Records posted",
          "seats": "Seats active / licensed",
          "errorCount": "Errors",
          "planLimit": "Plan-limit proximity",
          "featuresAdopted": "Features adopted",
          "lastActive": "Last active {when}"
        },
        "people": {
          "title": "People & users",
          "customerContacts": "Customer contacts",
          "grootOwners": "Groot owners",
          "reveal": "Show contacts",
          "revealError": "Could not load contacts. Please try again.",
          "noContacts": "No customer contacts found.",
          "noOwners": "No Groot owner assigned.",
          "ownersAfterReveal": "Show contacts to view assigned owners.",
          "colName": "Name",
          "colEmail": "Email",
          "colRole": "Role",
          "colLastActive": "Last active",
          "roles": {
            "owner": "Owner",
            "finance_admin": "Finance",
            "manager": "Manager",
            "employee": "Employee"
          },
          "assignmentType": {
            "account_manager": "Account manager",
            "support": "Support",
            "collaborator": "Collaborator"
          }
        },
        "contacts": {
          "title": "Stakeholders",
          "description": "Non-login contacts linked to this account.",
          "add": "Add stakeholder",
          "edit": "Edit",
          "delete": "Delete",
          "link": "Link existing contact",
          "cancel": "Cancel",
          "save": "Save",
          "createReason": "Created via People panel",
          "updateReason": "Updated via People panel",
          "deleteReason": "Deleted via People panel",
          "linkReason": "Linked via People panel",
          "created": "Stakeholder added.",
          "updated": "Stakeholder updated.",
          "deleted": "Stakeholder removed.",
          "linked": "Contact linked.",
          "createError": "Could not add the stakeholder.",
          "updateError": "Could not update the stakeholder.",
          "deleteError": "Could not remove the stakeholder.",
          "linkError": "Could not link the contact.",
          "empty": "No stakeholders linked to this account.",
          "nameRequired": "Name is required.",
          "contactIdRequired": "Contact ID is required.",
          "confirmDelete": "Remove this stakeholder? This deletes the contact and all its account links.",
          "colName": "Name",
          "colTitle": "Title",
          "colEmail": "Email",
          "colPhone": "Phone",
          "colInfluence": "Influence",
          "colRole": "Role",
          "colActions": "Actions",
          "formName": "Name",
          "formTitle": "Title",
          "formEmail": "Email",
          "formPhone": "Phone",
          "formInfluence": "Influence",
          "formRole": "Role in account",
          "formPrimary": "Primary contact",
          "formContactId": "Existing contact ID",
          "influence": {
            "champion": "Champion",
            "economic_buyer": "Economic buyer",
            "blocker": "Blocker",
            "user": "User",
            "unknown": "Unknown"
          }
        },
        "notes": {
          "title": "Notes",
          "add": "Add note",
          "placeholder": "Add a note about this account…",
          "saved": "Note added",
          "saveError": "Could not save the note. Please try again."
        },
        "timeline": {
          "title": "Timeline",
          "note": "Note",
          "event": "Event",
          "emptyTitle": "No activity yet",
          "emptyBody": "Product events and notes will appear here."
        },
        "billing": {
          "title": "Billing",
          "plan": "Plan",
          "status": "Status",
          "trial": "Trial",
          "trialNone": "No active trial",
          "periodEnd": "Period end",
          "subscriptionId": "Subscription ID",
          "source": "Source",
          "manual": "Manual",
          "manualOverrideActive": "Manual override active. Stripe webhooks cannot change plan or status until deactivated.",
          "manualNoOverride": "Manual subscription. A later Stripe webhook may override plan/status (no billingOverride set).",
          "notConfigured": "You don't have permission to change billing.",
          "dialogDescription": "This change is audited with your identity and the reason below.",
          "reason": "Reason",
          "reasonPlaceholder": "Why are you making this change?",
          "reasonRequired": "A reason is required.",
          "confirm": "Confirm",
          "cancel": "Cancel",
          "applying": "Applying…",
          "success": "Billing updated.",
          "error": "Billing update failed.",
          "planLabel": "Plan",
          "periodEndLabel": "Period end (optional)",
          "trialStartLabel": "Trial start",
          "trialEndLabel": "Trial end",
          "newTrialEndLabel": "New trial end",
          "actions": {
            "setTitle": "Set plan",
            "activateTitle": "Activate (manual)",
            "deactivateTitle": "Deactivate",
            "startTrialTitle": "Start trial",
            "extendTrialTitle": "Extend trial",
            "endTrialTitle": "End trial"
          }
        },
        "roster": {
          "pageTitle": "Roster onboarding",
          "title": "Roster onboarding",
          "subtitle": "Onboard a whole team into one business with roles and reporting wired up front.",
          "selectAccount": "Account",
          "selectAccountPlaceholder": "Select an account",
          "reason": "Reason",
          "reasonPlaceholder": "Why are you onboarding this roster? (audited)",
          "pasteTitle": "Paste roster",
          "pasteHint": "One per line: email, role, manager email, approves-to email. Role is one of finance_admin, manager, employee.",
          "pastePlaceholder": "alice@acme.com, employee, mgr@acme.com\nmgr@acme.com, manager\nfa@acme.com, finance_admin",
          "approvesToNotActive": "Not an active approver yet, so this row will be refused. Leave blank unless approval must escalate past the manager.",
          "previewTitle": "Preview",
          "colEmail": "Email",
          "colRole": "Role",
          "colManager": "Reports to",
          "colApprovesTo": "Approves to",
          "submit": "Send invitations",
          "submitting": "Sending...",
          "resultsTitle": "Results",
          "colResultEmail": "Email",
          "colResultStatus": "Status",
          "colResultDetail": "Detail",
          "statusInvited": "Invited",
          "statusInvitedEmailFailed": "Invited (email failed)",
          "statusSkipped": "Skipped (already a member)",
          "statusFailed": "Failed",
          "statusEmailSent": "Email sent",
          "copyLink": "Copy invitation link",
          "linkCopied": "Link copied",
          "noRows": "No rows to preview yet",
          "errorReasonRequired": "A reason is required.",
          "errorAccountRequired": "Select an account.",
          "errorNoRows": "Add at least one invite.",
          "errorGeneric": "Something went wrong. Please try again.",
          "batchTooLarge": "A batch is capped at 100 invites.",
          "summary": "Invited [[invited]], skipped [[skipped]], failed [[failed]].",
          "roles": {
            "employee": "Employee",
            "manager": "Manager",
            "finance_admin": "Finance admin"
          },
          "errors": {
            "reasonRequired": "Add a short reason for this bulk invite before sending it.",
            "batchTooLarge": "That's too many people at once. Split the list into smaller batches and send them one at a time.",
            "invalidArgument": "Some rows in the pasted list couldn't be read. Check that every row has a name and a valid email address."
          }
        }
      },
      "accountList": {
        "title": "Accounts",
        "subtitle": "Your assigned accounts, prioritized by health.",
        "searchPlaceholder": "Search accounts…",
        "colAccount": "Account",
        "colHealth": "Health",
        "colBlocker": "Top blocker",
        "open": "Open account",
        "loadMore": "Load more",
        "refineHint": "Refine your search to see more accounts.",
        "emptyTitle": "No accounts",
        "emptyBody": "No accounts are assigned to you yet.",
        "band": {
          "all": "All",
          "red": "At risk",
          "yellow": "Watch",
          "green": "Healthy",
          "insufficient_data": "Insufficient data"
        }
      },
      "leads": {
        "title": "Solo Leads",
        "subtitle": "People who ran the Bookkeeping Health Check on the Solo landing pages.",
        "colEmail": "Email",
        "colWhatsapp": "WhatsApp",
        "colPersona": "Persona",
        "colScore": "Score",
        "colLock": "Founding lock",
        "colPrice": "Preferred price",
        "colDate": "Date",
        "scoreInProgress": "In progress",
        "locked": "Locked",
        "notLocked": "Not locked",
        "refresh": "Refresh",
        "exportCsv": "Export CSV",
        "emptyTitle": "No leads yet",
        "emptyBody": "Leads from the Solo landing pages will show up here.",
        "errorTitle": "Could not load leads",
        "truncatedHint": "Showing the newest leads. Refine or export to see the rest.",
        "loadingLabel": "Loading leads"
      },
      "today": {
        "title": "Today",
        "subtitle": "What needs your attention across your accounts.",
        "priorityAlerts": "Priority alerts",
        "viewAll": "View all",
        "kpi": {
          "atRisk": "At risk",
          "expansionReady": "Expansion-ready",
          "trialsEnding": "Trials ending",
          "openTasks": "Open tasks"
        },
        "empty": {
          "title": "You're all caught up",
          "description": "No priority alerts across your accounts right now."
        }
      },
      "alerts": {
        "title": "Alerts",
        "subtitle": "Proactive alerts for the accounts you own.",
        "digestNote": "Trial and milestone alerts are also included in your daily email digest.",
        "filter": {
          "unread": "Unread",
          "all": "All"
        },
        "actions": {
          "markRead": "Mark as read",
          "dismiss": "Dismiss",
          "error": "Couldn't update this alert. Please try again."
        },
        "empty": {
          "title": "No alerts",
          "description": "Proactive alerts about your accounts will appear here."
        }
      },
      "featureRequests": {
        "title": "Feature Requests",
        "subtitle": "Cross-account demand, weighted by opportunity value.",
        "opsOnly": "The cross-account demand roll-up is available to ops and super staff only.",
        "empty": "No feature requests logged yet.",
        "truncated": "Showing a capped set of requests. Refine the view as demand grows.",
        "accountsCount": "{n} accounts",
        "atStake": "at stake",
        "mixedCurrency": "{n} currencies",
        "statusOpen": "{n} open",
        "statusPlanned": "{n} planned",
        "statusShipped": "{n} shipped",
        "viewAccounts": "View accounts",
        "noAccounts": "No accounts found.",
        "severity": {
          "blocker": "Blocker",
          "important": "Important",
          "nice_to_have": "Nice to have"
        },
        "status": {
          "open": "Open",
          "planned": "Planned",
          "shipped": "Shipped",
          "declined": "Declined"
        },
        "log": {
          "opportunityLabel": "Open pipeline",
          "placeholder": "Log a feature this account asked for…",
          "severityLabel": "Priority",
          "add": "Log request",
          "empty": "No feature requests logged for this account yet.",
          "saved": "Feature request logged",
          "saveError": "Couldn't log the request. Please try again."
        }
      },
      "accountInsights": {
        "title": "AI talking points",
        "regenerate": "Regenerate",
        "error": "Couldn't generate insights right now. Try again.",
        "lowConfidence": "Not enough signal yet to generate talking points for this account.",
        "nextBestAction": "Next best action",
        "talkingPoints": "Talking points",
        "releaseMatches": "They asked, we shipped",
        "draftEmail": "Draft email",
        "draftCaveat": "This is a draft only. Review and send it yourself. Nothing is sent automatically.",
        "copy": "Copy",
        "copied": "Copied to clipboard",
        "copyError": "Couldn't copy to clipboard"
      },
      "pipeline": {
        "title": "Pipeline",
        "subtitle": "Your sales pipeline across accounts.",
        "forecast": "Weighted forecast",
        "openCount": "{count} open deals",
        "mixedCurrency": "Totals span multiple currencies (summed nominally).",
        "excludedDeals": "{count} deal(s) excluded (no FX rate for {currencies}).",
        "newDeal": "New deal",
        "newDealDesc": "Add a deal and choose its starting stage.",
        "createDeal": "Create deal",
        "cancel": "Cancel",
        "close": "Close",
        "closeDeal": "Close deal",
        "closeDealDesc": "Mark this deal won or lost and record the reason.",
        "confirmClose": "Confirm close",
        "won": "Won",
        "lost": "Lost",
        "reason": "Reason",
        "reasonPlaceholder": "Why was this deal won or lost?",
        "dealTitle": "Deal name",
        "dealTitlePlaceholder": "e.g. Pro plan upgrade",
        "value": "Value",
        "currency": "Currency",
        "startingStage": "Starting stage",
        "moveTo": "Move to…",
        "flagBlocker": "Flag blocker",
        "editBlocker": "Edit blocker",
        "clearBlocker": "Clear",
        "saveBlocker": "Save",
        "blockerTitle": "Deal blocker",
        "blockerDesc": "Note what's blocking this deal so the team can follow up.",
        "blockerLabel": "What's blocking this deal?",
        "blockerPlaceholder": "e.g. Waiting on legal review",
        "blockerSaved": "Blocker updated",
        "blockerError": "Couldn't update the blocker. Please try again.",
        "dealCreated": "Deal created",
        "createError": "Couldn't create the deal. Please try again.",
        "dealClosed": "Deal closed",
        "closeError": "Couldn't close the deal. Please try again.",
        "moveError": "Couldn't move the deal. Please try again.",
        "emptyTitle": "No deals yet",
        "emptyBody": "Create your first deal to start tracking your pipeline.",
        "accountLabel": "Account",
        "accountLoading": "Loading accounts…",
        "accountNone": "No accounts in scope",
        "scope": {
          "mine": "Mine",
          "team": "Team",
          "all": "All"
        },
        "stages": {
          "interest": "Interest",
          "qualified": "Qualified",
          "technical_eval": "Technical eval",
          "business_eval": "Business eval",
          "closed": "Closed"
        }
      },
      "tasks": {
        "title": "Tasks",
        "subtitle": "Suggested and manual tasks for an account.",
        "suggestedTitle": "Suggested",
        "manualTitle": "Manual",
        "accept": "Accept",
        "dismiss": "Dismiss",
        "dismissError": "Couldn't dismiss the suggestion. Please try again.",
        "accepted": "Task added",
        "acceptError": "Couldn't accept the suggestion. Please try again.",
        "noSuggestions": "No suggestions right now.",
        "noSignals": "Not enough signal yet to suggest tasks.",
        "noTasks": "No open tasks.",
        "add": "Add",
        "addPlaceholder": "Add a task…",
        "taskAdded": "Task added",
        "addError": "Couldn't add the task. Please try again.",
        "complete": "Complete",
        "completeError": "Couldn't complete the task. Please try again.",
        "noAccountTitle": "Select an account",
        "noAccountBody": "Choose an account to see its tasks.",
        "accountLabel": "Account",
        "severity": {
          "info": "Info",
          "warning": "Warning",
          "critical": "Critical"
        }
      },
      "playbooks": {
        "title": "Playbooks",
        "subtitle": "Sales plays you can run on an account.",
        "suggested": "Suggested",
        "openPlay": "Open play",
        "opened": "Added {count} tasks",
        "openError": "Couldn't open the play. Please try again.",
        "confirmBody": "This creates {count} tasks on {account} and opens a draft email for you to review.",
        "confirmStepsLabel": "Tasks that will be created",
        "confirmDraftNote": "A draft email opens next for you to review. Groot never sends it for you.",
        "apply": "Add {count} tasks",
        "applying": "Adding…",
        "cancel": "Cancel",
        "thisAccount": "this account",
        "stepsCount": "{count} steps",
        "draftTitle": "Draft email",
        "draftNote": "Review and send this yourself. Groot never sends it for you.",
        "emailSubject": "Subject",
        "emailBody": "Body",
        "copyEmail": "Copy email",
        "copied": "Copied to clipboard",
        "copyError": "Couldn't copy. Select the text to copy it.",
        "done": "Done",
        "noAccountTitle": "Select an account",
        "noAccountBody": "Choose an account to see its plays.",
        "accountLabel": "Account",
        "plays": {
          "expansion": {
            "label": "Expansion",
            "description": "A healthy account is bumping a plan limit. Start an upgrade conversation."
          },
          "trial_rescue": {
            "label": "Trial rescue",
            "description": "A trial is ending. Help them reach value before it lapses."
          },
          "activation": {
            "label": "Activation",
            "description": "This account is new. Guide them to their first win."
          },
          "ask_shipped": {
            "label": "Your ask shipped",
            "description": "A feature they wanted is live. Tell them and invite feedback."
          },
          "blocker_recovery": {
            "label": "Blocker recovery",
            "description": "This account has gone quiet. Check in and clear the blocker."
          }
        }
      },
      "staffRoles": {
        "title": "Staff Roles",
        "subtitle": "Elevate or demote platform staff and manage which staffer owns each customer account. Super Admin only.",
        "superOnly": "Only a Super Admin can manage staff roles and account assignments.",
        "roleManagement": {
          "roleInfo": {
            "heading": "Role capabilities",
            "sales": "manage assigned accounts only (CRM notes, tasks, deals, meetings). No access to other accounts.",
            "support": "read any account and reproduce issues via read-only view-as. No CRM writes, no product analytics, no config.",
            "product": "read any account plus product/usage analytics. View-as is just-in-time (requested per incident), not standing.",
            "engineering": "all accounts, plus product analytics, view-as, feature toggles, business config, and trial bundles.",
            "super": "everything, plus assign accounts, manage staff roles, and platform config. Sees all accounts.",
            "note": "Sales, Support and Product are distinct roles, not tiers. Sales sees only assigned accounts; Support/Product/Engineering/Super see all accounts (read).",
            "noDelete": "No staff role can ever delete or edit customer financial data. View-as is strictly read-only."
          },
          "title": "Role management",
          "subtitle": "Change a staffer's role tier. Every change is recorded in the staff audit log.",
          "columnStaff": "Staff member",
          "columnRole": "Role",
          "columnEngineering": "Engineering",
          "loading": "Loading staff…",
          "empty": "No platform staff found.",
          "roleFor": "Change role for {name}",
          "you": "You",
          "lastSuperNote": "This is the last Super Admin. Promote another staffer to Super before changing this role.",
          "lastSuperBlocked": "Can't demote the last Super Admin. There must always be at least one.",
          "changed": "Role updated to {role}.",
          "changeError": "Couldn't update the role. Please try again."
        },
        "engineeringLens": {
          "heading": "Engineering lens",
          "description": "Grants the DSPy / product-internals dashboards (view_dspy_metrics), independent of the CRM role. Turn on for engineers who watch the self-improvement flywheel.",
          "superNote": "Super Admin holds this automatically.",
          "toggleFor": "Toggle the engineering lens for {name}",
          "on": "On",
          "off": "Off",
          "superImplicit": "Included with Super Admin",
          "granted": "Engineering lens granted.",
          "revoked": "Engineering lens revoked.",
          "error": "Couldn't update the engineering lens. Please try again."
        },
        "assignments": {
          "title": "Account assignments",
          "subtitle": "Assign a staffer to a customer account. Assignments drive account visibility and are audited.",
          "staffLabel": "Staff member",
          "staffPlaceholder": "Select a staff member…",
          "staffNone": "No platform staff available.",
          "pickStaff": "Pick a staff member to view and manage their account assignments.",
          "accountLabel": "Customer account",
          "typeLabel": "Assignment type",
          "assign": "Assign",
          "unassign": "Remove",
          "currentTitle": "Current assignments",
          "automatic": "Added automatically",
          "loading": "Loading assignments…",
          "empty": "No accounts assigned yet.",
          "assigned": "Account assigned.",
          "assignError": "Couldn't assign the account. Please try again.",
          "alreadyAssigned": "Already assigned to this account.",
          "removed": "Assignment removed.",
          "removeError": "Couldn't remove the assignment. Please try again.",
          "type": {
            "account_manager": "Account manager",
            "support": "Support",
            "collaborator": "Collaborator"
          }
        }
      },
      "meetingCapture": {
        "title": "Meeting capture",
        "subtitle": "Log a call from any source. We summarise it and add it to this account's timeline and deal. Nothing is sent to the customer.",
        "cancel": "Cancel",
        "followUpLabel": "Follow-up task (optional)",
        "followUpPlaceholder": "e.g. Send pricing follow-up",
        "followUpHint": "Seeds a reminder task for you. It is never sent to the customer.",
        "connectHint": "Connect this source to enable it.",
        "sources": {
          "checkIn": "Log check-in",
          "paste": "Paste transcript",
          "upload": "Upload recording",
          "connectMeet": "Connect Meet-Drive",
          "meetConnected": "Import from Meet",
          "connectGranola": "Connect Granola",
          "granola": "Import from Granola"
        },
        "sourceLabel": {
          "google_meet": "Google Meet",
          "upload": "Upload",
          "granola": "Granola",
          "paste": "Paste"
        },
        "quality": {
          "reAnalysable": "Re-analysable",
          "summaryOnly": "Summary-only"
        },
        "transcription": {
          "pending": "Transcription pending",
          "failed": "Transcription failed"
        },
        "planWarning": {
          "title": "Google Meet recording needs a paid plan",
          "body": "Meet auto-recording requires {minPlan} or higher, so Business Starter cannot record. Upload, Granola, and paste work on any plan.",
          "learnMore": "Learn more"
        },
        "checkIn": {
          "title": "Log a check-in",
          "description": "Record a quick note from a call or touchpoint. Your notes are the summary. No AI is used.",
          "titleLabel": "Title",
          "titlePlaceholder": "e.g. Onboarding call",
          "notesLabel": "Notes",
          "notesPlaceholder": "What was discussed, decisions, next steps…",
          "save": "Log check-in",
          "saved": "Check-in logged.",
          "saveError": "Could not log the check-in. Please try again."
        },
        "paste": {
          "title": "Paste a transcript",
          "description": "Paste a transcript or your notes; we summarise them into a sales activity.",
          "titleLabel": "Title (optional)",
          "titlePlaceholder": "e.g. Discovery call",
          "transcriptLabel": "Transcript or notes",
          "transcriptPlaceholder": "Paste the meeting transcript or your raw notes here…",
          "save": "Summarise & log",
          "savedLlm": "Meeting summarised and logged.",
          "savedManual": "Notes logged (AI summariser not configured, so your notes were kept verbatim).",
          "saveError": "Could not summarise the transcript. Please try again.",
          "noLlmNote": "The AI summariser isn't configured, so your notes will be logged verbatim. Nothing will be invented."
        },
        "upload": {
          "title": "Upload a recording",
          "description": "Drop an audio or video file. We keep your copy so analysis can be re-run later.",
          "titleLabel": "Title",
          "titlePlaceholder": "e.g. Renewal call",
          "fileLabel": "Recording",
          "choose": "Choose an audio or video file",
          "save": "Upload & process",
          "savedComplete": "Recording transcribed, summarised and logged.",
          "savedPending": "Recording stored. Transcription is pending. The raw file is kept so it can be processed later.",
          "saveError": "Could not upload the recording. Please try again.",
          "pendingNote": "Transcription isn't configured yet, so the recording will be stored with a 'transcription pending' status. The raw file is kept and re-analysable once transcription is enabled. No transcript is invented."
        },
        "granola": {
          "title": "Import from Granola",
          "description": "Import a meeting summary from Granola. Granola summaries are stored as-is (summary-only).",
          "docIdLabel": "Granola document ID",
          "docIdPlaceholder": "Paste the Granola meeting ID",
          "summaryOnlyNote": "Granola provides the summary. We don't keep a re-analysable raw recording (summary-only).",
          "import": "Import",
          "imported": "Granola meeting imported.",
          "importError": "Could not import the Granola meeting. Please try again.",
          "connectRequired": "Granola isn't connected. Add a Granola API key to enable import.",
          "notConnectedTitle": "Granola isn't connected",
          "notConnectedBody": "Connect Granola with an API key to import meeting summaries. Until it's connected, no meetings can be imported.",
          "pickNoteLabel": "Pick a recent Granola note",
          "loadingNotes": "Loading your recent Granola notes…",
          "noNotes": "No recent Granola notes found. Enter a note ID below."
        },
        "feed": {
          "emptyTitle": "No meetings captured yet",
          "emptyBody": "Log a check-in, paste a transcript, upload a recording, or connect Meet/Granola to start building this account's activity timeline.",
          "followUpSeeded": "Follow-up task created"
        }
      },
      "viewAs": {
        "startTitle": "View customer screens (read-only)",
        "startDescription": "Start a time-boxed, read-only view-as session. Writes are blocked; credentials and payment methods are masked; every action is audited.",
        "reasonLabel": "Reason (required)",
        "reasonPlaceholder": "e.g. Reproduce the receipt OCR error the customer reported",
        "modeLabel": "Mode",
        "modeRoutine": "Routine (customer must approve first)",
        "modeBreakGlass": "Break-glass emergency (customer notified after)",
        "justificationLabel": "Break-glass justification (required)",
        "justificationPlaceholder": "Why this cannot wait for consent",
        "durationLabel": "Time limit (minutes)",
        "start": "Start session",
        "starting": "Starting…",
        "startError": "Couldn't start the session. Please try again.",
        "requestedTitle": "Waiting for customer approval",
        "requestedBody": "The customer has been asked to approve read-only access. The session begins only after they grant it.",
        "banner": "Viewing as {name} in read-only mode, ending in {time}",
        "bannerExpired": "View-as session ended",
        "bannerReadOnly": "Read-only",
        "end": "End session",
        "ending": "Ending…",
        "endError": "Couldn't end the session. Please try again.",
        "maskedCredential": "Masked in view-as"
      },
      "accountControls": {
        "backToAdmin": "Back to admin",
        "untitledAccount": "Account",
        "scopeNotice": "These controls stay in Groot Finance. Billing and trial commands moved to the CRM app. Every action here is capability-gated and written to the staff audit log.",
        "billingMoved": "Looking for plan, subscription or manual activation? Those moved to the CRM app's Billing section on this account.",
        "viewAs": {
          "title": "View as customer",
          "description": "Start an audited, read-only session to reproduce what this customer sees. Requires a reason, and routine sessions wait for customer approval.",
          "noCapability": "Your staff role cannot start a view-as session. This needs the start_viewas capability."
        },
        "trialBundle": {
          "title": "Trial bundle",
          "description": "Grant this account a time-limited bundle of trial features. The expiry date is shown before you confirm.",
          "noCapability": "Your staff role cannot apply a trial bundle. This needs the apply_trial_bundle capability."
        },
        "setup": {
          "chartTitle": "Chart of accounts",
          "chartDescription": "Import the customer’s own chart. Only possible while the chart is empty and nobody has accepted an invitation; otherwise use Replace below.",
          "profileTitle": "Apply a profile",
          "profileDescription": "Sets features and seeds expense categories. Do this after the chart, or the categories lose their GL codes.",
          "rosterTitle": "Onboard the team",
          "rosterDescription": "Invite up to 100 people at once, with roles and reporting wired up front."
        }
      },
      "provisioning": {
        "title": "Account provisioning",
        "subtitle": "Create a customer account, set what they can see, and onboard their team without waiting for anyone to sign up.",
        "account": "Account",
        "accountPlaceholder": "Select an account",
        "reason": "Reason",
        "reasonPlaceholder": "Why is this account being provisioned? (audited)",
        "errorGeneric": "Something went wrong. Please try again.",
        "tenant": {
          "title": "Create the account",
          "subtitle": "Creates the business and seats its owner. The owner stays pending until they accept the invitation.",
          "name": "Business name",
          "namePlaceholder": "Acme Sdn Bhd",
          "slug": "Slug",
          "slugHint": "Used in URLs. Filled from the name; a duplicate gets a suffix automatically.",
          "ownerEmail": "Owner email",
          "ownerEmailHint": "This person becomes the account owner when they accept. Nothing is active until then.",
          "country": "Country",
          "homeCurrency": "Home currency",
          "businessType": "Business type",
          "plan": "Plan",
          "planHint": "Recorded as a manual contract, so Stripe cannot overwrite it.",
          "regNumber": "Registration number",
          "regNumberPlaceholder": "SSM / UEN (optional)",
          "taxId": "Tax identification number",
          "taxIdPlaceholder": "LHDN TIN, e.g. C24539313070 (optional)",
          "taxIdHint": "Stored as the LHDN TIN, the field e-invoicing reads. Required before this account can issue e-invoices; the customer can also set it later in Settings.",
          "legalName": "Registered legal name",
          "legalNamePlaceholder": "As registered with SSM / ACRA, if it differs from the name above",
          "legalNameHint": "Used on invoices, statements and every e-invoice. Leave blank when the trading name above is the registered one.",
          "address": "Registered address",
          "addressLine1Placeholder": "Street address, line 1",
          "addressLine2Placeholder": "Building, unit or area (optional)",
          "city": "City",
          "cityPlaceholder": "e.g. Petaling Jaya",
          "postalCode": "Postcode",
          "postalCodePlaceholder": "e.g. 47810",
          "stateCode": "State",
          "stateCodePlaceholder": "Select a state",
          "contactPhone": "Contact number",
          "contactPhonePlaceholder": "e.g. +60123456789",
          "lhdnAddressHint": "A Malaysian account cannot request an e-invoice until the city, postcode and contact number are filled in. You can provision without them and add them later; the account checklist will keep showing them as missing.",
          "deferChart": "The customer is importing their own chart of accounts",
          "deferChartHint": "Skips the starter chart. Category GL codes are dropped so nothing points at accounts this business will never have.",
          "submit": "Create account",
          "submitting": "Creating...",
          "createdTitle": "Account created",
          "createdOwnerPending": "They become the owner once they accept. Invite the rest of the team in step 3.",
          "createdInviteSent": "Invitation sent to",
          "createdInviteFailed": "The invitation email did not send. Share this link with the owner instead:",
          "accountOwner": "Groot account owner",
          "accountOwnerSelf": "Me",
          "accountOwnerHint": "The staff member who owns this relationship. It sets visibility scope and where tickets route. It is not a seat on the customer team and grants no extra access to their data.",
          "chartTitle": "Import their chart of accounts",
          "chartHint": "Upload the customer’s chart now, while nobody has signed in yet. Needs a code column, a name column, and a type column. Codes that are not plain numbers cannot have their type guessed, so those rows need one.",
          "chartChoose": "Choose file",
          "chartRead": "Accounts read:",
          "chartNoType": "Rows with no account type, which will be refused:",
          "chartImport": "Import chart",
          "chartImported": "Chart imported. Accounts created:",
          "chartNoRows": "No accounts could be read from that file.",
          "chartParseFailed": "That file could not be read. Try CSV, XLSX or XLS.",
          "chartTemplate": "Download template",
          "diagnose": {
            "noRows": "We could not read any accounts from that file. Check that it has a row per account, with a code and a name.",
            "noTypeColumn": "That file has no Type column, or it is empty on every row. Every account needs a type (Asset, Liability, Equity, Income or Expense) because a code like 90A-S200 cannot tell us on its own. Download the template, copy your accounts in, and fill the Type column.",
            "someRowsMissingType": "{missing} of {rowCount} rows have no type. Those rows will be skipped. Fill in the Type column for them (Asset, Liability, Equity, Income or Expense).",
            "reservedCodeShape": "Codes like {codes} use a format reserved for Groot’s own accounts and will be refused. Use your own numbering instead, for example 5100 rather than 5100-0001.",
            "duplicateCodes": "The same code appears more than once ({codes}). This usually means the wrong column was read as the account code. Check the file against the template."
          },
          "chartFixWithTemplate": "Download the template"
        },
        "profile": {
          "title": "Set what they can see",
          "subtitle": "Apply a named profile to turn features on and off for this account. Changes are permanent and never expire.",
          "profile": "Profile",
          "profilePlaceholder": "Select a profile",
          "emptyTitle": "No profiles yet",
          "emptyDesc": "An engineer needs to create a provisioning profile before one can be applied.",
          "willEnable": "Turns on",
          "willDisable": "Turns off",
          "basePlanNote": "Assumes plan:",
          "seedsCategories": "Seeds expense categories:",
          "submit": "Apply profile",
          "submitting": "Applying...",
          "applied": "Profile applied.",
          "resultCategories": "Categories added:",
          "resultSkipped": "already present:",
          "planMismatch": "This account is not on the plan the profile assumes. The features were applied, but check the plan if something looks missing.",
          "glCodesDropped": "Categories seeded without a GL code:",
          "glCodesDroppedHint": "Their codes name no account in this business chart, so they will post to the fallback account. Import the chart first, then apply the profile again.",
          "manageLink": "Manage account profiles"
        },
        "errors": {
          "reasonRequired": "Add a short reason before submitting. It is recorded in the audit log.",
          "nameRequired": "A business name is required.",
          "ownerEmailInvalid": "Enter a valid owner email address.",
          "ownerCreateFailed": "Could not create the owner record. Nothing was saved.",
          "profileNotFound": "That profile is no longer available. Pick another.",
          "unknownFeature": "This profile names a feature that no longer exists. An engineer needs to fix it.",
          "notAssignableStaff": "That account owner is not an active staff member. Pick someone else.",
          "chartNotEmpty": "That business already has accounts, so the owner imports from Accounting.",
          "tenantInUse": "Somebody has accepted their invitation, so the chart is theirs to import.",
          "chartImportEmpty": "No accounts could be read from that file.",
          "tooManyAccounts": "That file has too many accounts for one import.",
          "tinInUse": "Another business already holds that tax ID (TIN). Nothing was created."
        },
        "createdAndInvited": "Account created and the owner has been invited.",
        "createdInviteFailed": "Account created, but the invitation email did not send.",
        "builder": {
          "title": "Manage profiles",
          "subtitle": "Create and edit the profiles step 2 applies. A profile decides which features an account gets and which expense categories it starts with.",
          "editExisting": "Profile to edit",
          "newProfile": "Create a new profile",
          "loading": "Loading the full profile...",
          "key": "Key",
          "keyHint": "Stable id used in audit records. It cannot be changed once the profile exists.",
          "label": "Name",
          "description": "Description",
          "basePlan": "Assumed plan",
          "basePlanHint": "Recorded so the apply step can warn when an account is on a different plan. Applying a profile does not change billing.",
          "features": "Features",
          "featuresHint": "Turn a feature on, force it off, or leave it alone. Only features staff are allowed to set are listed.",
          "stanceOn": "on",
          "stanceOff": "off",
          "stanceNone": "leave alone",
          "categories": "Expense categories",
          "categoriesHint": "One per line. Paste two columns in either order and the GL code is detected automatically, or paste names alone when the chart is not ready. Codes are checked against the account's own chart when the profile is applied.",
          "categoriesParsed": "Categories read:",
          "nothingSet": "This profile changes no features yet. Turn at least one on or off before saving.",
          "create": "Create profile",
          "save": "Save changes",
          "deactivate": "Deactivate",
          "created": "Profile created.",
          "updated": "Profile updated.",
          "deactivated": "Profile deactivated. Accounts it was already applied to keep the features they have.",
          "errors": {
            "invalidArgument": "Check the key and the name. Both are required.",
            "emptyProfile": "A profile has to turn at least one feature on or off.",
            "notToggleable": "That feature is not one a profile is allowed to set.",
            "conflicting": "A feature cannot be both on and off.",
            "tooManyCategories": "Too many categories. A profile is capped at 100."
          }
        },
        "replace": {
          "title": "Replace their chart of accounts",
          "subtitle": "For an account somebody is already using. One person proposes, a different super approves. Accounts that carry postings, are referenced, or the customer edited are refused however many people approve.",
          "justification": "Why this is needed",
          "confirmName": "Type the business name to confirm",
          "propose": "Propose replacement",
          "proposed": "Proposed. A different super has to approve it.",
          "pendingBy": "Proposed by",
          "approve": "Approve and run",
          "reject": "Reject",
          "needsAnother": "Waiting on a different super. You cannot approve your own proposal.",
          "executed": "Chart replace executed.",
          "rejected": "Proposal rejected.",
          "noneRefused": "Every account in the file was applied.",
          "refusedTitle": "Accounts the planner refused:"
        }
      },
      "tenantDeletion": {
        "title": "Delete this account",
        "subtitle": "Deleting a customer account needs two people. You propose it with a reason, and a different super approves.",
        "superOnly": "Only a super can propose or approve an account deletion.",
        "justification": "Reason",
        "justificationPlaceholder": "Why should this account be deleted? (recorded)",
        "confirmName": "Type the account name to confirm",
        "confirmNameHint": "Must match the account name exactly. This is what catches a proposal aimed at the wrong tenant.",
        "propose": "Propose deletion",
        "proposed": "Deletion proposed. A different super must approve it.",
        "pendingTitle": "Deletion pending approval",
        "proposedBy": "Proposed by",
        "approve": "Approve and delete",
        "reject": "Reject",
        "approved": "Account deleted.",
        "rejected": "Proposal rejected.",
        "needsAnotherSuper": "You proposed this, so another super has to approve it.",
        "softDeleteNote": "This is a soft delete. The account row is kept for data integrity, its name and emails are anonymised, and a retention window applies. The name and slug are not freed for reuse.",
        "errorGeneric": "Something went wrong. Please try again.",
        "errors": {
          "invalidArgument": "Check the reason and the account name, then try again.",
          "actionMismatch": "That proposal is for a different action. Refresh and try again.",
          "selfApproval": "You proposed this one, so another super has to approve it.",
          "expired": "That proposal has expired. Propose it again.",
          "hasBooks": "This account holds financial records, so the law requires them to be kept. Use the two-person deletion above instead.",
          "inUse": "Someone has accepted an invitation to this account, so it cannot be purged. Use the two-person deletion above.",
          "nameMismatch": "The account name does not match. Check it and try again."
        },
        "purged": "Tenant purged. It kept no books, so nothing was retained.",
        "purgeEmptyTitle": "Or: purge permanently (empty tenants only)",
        "purgeEmptyHint": "One person, no approval, but only if this account never kept any books. It is refused if any financial record or accepted member exists. Use it for abandoned test tenants.",
        "purgeEmpty": "Purge permanently"
      },
      "accountReadiness": {
        "title": "Account readiness",
        "allClear": "Nothing outstanding.",
        "outstanding": "{count} item(s) need attention.",
        "identity": {
          "label": "Business identity",
          "ok": "Registration number, TIN, legal name and address are all set.",
          "missing": "Missing: {fields}"
        },
        "chart": {
          "label": "Chart of accounts",
          "ok": "{count} active accounts.",
          "empty": "No accounts yet. Import their chart before applying a profile."
        },
        "categories": {
          "label": "Expense categories",
          "ok": "{count} categories, all bound to a real account.",
          "none": "None yet. Apply a profile, or toggle Claims on the chart.",
          "blocked": "Waiting on the chart: a category only keeps its GL code if the account exists.",
          "dead": "{count} categories point at an account this chart does not have. They will post to the fallback account."
        },
        "team": {
          "label": "Team",
          "ok": "{active} active.",
          "somePending": "{active} active, {pending} still to accept.",
          "ownerPending": "The owner has not accepted yet ({pending} invitation(s) outstanding)."
        },
        "features": {
          "label": "Features",
          "none": "No overrides, so the plan baseline applies.",
          "some": "{count} feature override(s) set."
        },
        "books": {
          "label": "Books",
          "none": "No postings yet, so the chart can still be replaced freely.",
          "has": "This tenant has postings. A chart replace will refuse any account that carries them."
        }
      }
    }
  },
  "x_applocale_7": {
    "customersTitle": "Customers",
    "recurringInvoicesTitle": "Recurring Invoices",
    "createInvoiceTitle": "Create Invoice",
    "invoiceDetailsTitle": "Invoice Details",
    "invoiceSettingsTitle": "Invoice Settings"
  },
  "x_applocale_8": {
    "newJournalEntryTitle": "New Journal Entry",
    "approvalDetailsTitle": "Approval Details",
    "submissionDetailsTitle": "Submission Details",
    "customerDetailsTitle": "Customer Details",
    "editInvoiceTitle": "Edit Invoice"
  },
  "x_applocale_9": {
    "recordPaymentTitle": "Record Payment",
    "statementTitle": "Statement"
  },
  "x_components_0": {
    "errorBoundary": {
      "title": "Something went wrong",
      "unexpectedError": "An unexpected error occurred",
      "tryAgain": "Try Again"
    },
    "missingCurrencyBanner": {
      "prefix": "Your business currency is not set.",
      "linkText": "Set it in Business Settings",
      "suffix": "to ensure accurate financial reporting.",
      "dismiss": "Dismiss"
    },
    "consentLockOverlay": {
      "title": "Consent Required",
      "prefix": "Please review and accept our",
      "privacyPolicy": "Privacy Policy",
      "suffix": "to continue using Groot Finance.",
      "accepting": "Accepting...",
      "acceptFailed": "We could not record your consent. Please check your connection and try again.",
      "acceptButton": "Accept Privacy Policy",
      "signOut": "Sign Out"
    }
  },
  "x_components_1": {
    "unsavedChanges": {
      "defaultMessage": "You have unsaved changes. Are you sure you want to leave?",
      "title": "Unsaved Changes",
      "leave": "Leave",
      "stay": "Stay"
    },
    "forceUpdate": {
      "title": "Update Required",
      "description": "A critical update is required. Please update to continue using Groot Finance.",
      "currentVersion": "Current version: {version}",
      "updateNow": "Update Now"
    },
    "softUpdate": {
      "description": "A new version of Groot Finance is available.",
      "dismiss": "Dismiss",
      "refreshNow": "Refresh now",
      "update": "Update"
    },
    "pwaInstall": {
      "dismiss": "Dismiss",
      "ios": {
        "title": "Get the Groot Finance App",
        "description": "Download from the App Store for the best experience",
        "download": "Download"
      },
      "android": {
        "title": "Install Groot Finance",
        "description": "Add to your home screen for quick access",
        "install": "Install",
        "installing": "Installing..."
      }
    },
    "staleData": {
      "title": "Data may be outdated",
      "lastRefreshed": "Last refreshed {age}. Connect to the internet to get the latest data.",
      "daysAgo": "{count, plural, one {# day ago} other {# days ago}}",
      "hoursAgo": "{count, plural, one {# hour ago} other {# hours ago}}",
      "recently": "recently",
      "aWhile": "a while",
      "refresh": "Refresh data",
      "dismiss": "Dismiss warning"
    }
  },
  "x_components_2": {
    "invitationDialog": {
      "title": "Invite Team Member",
      "errors": {
        "emailRequired": "Email is required",
        "emailInvalid": "Please enter a valid email address",
        "roleRequired": "Role is required"
      },
      "fields": {
        "emailLabel": "Email Address *",
        "roleLabel": "Role *",
        "employeeIdLabel": "Employee ID",
        "departmentLabel": "Department",
        "jobTitleLabel": "Job Title",
        "optionalPlaceholder": "Optional"
      },
      "roles": {
        "employee": "Employee",
        "manager": "Manager"
      },
      "actions": {
        "cancel": "Cancel",
        "sending": "Sending...",
        "sendInvitation": "Send Invitation"
      }
    },
    "noBusinessFallback": {
      "title": "No Business Access",
      "description": "You currently don't have access to any business accounts. Let's get you connected to start using Groot Finance.",
      "createCard": {
        "heading": "New to Groot Finance?",
        "description": "Create your first business account to get started with our financial co-pilot.",
        "button": "Create New Business"
      },
      "invitedCard": {
        "heading": "Invited by a Business Owner?",
        "description": "Check your email for invitation links or contact your business owner to resend the invitation.",
        "checking": "Checking...",
        "checkButton": "Check for Invitations"
      },
      "helpCard": {
        "heading": "Need Help?",
        "description": "Our support team can help you connect to the right business or set up a new account.",
        "button": "Contact Support"
      },
      "footer": "Once you have business access, you'll be able to manage financial documents, track transactions, and use our AI-powered financial guidance.",
      "support": {
        "emailSubject": "Request Business Access - Groot Finance",
        "emailBody": "Hello Groot Finance Support,\n\nI am unable to access any businesses in my account. Could you please help me:\n\n1. Check if I have pending business invitations\n2. Connect me with the appropriate business owner\n3. Set up a new business account if needed\n\nThank you for your assistance.\n\nBest regards"
      },
      "compact": {
        "label": "No business access",
        "refresh": "Refresh"
      }
    },
    "nativeUserButton": {
      "profileAlt": "Profile",
      "businesses": "Businesses",
      "signingOut": "Signing out...",
      "signOut": "Sign out"
    },
    "nativeSignIn": {
      "title": "Sign in to Groot Finance",
      "subtitle": "Enter your email and password to continue",
      "emailLabel": "Email",
      "emailPlaceholder": "name@company.com",
      "passwordLabel": "Password",
      "passwordPlaceholder": "Enter your password",
      "signInButton": "Sign In",
      "noAccountPrompt": "Don't have an account?",
      "signUpLink": "Sign up",
      "noAccountContactAdmin": "Don't have an account? Contact your organization administrator to get access.",
      "errors": {
        "additionalVerification": "Additional verification required. Please try again.",
        "signInFailed": "Sign in failed. Please check your credentials."
      }
    },
    "nativeSignUp": {
      "title": "Create Your Account",
      "subtitle": "Get started with Groot Finance",
      "firstNameLabel": "First Name",
      "firstNamePlaceholder": "First",
      "lastNameLabel": "Last Name",
      "lastNamePlaceholder": "Last",
      "emailLabel": "Email",
      "emailPlaceholder": "name@company.com",
      "passwordLabel": "Password",
      "passwordPlaceholder": "Create a password",
      "createAccountButton": "Create Account",
      "haveAccountPrompt": "Already have an account?",
      "signInLink": "Sign in",
      "verify": {
        "title": "Verify Your Email",
        "subtitle": "Enter the verification code sent to {email}",
        "codeLabel": "Verification Code",
        "codePlaceholder": "Enter code",
        "verifyButton": "Verify"
      },
      "errors": {
        "signUpFailed": "Sign up failed. Please try again.",
        "verificationFailedRetry": "Verification failed. Please try again.",
        "verificationFailed": "Verification failed."
      }
    }
  },
  "x_timesheet_0": {
    "durationMinutes": "{mins} min",
    "durationHours": "{hrs, plural, one {# hr} other {# hrs}}",
    "durationHoursMinutes": "{hrs, plural, one {# hr} other {# hrs}} {mins} min",
    "loadingAttendance": "Loading attendance...",
    "notCheckedIn": "Not checked in",
    "startWorkDay": "Start your work day",
    "checkIn": "Check In",
    "checkOut": "Check Out",
    "checkedInAt": "Checked in at {time}",
    "workingFor": "Working for {duration}",
    "checkedOut": "Checked out",
    "checkedInSuccess": "Checked in successfully",
    "checkInFailed": "Failed to check in",
    "checkedOutSuccess": "Checked out successfully",
    "checkOutFailed": "Failed to check out",
    "loadingPendingTimesheets": "Loading pending timesheets...",
    "allCaughtUp": "All Caught Up!",
    "noPendingTimesheets": "No pending timesheets to review.",
    "pendingReview": "Pending Review",
    "pendingTimesheetApprovals": "Pending Timesheet Approvals",
    "reviewTimesheetsDescription": "Review timesheets with anomalies and approve or reject them",
    "unknownEmployee": "Unknown Employee",
    "overtimeBadge": "+{value} OT",
    "issueCount": "{count, plural, one {# issue} other {# issues}}",
    "regularLabel": "Regular: {value}",
    "otLabel": "OT: {value}",
    "anomalies": "Anomalies",
    "flaggedDays": "Flagged Days",
    "thDate": "Date",
    "thIn": "In",
    "thOut": "Out",
    "thRegular": "Regular",
    "thOT": "OT",
    "thFlags": "Flags",
    "notesReason": "Notes / Reason",
    "notesPlaceholder": "Add notes (optional for approve, required for reject)",
    "approving": "Approving...",
    "approve": "Approve",
    "rejecting": "Rejecting...",
    "reject": "Reject",
    "loadingTimesheet": "Loading timesheet...",
    "back": "Back",
    "failedToLoadTimesheet": "Failed to load timesheet.",
    "failedToConfirmTimesheet": "Failed to confirm timesheet.",
    "failedToApproveTimesheet": "Could not approve this timesheet. Please try again in a moment.",
    "failedToRejectTimesheet": "Could not reject this timesheet. Please try again in a moment.",
    "errorNoLongerPendingReview": "This timesheet is no longer awaiting review. Refresh the page to see its latest status.",
    "timesheetTitle": "Timesheet: {start} to {end}",
    "daysCount": "{count} days",
    "statusDraft": "Draft",
    "statusConfirmed": "Confirmed",
    "statusApproved": "Approved",
    "statusFinalized": "Finalized",
    "statusLocked": "Locked",
    "dayTypeWorkday": "Workday",
    "dayTypeRestDay": "Rest Day",
    "dayTypeHoliday": "Holiday",
    "dayTypeLeave": "Leave",
    "attendancePresent": "Present",
    "attendanceLate": "Late",
    "attendanceEarlyDeparture": "Early Departure",
    "attendanceAbsent": "Absent",
    "attendanceRestDay": "Rest Day",
    "attendanceHoliday": "Holiday",
    "attendanceLeave": "Leave",
    "regularHours": "Regular Hours",
    "overtimeHours": "Overtime Hours",
    "deductions": "Deductions",
    "netPayable": "Net Payable",
    "anomaliesDetected": "Anomalies Detected",
    "anomaliesDescription": "The following issues were found and may require review before confirmation.",
    "dailyEntries": "Daily Entries",
    "thDayType": "Day Type",
    "thCheckIn": "Check In",
    "thCheckOut": "Check Out",
    "thStatus": "Status",
    "noDailyEntries": "No daily entries recorded.",
    "overtimeByTier": "Overtime by Tier",
    "thTier": "Tier",
    "thMultiplier": "Multiplier",
    "thHours": "Hours",
    "multiplierValue": "{value}x",
    "leaveSummary": "Leave Summary",
    "dayCount": "{count, plural, one {# day} other {# days}}",
    "reviewAndConfirm": "Review the entries above and confirm when ready.",
    "confirming": "Confirming...",
    "confirmTimesheet": "Confirm Timesheet",
    "applicableWeekdayOt": "Weekday OT",
    "applicableRestDay": "Rest Day",
    "applicablePublicHoliday": "Public Holiday",
    "effectiveRuleBadge": "Applied to timesheets",
    "effectiveRuleHint": "Timesheets use the rule linked to an employee work schedule. When there is none, the rule marked below applies.",
    "fallbackRatesHint": "Until you add a rule, overtime is recorded at these built in rates:",
    "scheduleOvertimeRuleLabel": "OT rule: {name}",
    "tierValidationHint": "Every tier needs a label and a rate above 0.",
    "toastScheduleUpdated": "Work schedule updated",
    "toastScheduleCreated": "Work schedule created",
    "toastScheduleSaveFailed": "Failed to save work schedule",
    "toastScheduleDeleted": "Work schedule deleted",
    "toastScheduleDeleteFailed": "Failed to delete work schedule",
    "toastOtRuleUpdated": "Overtime rule updated",
    "toastOtRuleCreated": "Overtime rule created",
    "toastOtRuleSaveFailed": "Failed to save overtime rule",
    "toastOtRuleDeleted": "Overtime rule deleted",
    "toastOtRuleDeleteFailed": "Failed to delete overtime rule",
    "toastPayPeriodSaved": "Pay period saved",
    "toastPayPeriodSaveFailed": "Failed to save pay period",
    "toastTrackingEnabled": "Tracking enabled for {name}",
    "toastTrackingDisabled": "Tracking disabled for {name}",
    "toastTrackingFailed": "Failed to update tracking",
    "selectBusinessPrompt": "Please select a business to configure timesheet settings.",
    "settingsTitle": "Timesheet & Attendance Settings",
    "settingsSubtitle": "Configure work schedules, overtime rules, and pay periods for your organization",
    "employeeTracking": "Employee Tracking",
    "employeeTrackingDescription": "Enable attendance tracking for team members. Only tracked employees can check in/out.",
    "loadingTeamMembers": "Loading team members...",
    "noActiveMembers": "No active team members found",
    "tracked": "Tracked",
    "notTracked": "Not tracked",
    "workSchedules": "Work Schedules",
    "workSchedulesDescription": "Define working hours, break times, and work days",
    "addSchedule": "Add Schedule",
    "loadingSchedules": "Loading schedules...",
    "noSchedules": "No work schedules configured",
    "noSchedulesHint": "Add a schedule to define working hours for your team",
    "default": "Default",
    "breakLabel": "Break: {minutes}min",
    "graceLabel": "Grace: {minutes}min",
    "overtimeRules": "Overtime Rules",
    "overtimeRulesDescription": "Configure overtime calculation and rate tiers",
    "addRule": "Add Rule",
    "loadingOvertimeRules": "Loading overtime rules...",
    "noOvertimeRules": "No overtime rules configured",
    "noOvertimeRulesHint": "Add a rule to define how overtime is calculated and paid",
    "noOvertimeRulesHintUnpaid": "Add a rule to define how overtime hours are measured. These hours are recorded for reporting.",
    "overtimeNotPaidNotice": "Overtime is not included in payroll. These rates describe how hours are measured and reported.",
    "payImpact": "Pay impact",
    "payImpactDescription": "Decide whether timesheet hours change payroll",
    "loadingPayImpact": "Loading pay impact settings...",
    "payOvertimeLabel": "Pay overtime",
    "payOvertimeOn": "Payroll prices overtime hours with the rate tiers on this page and adds them to pay.",
    "payOvertimeOff": "Overtime hours are recorded and reported. Payroll does not change because of them.",
    "attendanceDeductionsLabel": "Deduct attendance shortfalls",
    "attendanceDeductionsOn": "Payroll subtracts recorded lateness and early departure from wages.",
    "attendanceDeductionsOff": "Lateness and early departure are recorded and reported. Payroll does not change because of them.",
    "attendanceDeductionsCaution": "Deductions from wages are restricted by law and may need the employee's written consent. Confirm you are entitled to make them before you turn this on.",
    "payImpactChangedBy": "Last changed by {name} on {date}",
    "payImpactChangedOn": "Last changed on {date}",
    "toastPayImpactSaved": "Pay impact updated",
    "toastPayImpactFailed": "Failed to update pay impact",
    "dailyThresholdLabel": "Overtime after {hours}h a day",
    "preApprovalLabel": "Manager approval: {value}",
    "yes": "Yes",
    "no": "No",
    "rateTierChip": "{label}: {multiplier}x ({applicable})",
    "payPeriod": "Pay Period",
    "payPeriodDescription": "Set payroll frequency and confirmation deadlines",
    "edit": "Edit",
    "configure": "Configure",
    "loadingPayPeriod": "Loading pay period configuration...",
    "payPeriodNotConfigured": "Pay period not configured",
    "payPeriodNotConfiguredHint": "Set up your payroll frequency and confirmation deadlines",
    "frequency": "Frequency",
    "frequency_weekly": "Weekly",
    "frequency_biweekly": "Biweekly",
    "frequency_monthly": "Monthly",
    "startDay": "Start Day",
    "dayValue": "Day {day}",
    "confirmationDeadline": "Confirmation Deadline",
    "daysValue": "{count} days",
    "day_0": "Sun",
    "day_1": "Mon",
    "day_2": "Tue",
    "day_3": "Wed",
    "day_4": "Thu",
    "day_5": "Fri",
    "day_6": "Sat",
    "editWorkSchedule": "Edit Work Schedule",
    "newWorkSchedule": "New Work Schedule",
    "scheduleNameLabel": "Schedule Name *",
    "scheduleNamePlaceholder": "e.g., Standard Office Hours",
    "startTime": "Start Time",
    "endTime": "End Time",
    "workDays": "Work Days",
    "breakMinutesLabel": "Break (minutes)",
    "graceMinutesLabel": "Grace (minutes)",
    "defaultSchedule": "Default schedule",
    "cancel": "Cancel",
    "saving": "Saving...",
    "updateSchedule": "Update Schedule",
    "saveSchedule": "Save Schedule",
    "editOvertimeRule": "Edit Overtime Rule",
    "newOvertimeRule": "New Overtime Rule",
    "ruleNameLabel": "Rule Name *",
    "ruleNamePlaceholder": "e.g., Malaysia Standard OT",
    "dailyThresholdHoursLabel": "Overtime starts after (hours per day)",
    "dailyThresholdPlaceholder": "Work schedule hours",
    "dailyThresholdHelp": "Leave blank to use each employee's work schedule.",
    "dailyThresholdFromSchedule": "Overtime after work schedule hours",
    "requiresPreApproval": "Overtime needs manager approval",
    "rateTiers": "Rate Tiers",
    "addTier": "Add Tier",
    "tierLabel": "Label",
    "tierLabelPlaceholder": "e.g., 1.5x OT",
    "tierRate": "Rate",
    "applicableOn": "Applicable On",
    "updateRule": "Update Rule",
    "saveRule": "Save Rule",
    "editPayPeriod": "Edit Pay Period",
    "configurePayPeriod": "Configure Pay Period",
    "dayOfMonthHint": "Day of month (1-28)",
    "dayOfWeekHint": "Weekday the period starts on",
    "startDayInvalid": "Enter a whole day of the month from 1 to 28.",
    "confirmationDeadlineHint": "Days after period ends to confirm timesheets",
    "savePayPeriod": "Save Pay Period",
    "errorWorkScheduleInUse": "This work schedule is still assigned to employees, so it can't be deleted. Move them to another schedule first.",
    "errorLastActiveWorkSchedule": "This is your only active work schedule, so it can't be deleted. Create the replacement schedule first, then delete this one.",
    "errorPayrollCycleLocked": "Payroll has already been posted on the current pay cycle, so the cut-off can't be moved now. Reverse the affected pay runs first, then save this change.",
    "errorPayrollCycleCheckIncomplete": "We couldn't finish checking this business's posted pay runs, so nothing was changed. Please contact support before changing the pay cycle.",
    "errorAlreadyConfirmed": "This timesheet is no longer a draft, so it cannot be confirmed again. Refresh the page to see its current status.",
    "requiresPreApprovalHelp": "Timesheets with overtime are held for the manager instead of being approved automatically.",
    "addMissedDay": "Add a missed day",
    "anomalyLabel": "Anomaly",
    "anomalySheetNote": "This timesheet has flagged entries, so after you confirm it goes to your manager for approval.",
    "cleanSheetNote": "A timesheet with no flagged entries is approved when you confirm it, with no manager step.",
    "editDay": "Add or correct",
    "errorEntryNotEditable": "A leave day cannot be edited here. Workdays, rest days and holidays can.",
    "errorInvalidTimeRange": "Check out must be after check in, on the same day.",
    "errorPayPeriodNotConfigured": "Set up a pay period in Timesheet settings first.",
    "errorReasonRequired": "Please give a reason for this change.",
    "errorTimeInFuture": "That time has not happened yet.",
    "errorTimesheetExistsForDate": "This day is already on a timesheet. Open the timesheet and correct it there.",
    "errorTimesheetLocked": "This timesheet can no longer be edited. Refresh the page.",
    "generateCurrent": "Generate for this pay period",
    "generateDescription": "Timesheets are built every night for the pay period that just ended. Build them now to start on the current period, or to review the last one.",
    "generateFailed": "Timesheets could not be generated. Please try again.",
    "generatePrevious": "Generate for the last pay period",
    "generateResult": "Created {created}, already there {alreadyThere}",
    "generateTitle": "Generate timesheets",
    "generating": "Generating...",
    "hasAnomaliesTitle": "Has flagged entries",
    "loadingTimesheets": "Loading timesheets...",
    "myTimesheets": "My Timesheets",
    "myTimesheetsDescription": "View your timesheet history and details",
    "noBusinessSelected": "Please select a business to view your timesheets.",
    "noTimesheetsBody": "Your timesheet appears here once your pay period is generated. Your administrator can generate it now.",
    "noTimesheetsBodyAdmin": "Timesheets appear here once a pay period is generated. Use Generate timesheets above to build them now.",
    "noTimesheetsTitle": "No timesheets yet",
    "timeEntryAuditNote": "Your correction is recorded with your reason, so it can be audited.",
    "timeEntryCancel": "Cancel",
    "timeEntryCheckIn": "Check in",
    "timeEntryCheckOut": "Check out",
    "timeEntryDate": "Date",
    "timeEntryFailed": "The time could not be saved. Please try again.",
    "timeEntryReason": "Reason",
    "timeEntryReasonPlaceholder": "Why are you adding or changing this time?",
    "timeEntrySave": "Save",
    "timeEntrySaving": "Saving...",
    "timeEntrySentToManager": "Entries you add or change are sent to your manager.",
    "timeEntryTimeZoneNote": "Times are in {zone}.",
    "timeEntryAppliedBreak": "This correction keeps its {minutes} minute unpaid break, so a later schedule change does not move it.",
    "timeEntryTitleAdd": "Add a missed day",
    "timeEntryTitleEdit": "Correct {date}",
    "trackingNotEnabledBody": "Contact your administrator to enable timesheet and attendance tracking.",
    "trackingNotEnabledTitle": "Attendance tracking is not enabled for your account",
    "trackingNotEnabledOwnTitle": "Your own attendance is not being tracked",
    "trackingNotEnabledOwnBody": "Generating timesheets above is not affected. Attendance tracking is off only for you personally, so there is no check-in or timesheet of your own.",
    "errorPeriodNotEnded": "This pay period has not ended yet, so the timesheet cannot be confirmed.",
    "confirmAfterPeriodEnd": "You can confirm this timesheet after the pay period ends on {date}.",
    "errorTimesheetIncomplete": "A working day on this timesheet has neither attendance nor an absence. Refresh the timesheet and check each day.",
    "anomalyFlags": {
      "missing_checkin": "No check-in recorded",
      "incomplete_session": "Checked in but never checked out",
      "location_flagged": "Checked in away from the work location",
      "manual_edit": "Time edited by hand",
      "ot_requires_approval": "Overtime needs approval",
      "leave_attendance_conflict": "Leave and attendance overlap"
    },
    "errorBusinessMismatch": "This timesheet belongs to a different business than the one shown on this page, or your active business was switched in another window. Nothing was changed. Refresh the page and try again.",
    "editedBy": "Edited by {name}"
  },
  "x_finstmt_0": {
    "generatingReport": "Generating report...",
    "noDataAvailable": "No data available for the selected period",
    "noItems": "No items",
    "balanceSheet": "Balance Sheet",
    "balanceSheetAsOf": "As of {date}",
    "balanceSheetPointInTimeNote": "Point-in-time balances at this date, not movement within a start/end period.",
    "balancedBadge": "A = L + E",
    "unbalancedBadge": "Unbalanced ({amount})",
    "unbalancedWarning": "The accounting equation is not balanced. Assets ({assets}) does not equal Liabilities + Equity ({liabilitiesAndEquity}). Imbalance: {imbalance}.",
    "assets": "ASSETS",
    "currentAssets": "Current Assets",
    "totalCurrentAssets": "Total Current Assets",
    "nonCurrentAssets": "Non-Current Assets",
    "totalNonCurrentAssets": "Total Non-Current Assets",
    "totalAssets": "Total Assets",
    "liabilities": "LIABILITIES",
    "currentLiabilities": "Current Liabilities",
    "totalCurrentLiabilities": "Total Current Liabilities",
    "nonCurrentLiabilities": "Non-Current Liabilities",
    "totalNonCurrentLiabilities": "Total Non-Current Liabilities",
    "totalLiabilities": "Total Liabilities",
    "equity": "EQUITY",
    "retainedEarnings": "Retained Earnings",
    "totalEquity": "Total Equity",
    "totalLiabilitiesAndEquity": "Total Liabilities & Equity",
    "unclassified": "UNCLASSIFIED",
    "totalUnclassified": "Total Unclassified",
    "unclassifiedNote": "Posted balances on accounts whose code or type matches no balance sheet section. They are shown as a net debit and are excluded from the totals above. Re-code these accounts to place them.",
    "trialBalance": "Trial Balance",
    "trialBalanceAsOf": "As of {date}",
    "trialBalanceCumulativeNote": "Cumulative balances up to this date, not movement within a start/end period.",
    "balanced": "Balanced",
    "accountCode": "Account Code",
    "accountName": "Account Name",
    "type": "Type",
    "debitBalance": "Debit Balance",
    "creditBalance": "Credit Balance",
    "total": "TOTAL",
    "cashFlowStatement": "Cash Flow Statement",
    "verified": "Verified",
    "integrityError": "Integrity Error",
    "openingBalance": "Opening Balance",
    "operatingActivities": "Operating Activities",
    "totalOperatingActivities": "Total Operating Activities",
    "investingActivities": "Investing Activities",
    "totalInvestingActivities": "Total Investing Activities",
    "financingActivities": "Financing Activities",
    "totalFinancingActivities": "Total Financing Activities",
    "netChangeInCash": "Net Change in Cash",
    "closingBalance": "Closing Balance",
    "profitLossStatement": "Profit & Loss Statement",
    "hideComparison": "Hide Comparison",
    "comparePeriods": "Compare Periods",
    "current": "Current",
    "comparison": "Comparison",
    "variance": "Variance",
    "revenue": "Revenue",
    "costOfGoodsSold": "Cost of Goods Sold",
    "operatingExpenses": "Operating Expenses",
    "otherIncome": "Other Income",
    "otherExpenses": "Other Expenses",
    "grossProfit": "Gross Profit",
    "operatingIncome": "Operating Income",
    "netProfit": "Net Profit",
    "noItemsInSection": "No items in this section",
    "howItWorksTitle": "How Financial Statements Work",
    "trialBalanceHeading": "1. Trial Balance",
    "trialBalanceDesc": "Lists every account with its total debits and credits. The totals must always be equal. If they're not, something is wrong with your journal entries.",
    "trialBalanceUse": "Use it to: Verify your books are balanced before generating other reports.",
    "profitLossHeading": "2. Profit & Loss (Income Statement)",
    "profitLossDesc": "Shows your revenue minus expenses for a period. Tells you whether your business made or lost money.",
    "profitLossUse": "Use it to: Understand profitability, compare periods, and identify spending trends.",
    "balanceSheetHeading": "3. Balance Sheet",
    "balanceSheetDesc": "A snapshot of what your business owns (assets), owes (liabilities), and the owners' stake (equity) at a specific date. Assets must always equal Liabilities + Equity.",
    "balanceSheetUse": "Use it to: Assess financial health, apply for loans, or report to investors.",
    "cashFlowHeading": "4. Cash Flow Statement",
    "cashFlowDesc": "Shows where cash came from and where it went, categorized into Operating (day-to-day), Investing (assets), and Financing (loans/equity) activities.",
    "cashFlowUse": "Use it to: Understand liquidity and ensure you have enough cash to operate.",
    "tipsHeading": "Tips",
    "tipPostedEntries": "All reports are generated from your posted journal entries.",
    "tipDraftVoided": "Draft and voided entries are excluded automatically.",
    "tipExportPdf": "Use \"Export CSV\" to share reports with your accountant or auditor. PDF export is coming soon.",
    "tipComparison": "The P&L supports period comparison. Toggle it to see how this period compares to the last.",
    "tipChatAgent": "You can also ask the chat agent: \"Show me P&L for last quarter\"",
    "fxEffectOnCash": "Effect of exchange rate changes on cash",
    "totalFxEffectOnCash": "Total effect of exchange rate changes on cash",
    "unclassifiedActivities": "Unclassified movements",
    "totalUnclassifiedActivities": "Total unclassified movements",
    "unclassifiedHint": "These movements settle an account the chart does not tell us is trade or financing. Set its type or name it, then regenerate.",
    "cashPerLedger": "Cash per ledger at period end",
    "cashDifference": "Difference",
    "cashTiesToLedger": "Closing cash agrees to the ledger cash accounts",
    "cashDoesNotTie": "Closing cash does not agree to the ledger cash accounts",
    "policyNote": "Interest paid and received are shown in operating activities. Dividends paid are shown in financing activities (IAS 7.31 to 7.34 policy choice). Payments to suppliers, employees and tax authorities are operating activities.",
    "bridgeTitle": "Reconciliation from profit to operating cash",
    "bridgeProfit": "Profit for the period",
    "bridge_nonCashCharges": "Depreciation, amortisation and other non-cash charges",
    "bridge_fxOnCash": "Unrealised exchange differences on cash",
    "bridge_receivables": "Decrease (increase) in trade receivables",
    "bridge_inventories": "Decrease (increase) in inventories",
    "bridge_payables": "Increase (decrease) in trade payables",
    "bridge_accruals": "Increase (decrease) in accruals",
    "bridge_tax": "Increase (decrease) in tax and statutory balances",
    "bridge_otherAssets": "Decrease (increase) in other current assets",
    "bridge_otherLiabilities": "Increase (decrease) in other operating liabilities",
    "bridgeNetOperating": "Net cash from operating activities per this reconciliation",
    "bridgeDifference": "Difference to the operating total above",
    "bridgeTies": "The reconciliation agrees to the operating cash flow above.",
    "bridgeDoesNotTie": "The reconciliation does not agree to the operating cash flow above. The difference is shown, not adjusted.",
    "bridgeUnavailable": "Not available: no cash account is configured for this business, so profit cannot be reconciled to cash.",
    "bridgePolicyNote": "Non-cash items are charges and credits to profit that move no cash: depreciation and amortisation, and unrealised exchange differences on cash. Working capital changes are the period movements on receivables, inventories, payables, accruals and tax balances.",
    "lineCustomers": "Cash received from customers",
    "lineSuppliers": "Cash paid to suppliers",
    "lineStatutory": "Statutory payments",
    "lineAccruals": "Cash paid on accrued expenses",
    "lineSales": "Cash received from sales and other income",
    "lineOperatingExpenses": "Cash paid for operating expenses",
    "lineRevaluation": "Foreign exchange revaluation",
    "showMovements": "Show {count, plural, one {# movement} other {# movements}}",
    "hideMovements": "Hide movements",
    "movementsTruncated": "Showing the first {shown} of {count} movements. The CSV export lists the same capped detail.",
    "retainedProfitsBroughtForward": "Retained profits (brought forward)",
    "currentYearProfitLoss": "Current year profit / (loss)",
    "trialBalanceNotRebasedNote": "Profit and loss accounts show their balance since the first entry. They are not reset at the start of the financial year.",
    "compareWith": "Compare with",
    "compareNone": "No comparison",
    "compare_asAt_prior_month_end": "End of previous month",
    "compare_asAt_prior_year": "Same date last year",
    "compare_asAt_prior_financial_year_end": "End of previous financial year",
    "compare_range_prior_period": "Previous period (same length)",
    "compare_range_prior_year": "Same period last year",
    "comparisonFailed": "We couldn't load the comparison. The report is shown without it.",
    "statementLedgerChanged": "The books changed while this statement was being read, so nothing is shown. Try again.",
    "statementLedgerTooLarge": "This ledger is too large to read in one pass, so the statement could not be produced. Contact support.",
    "statementLoadFailed": "We could not load this statement. Your books are unchanged. Try again.",
    "statementRetry": "Try again",
    "changeColumn": "Change",
    "changeNetColumn": "Change in net balance (debit less credit)",
    "comparedWithDate": "Compared with {date}",
    "comparedWithPeriod": "Compared with {period}",
    "periodRange": "{from} to {to}",
    "comparativeUnbalanced": "The balance sheet as of {date} does not balance: assets and liabilities plus equity differ by {imbalance}.",
    "comparativeTrialBalanceUnbalanced": "The trial balance as of {date} does not balance: debits and credits differ by {imbalance}.",
    "comparativeCashDoesNotTie": "The cash flow for {period} does not tie to the ledger cash balance.",
    "trialBalanceViewLabel": "Trial balance view",
    "trialBalanceViewAsAt": "As at a date",
    "trialBalanceViewPeriod": "For a period",
    "periodTrialBalance": "Trial Balance for a Period",
    "periodTrialBalanceFor": "For {from} to {to}",
    "periodTrialBalanceNote": "Opening balance, movement in the period and closing balance for each account, with debit and credit totals.",
    "periodTrialBalanceOpeningNote": "Profit and loss accounts open at the start of the financial year ({date}). Balance sheet accounts open with their full balance.",
    "periodTrialBalanceLoadFailed": "We couldn't load the trial balance for this period. Please try again.",
    "periodDoesNotFootBadge": "Does not balance",
    "periodDoesNotFootWarning": "The columns do not balance. Debits and credits differ in the opening, the period or the closing of at least one currency, so a posting or a missing account needs attention. Nothing has been adjusted to hide it.",
    "periodGroupOpening": "Opening balance",
    "periodGroupPeriod": "Movement in the period",
    "periodGroupClosing": "Closing balance",
    "periodCurrency": "Currency",
    "periodDebit": "Debit",
    "periodCredit": "Credit",
    "periodTotalsIn": "Total in {currency}",
    "periodBroughtForwardNote": "Retained profits (brought forward) is the profit or loss of the earlier financial years. It is worked out from the ledger and is not an account, so that the opening and closing columns balance.",
    "equityChangesHeading": "5. Statement of Changes in Equity",
    "equityChangesDesc": "Shows how the owners' interest moved over the period: opening balance, profit or loss, capital introduced, drawings and dividends, other movements and the closing balance, by component of equity.",
    "equityChangesUse": "Use it to: See what changed equity, and check that the closing balance equals total equity on the balance sheet.",
    "equityMovements": "Movements in the period",
    "equityTotalOpening": "Total opening balance"
  },
  "x_acctmgmt_0": {
    "saving": "Saving...",
    "cards": {
      "businessProfile": {
        "title": "Business Profile",
        "description": "Company information, logo, and basic settings"
      },
      "currencyFinance": {
        "title": "Currency & Finance",
        "description": "Functional currency and operational currencies"
      },
      "teamManagement": {
        "title": "Team Management",
        "description": "Invite members, manage roles and permissions"
      },
      "approvalWorkflows": {
        "title": "Approval Workflows",
        "description": "Review and approve expense claims"
      }
    },
    "management": {
      "title": "Business Management",
      "subtitle": "Quick access to advanced business settings",
      "ownerBadge": "Owner",
      "nonManagerNotice": "Business management settings are available to managers and administrators"
    },
    "preferences": {
      "title": "Preferences",
      "subtitle": "Customize your display and notification settings"
    },
    "currency": {
      "label": "Preferred Display Currency",
      "help": "All amounts will be converted and displayed in this currency"
    },
    "currencyNames": {
      "USD": "US Dollar",
      "SGD": "Singapore Dollar",
      "MYR": "Malaysian Ringgit",
      "THB": "Thai Baht",
      "IDR": "Indonesian Rupiah",
      "VND": "Vietnamese Dong",
      "PHP": "Philippine Peso",
      "CNY": "Chinese Yuan",
      "EUR": "Euro",
      "INR": "Indian Rupee"
    },
    "timezone": {
      "label": "Timezone",
      "help": "Used for your dashboard and notification scheduling"
    },
    "language": {
      "label": "Language",
      "help": "Your preferred language. The app will load in this language by default after you sign in."
    },
    "emailNotifications": {
      "label": "Email Notifications",
      "loading": "Loading preferences...",
      "marketing": {
        "label": "Marketing & Promotions",
        "description": "Receive updates about new features and special offers"
      },
      "onboarding": {
        "label": "Onboarding Tips",
        "description": "Get helpful tips to make the most of Groot Finance"
      },
      "productUpdates": {
        "label": "Product Updates",
        "description": "Stay informed about product improvements and changes"
      },
      "unsubscribeAll": {
        "label": "Unsubscribe from all marketing",
        "description": "Turn off all non-essential emails (you'll still receive important account notifications)"
      },
      "transactionalNote": "Transactional emails (password resets, security alerts, and billing notifications) cannot be disabled."
    },
    "toast": {
      "tryAgain": "Please try again.",
      "currencyUpdated": {
        "title": "Currency updated",
        "description": "Display currency changed to {currency}"
      },
      "currencyFailed": {
        "title": "Failed to update currency"
      },
      "timezoneUpdated": {
        "title": "Timezone updated",
        "description": "Timezone changed to {timezone}"
      },
      "timezoneFailed": {
        "title": "Failed to update timezone"
      },
      "languageUpdated": {
        "title": "Language updated",
        "description": "Default language set to {language}"
      },
      "languageFailed": {
        "title": "Failed to update language"
      },
      "notificationUpdated": {
        "title": "Notification settings updated",
        "description": "Your email preferences have been saved."
      },
      "updateFailed": {
        "title": "Failed to update"
      },
      "switchBusinessFailed": "Failed to switch business. Please try again."
    },
    "einvoice": {
      "title": "E-Invoice Notifications",
      "subtitle": "Control email notifications for e-invoice events",
      "loading": "Loading notification settings...",
      "autoDelivery": {
        "label": "Auto-deliver validated e-invoices to buyers",
        "description": "Automatically email the LHDN-validated PDF to the buyer after successful validation"
      },
      "buyerNotif": {
        "label": "Send buyer notification emails",
        "description": "Notify buyers via email on validation, cancellation, and rejection events"
      },
      "unsavedChanges": "You have unsaved changes",
      "saving": "Saving...",
      "saveChanges": "Save Changes",
      "allSaved": "All changes saved",
      "toast": {
        "csrfFailed": "Failed to get CSRF token",
        "saveFailed": "Failed to save",
        "saved": {
          "title": "Settings saved",
          "description": "Notification preferences updated."
        }
      }
    },
    "ai": {
      "noBusinessContext": "Business context not available",
      "loading": "Loading AI automation stats...",
      "title": "AI & Automation",
      "subtitle": "Track how AI helps automate your financial operations",
      "lifetimeSince": "Lifetime automation statistics since {since}",
      "youStarted": "you started",
      "empty": {
        "title": "Get Started with AI Automation",
        "subtitle": "Start processing documents to see how AI automates your workflow",
        "bullet1": "• Upload sales invoices for AR reconciliation",
        "bullet2": "• Import bank transactions for classification",
        "bullet3": "• Submit expense claims with receipt OCR"
      },
      "cards": {
        "automationRate": "Automation Rate",
        "automatedOf": "{automated} of {total} automated",
        "documentsProcessed": "Documents Processed",
        "reviewedByYou": "{count} reviewed by you",
        "timeSaved": "Time Saved",
        "zeroHours": "0 hours",
        "estimatedManual": "Estimated based on manual work"
      },
      "byFeature": {
        "title": "Automation by Feature",
        "processed": "{count} processed",
        "arRecon": {
          "title": "AR Reconciliation",
          "description": "Sales invoices matched to orders"
        },
        "bankRecon": {
          "title": "Bank Reconciliation",
          "description": "Transactions classified to GL accounts"
        },
        "feeBreakdown": {
          "title": "Fee Breakdown",
          "description": "Sales fees categorized automatically"
        },
        "expenseOCR": {
          "title": "Expense OCR",
          "description": "Receipt data extracted automatically"
        }
      },
      "help": {
        "question": "What is automation rate?",
        "answer": "The percentage of AI decisions that didn't require manual review or correction. A higher rate means AI is more accurately handling your financial operations."
      }
    },
    "display": {
      "workspaceLogoAlt": "Workspace Logo",
      "errorLoading": "Error loading business",
      "collapseSidebar": "Collapse sidebar",
      "expandSidebar": "Expand sidebar",
      "createNewBusiness": "Create New Business",
      "switchBusiness": "Switch Business",
      "businessFallback": "Business",
      "workspaceCount": "{count, plural, one {# workspace} other {# workspaces}}"
    }
  },
  "x_acctmgmt_1": {
    "tabs": {
      "title": "e-Invoice Settings",
      "subtitle": "Configure LHDN MyInvois integration, compliance fields, and buyer notification preferences",
      "integration": "Integration",
      "compliance": "Compliance",
      "notifications": "Notifications",
      "loadingIntegration": "Loading integration settings...",
      "loadingCompliance": "Loading compliance settings...",
      "loadingNotifications": "Loading notification settings..."
    },
    "complianceSettings": {
      "errorCsrf": "Failed to get CSRF token",
      "errorSave": "Failed to save",
      "errorSaveDescription": "Unable to save compliance settings",
      "toastSavedTitle": "Compliance settings saved",
      "toastSavedDescription": "Tax and business registration details updated.",
      "heading": "Compliance Information",
      "headingSubtitle": "Mandatory tax and business registration details for LHDN e-invoice compliance",
      "infoTitle": "Required for LHDN e-invoicing",
      "infoTin": "Tax Identification Number from LHDN",
      "infoBrn": "Business Registration Number from SSM",
      "infoMsic": "Your business activity classification",
      "msicCodeLabel": "MSIC Code",
      "requiredBadge": "Required",
      "lhdnTinLabel": "LHDN TIN (Tax Identification Number)",
      "lhdnTinPlaceholder": "e.g., IG24210777100",
      "brnLabel": "Business Registration Number (BRN)",
      "brnPlaceholder": "e.g., 202001234567",
      "sstLabel": "SST Registration Number",
      "sstPlaceholder": "e.g., B10-1234-56789012",
      "msicLabel": "MSIC Code (Business Activity)",
      "msicSearchPlaceholder": "Search by code or description...",
      "selected": "Selected: {code} ({description})",
      "autoSelfBillLabel": "Self-billed e-invoices: listed cases only",
      "autoSelfBillDescription": "Self-billing is allowed only for the cases LHDN lists, for example goods or services from a foreign supplier. A Malaysian vendor that is exempt or does not issue an e-invoice is not a self-billing case: ask the vendor for an e-invoice, or keep the receipt as proof of the expense.",
      "saving": "Saving...",
      "saveButton": "Save Compliance Settings"
    },
    "complianceForm": {
      "errorValidationFailed": "Validation failed",
      "errorInvalidCredentials": "Invalid credentials",
      "toastInvalidCredentialsTitle": "Invalid LHDN credentials",
      "toastInvalidCredentialsDescription": "Client ID or Secret is incorrect.",
      "toastSecretSaveFailedTitle": "Client Secret save failed",
      "toastSecretSaveFailedDescription": "e-Invoice fields saved, but LHDN Client Secret failed to save. Please retry.",
      "toastUpdatedTitle": "e-Invoice settings updated",
      "toastUpdatedDescription": "Your compliance details have been saved",
      "toastUpdateFailedTitle": "Failed to update e-Invoice settings",
      "toastUpdateFailedDescription": "Unable to update compliance details",
      "toastUpdateErrorTitle": "Error updating e-Invoice settings",
      "toastUpdateErrorDescription": "Unable to connect to server",
      "heading": "e-Invoice Compliance",
      "lhdnTinLabel": "LHDN TIN (Tax Identification Number)",
      "brnLabel": "Business Registration Number (BRN)",
      "brnPlaceholder": "e.g. 202001234567",
      "sstLabel": "SST Registration Number",
      "sstPlaceholder": "e.g. B10-1234-56789012",
      "msicLabel": "MSIC Code (Business Activity)",
      "msicSearchPlaceholder": "Search by code or activity description...",
      "msicNoMatch": "No matching MSIC codes. You can enter a custom code below.",
      "useCustomCode": "Use custom code: {code}",
      "selected": "Selected: {code} ({description})",
      "connected": "Connected to LHDN MyInvois",
      "notConnected": "Not connected",
      "connectedHint": "E-invoices are being polled automatically.",
      "notConnectedHint": "Enter Client ID and Secret below to connect.",
      "active": "Active",
      "clientIdLabel": "LHDN Client ID",
      "clientIdPlaceholder": "e.g., 3cec36d3-bf94-4e82-a4ca-b2614e56c77e",
      "clientIdHint": "From MyInvois portal → Taxpayer Profile → ERP tab.",
      "clientSecretLabel": "LHDN Client Secret (Secret 1 or 2)",
      "updateSecret": "Update secret",
      "clientSecretPlaceholder": "Enter either Client Secret 1 or 2...",
      "clientSecretHint": "Stored securely (encrypted at rest). Required for automatic e-invoice retrieval.",
      "ownKeysHeading": "Receive e-invoices from your suppliers (optional)",
      "ownKeysHint": "Your own MyInvois client ID and secret let Groot fetch and check the e-invoices your suppliers send you. Groot does not need them to file your own e-invoices.",
      "invalidCredentialsPrefix": "Invalid credentials:",
      "peppolLabel": "Peppol Participant ID",
      "autoSelfBillLabel": "Self-billed e-invoices: listed cases only",
      "autoSelfBillDescription": "Self-billing is allowed only for the cases LHDN lists, for example goods or services from a foreign supplier. A Malaysian vendor that is exempt or does not issue an e-invoice is not a self-billing case: ask the vendor for an e-invoice, or keep the receipt as proof of the expense.",
      "notificationsHeading": "E-Invoice Notifications",
      "autoDeliverLabel": "Auto-deliver validated e-invoices to buyers",
      "autoDeliverDescription": "Automatically email the LHDN-validated PDF to the buyer after successful validation",
      "buyerNotificationsLabel": "Send buyer notification emails",
      "buyerNotificationsDescription": "Notify buyers via email on validation, cancellation, and rejection events",
      "saveButton": "Save Details",
      "taxIdFormatHint": "Expected format, e.g. {example}",
      "tinInUse": "This TIN is already used by another Groot workspace, so it was not saved. If it is yours, contact support@hellogroot.com."
    },
    "categoryManagement": {
      "errorFetch": "Failed to fetch categories",
      "errorFetchNetwork": "Network error while fetching categories",
      "successUpdated": "Category updated successfully",
      "successCreated": "Category created successfully",
      "errorSave": "Failed to save category",
      "errorSaveNetwork": "Network error while saving category",
      "successDeleted": "Category deleted successfully",
      "errorDelete": "Failed to delete category",
      "errorDeleteNetwork": "Network error while deleting category",
      "noPermission": "Category management is available for managers and finance users only.",
      "expenseCategories": "Expense Categories",
      "cogsCategories": "COGS Categories",
      "expenseCategoriesDescription": "Manage expense categories for your organization",
      "addCategory": "Add Category",
      "searchPlaceholder": "Search categories...",
      "loading": "Loading categories...",
      "noMatch": "No categories match your search",
      "noCategories": "No categories found",
      "glPrefix": "GL: {code}",
      "inactive": "Inactive",
      "default": "Default",
      "receiptRequired": "Receipt required",
      "receiptNotRequired": "Receipt not required",
      "receiptThreshold": "(>${amount})",
      "managerApprovalRequired": "Manager approval required",
      "managerApprovalNotRequired": "Manager approval not required",
      "policyLimit": "Policy limit: ${amount}",
      "keywords": "Keywords: {keywords}",
      "edit": "Edit",
      "deleteDialogTitle": "Delete Category",
      "deleteDialogMessage": "Are you sure you want to delete the category \"{name}\"? This action cannot be undone and may affect existing expense claims.",
      "deleteConfirm": "Delete",
      "deleteCancel": "Cancel"
    },
    "deleteAccount": {
      "errorCheckEligibility": "Failed to check deletion eligibility",
      "errorCheckEligibilityRetry": "Failed to check deletion eligibility. Please try again.",
      "errorDeletionFailed": "Account deletion failed",
      "errorDeletionFailedRetry": "Account deletion failed. Please try again.",
      "errorExportFailed": "We couldn't finish preparing your data export, so your account has not been deleted. Everything is still intact. Please try again in a few minutes. If it keeps failing, contact support@hellogroot.com and we'll help you complete it.",
      "errorExportMisconfigured": "We can't prepare your data export right now because of a problem on our side, so your account has not been deleted. Everything is still intact. Please contact support@hellogroot.com and we'll complete this for you.",
      "errorSubscriptionCancelFailed": "We couldn't cancel your billing subscription, so your account has not been deleted and your sign-in still works. We stopped rather than leave you paying for an account you could no longer reach. Please try again in a few minutes, or contact support@hellogroot.com and we'll finish this for you.",
      "dangerZone": "Danger Zone",
      "deleteHeading": "Delete your account",
      "deleteDescription": "Permanently delete your account and all associated data. This action cannot be undone. Your personal data will be removed, financial records will show \"Deleted User\", and you will lose access to all businesses.",
      "checking": "Checking...",
      "deleteAccountButton": "Delete Account",
      "cannotDeleteTitle": "Cannot Delete Account",
      "cannotDeleteDescription": "You are the sole owner of the following businesses with other members. Transfer ownership or remove all members before deleting your account.",
      "memberCount": "{count, plural, one {# member} other {# members}}",
      "gotIt": "Got it",
      "willPermanently": "This will permanently:",
      "bulletPersonalData": "Delete your personal data (conversations, notifications)",
      "bulletAnonymize": "Anonymize financial records to \"Deleted User\"",
      "bulletRemoveBusinesses": "Remove you from all businesses",
      "bulletCancelPending": "Cancel pending expense claims and leave requests",
      "bulletCancelSubscription": "Cancel your active subscription",
      "pendingItemsNotice": "You have {count, plural, one {# pending item} other {# pending items}} that will be automatically cancelled.",
      "archiveTitle": "Your data will be archived",
      "archiveDescriptionBefore": "A copy of your data will be saved and your business owner(s) will receive a download link that expires after 7 days. You can also download your data now from the ",
      "downloadMyData": "Download My Data",
      "archiveDescriptionAfter": " section above.",
      "typeToConfirmBefore": "Type ",
      "typeToConfirmAfter": " to confirm",
      "typeDeletePlaceholder": "Type DELETE",
      "cancel": "Cancel",
      "deleting": "Deleting...",
      "deleteMyAccount": "Delete My Account"
    }
  },
  "x_acctmgmt_2": {
    "dialog": {
      "title": "Invite Team Member"
    },
    "errors": {
      "emailRequired": "Email is required",
      "emailInvalid": "Please enter a valid email address",
      "roleRequired": "Role is required",
      "managerRequired": "Manager is required for employees"
    },
    "teamLimit": {
      "title": "Team Limit Reached",
      "defaultMessage": "You've reached the maximum number of team members for your current plan.",
      "upgradePlan": "Upgrade Plan",
      "dismiss": "Dismiss"
    },
    "fields": {
      "emailLabel": "Email Address *",
      "roleLabel": "Role *",
      "managerLabelRequired": "Manager *",
      "managerLabelOptional": "Manager (Optional)",
      "managerPlaceholderSelect": "Select manager",
      "managerPlaceholderNone": "No manager",
      "noManager": "No Manager",
      "noManagersAvailable": "No managers available. Add a manager first before inviting employees.",
      "employeeId": "Employee ID",
      "department": "Department",
      "jobTitle": "Job Title",
      "optional": "Optional"
    },
    "roles": {
      "employee": "Employee",
      "manager": "Manager",
      "financeAdmin": "Finance"
    },
    "actions": {
      "cancel": "Cancel",
      "sending": "Sending...",
      "sendInvitation": "Send Invitation"
    },
    "einvoice": {
      "heading": "LHDN MyInvois Integration",
      "subheading": "Configure your LHDN MyInvois API credentials and Peppol network settings",
      "status": {
        "connected": "Connected to LHDN MyInvois",
        "notConnected": "Not connected",
        "connectedHint": "E-invoices are being polled automatically every 5 minutes.",
        "notConnectedHint": "Enter your Client ID and Secret below to connect.",
        "active": "Active"
      },
      "guide": {
        "summary": "How to get your LHDN credentials",
        "lhdnFaq": "LHDN FAQ",
        "portalUrls": "Portal URLs:",
        "productionLabel": "Production:",
        "productionSuffix": "→ MyInvois (live)",
        "sandboxLabel": "Sandbox:",
        "sandboxSuffix": "→ Preprod (testing)",
        "step1Title": "Step 1: Access Taxpayer Profile",
        "step1Item1": "Log in to the MyInvois Portal",
        "step1Item2Prefix": "Top-right profile dropdown →",
        "step1Item2Bold": "\"View Taxpayer Profile\"",
        "step2Title": "Step 2: Register ERP",
        "step2Item1Prefix": "Scroll to",
        "step2Item1Bold1": "Representatives",
        "step2Item1Middle": "→",
        "step2Item1Bold2": "ERP tab",
        "step2Item2Prefix": "Click",
        "step2Item2Bold1": "\"Register ERP\"",
        "step2Item2Middle": "→ Enter name \"Groot Finance\" →",
        "step2Item2Bold2": "Save",
        "step3Title": "Step 3: Copy Credentials",
        "step3Item1Prefix": "Dialog shows:",
        "step3Item1Bold1": "Client ID",
        "step3Item1Bold2": "Client Secret 1",
        "step3Item1Bold3": "Client Secret 2",
        "step3Item2Prefix": "Copy all values immediately:",
        "step3Item2Bold": "secrets shown only once!",
        "step3Item3Prefix": "Tick confirm checkbox → Click",
        "step3Item3Bold": "\"Done\"",
        "step3Item4": "Enter Client ID and either Secret below",
        "twoSecretsBold": "Two secrets?",
        "twoSecretsText": "Both are valid; enter either one. Rotate via ERP tab → \"Regenerate Secrets\"."
      },
      "form": {
        "clientIdLabel": "LHDN Client ID",
        "requiredBadge": "Required",
        "clientIdPlaceholder": "e.g., 3cec36d3-bf94-4e82-a4ca-b2614e56c77e",
        "clientIdHint": "From MyInvois portal → Taxpayer Profile → ERP tab",
        "clientSecretLabel": "LHDN Client Secret (Secret 1 or 2)",
        "updateSecret": "Update secret",
        "clientSecretPlaceholder": "Enter either Client Secret 1 or 2...",
        "clientSecretHint": "Stored securely (encrypted at rest). Required for automatic e-invoice retrieval.",
        "invalidCredentialsPrefix": "Invalid credentials:",
        "peppolLabel": "Peppol Participant ID",
        "peppolHint": "Optional (for Peppol e-invoicing network)",
        "saving": "Saving...",
        "saveButton": "Save Integration Settings"
      },
      "toasts": {
        "validationRequestFailed": "Validation request failed",
        "invalidCredentials": "Invalid credentials",
        "invalidCredentialsTitle": "Invalid LHDN credentials",
        "invalidCredentialsDescription": "Client ID or Secret is incorrect. Please check and try again.",
        "csrfFailed": "Failed to get CSRF token",
        "saveFailedGeneric": "Failed to save",
        "saveSecretFailed": "Failed to save secret",
        "connectedTitle": "Connected to LHDN MyInvois",
        "connectedDescription": "Credentials validated and saved. Polling will start within 5 minutes.",
        "saveFailedTitle": "Failed to save",
        "saveFailedDescription": "Unable to save integration settings"
      }
    },
    "profile": {
      "heading": "Business Profile",
      "saveDetails": "Save Details",
      "logo": {
        "label": "Business Logo",
        "uploading": "Uploading...",
        "changeLogo": "Change Logo",
        "uploadLogo": "Upload Logo",
        "constraints": "JPG, PNG or WebP. Max 5MB."
      },
      "details": {
        "intro": "These details will appear on your invoices and customer-facing documents.",
        "businessName": "Business Name",
        "businessNamePlaceholder": "Enter your business name",
        "businessNameHint": "This name will appear in the sidebar and throughout the application.",
        "businessId": "Business ID",
        "businessIdHint": "A stable identifier for this business. Handy for support or for telling same-named businesses apart. Access is always permission-checked, so this ID is safe to share.",
        "businessIdCopy": "Copy",
        "businessIdCopied": "Business ID copied"
      },
      "address": {
        "label": "Business Address",
        "line1Placeholder": "Address Line 1 (Street address)",
        "line2Placeholder": "Address Line 2 (Unit, building, floor)",
        "line3Placeholder": "Address Line 3 (Optional)",
        "cityPlaceholder": "City",
        "postalCodePlaceholder": "Postal Code",
        "selectState": "Select state...",
        "stateProvincePlaceholder": "State / Province",
        "countryLockedHint": "Region is locked to your {currency} billing currency after subscription and cannot be changed."
      },
      "contact": {
        "emailLabel": "Company Contact Email",
        "emailHint": "Appears on invoices and customer-facing documents.",
        "phoneLabel": "Phone Number"
      },
      "toasts": {
        "csrfFailed": "Failed to get CSRF token",
        "profileUpdatedTitle": "Business profile updated",
        "profileUpdatedDescription": "Your business details have been saved",
        "updateFailedTitle": "Failed to update details",
        "updateFailedDescription": "Unable to update business details",
        "updateErrorTitle": "Error updating details",
        "serverError": "Unable to connect to server",
        "invalidFileTypeTitle": "Invalid file type",
        "invalidFileTypeDescription": "Please upload a JPG, PNG, or WebP image.",
        "fileTooLargeTitle": "File too large",
        "fileTooLargeDescription": "Please upload an image under 5MB.",
        "logoUploadedTitle": "Logo uploaded",
        "logoUploadedDescription": "Your business logo has been updated successfully",
        "uploadFailedTitle": "Upload failed",
        "uploadFailedDescription": "Failed to upload logo",
        "uploadErrorTitle": "Error uploading logo",
        "logoRemovedTitle": "Logo removed",
        "logoRemovedDescription": "Your business logo has been removed successfully",
        "removeFailedTitle": "Remove failed",
        "removeFailedDescription": "Failed to remove logo",
        "removeErrorTitle": "Error removing logo"
      }
    },
    "stripe": {
      "cardTitle": "Stripe Integration",
      "cardDescription": "Connect your Stripe account to sync your product catalog",
      "loadingStatus": "Loading integration status...",
      "connectedTo": "Connected to {accountName}",
      "accountId": "Account ID",
      "connectedLabel": "Connected",
      "unknown": "Unknown",
      "lastSynced": "Last Synced",
      "disconnectButton": "Disconnect Stripe",
      "previouslyConnected": "Previously connected; synced catalog items are preserved",
      "apiKeyLabel": "Stripe API Key",
      "apiKeyHintPrefix": "Use a",
      "restrictedKeyLink": "restricted key",
      "apiKeyHintMiddle": "(recommended) or a standard secret key from",
      "apiKeyHintPath": "Stripe Dashboard > Developers > API keys",
      "connecting": "Connecting...",
      "connectButton": "Connect Stripe",
      "errors": {
        "unexpected": "An unexpected error occurred",
        "connectFailed": "We couldn't connect that Stripe key. Check that it starts with sk_ or rk_, and that a restricted key has Products (Read), Prices (Read) and Connect (Read) enabled.",
        "ownerOnly": "Only the business owner can connect or disconnect Stripe. Ask the owner to do it."
      },
      "permissions": {
        "title": "Required permissions for restricted keys",
        "products": "Products",
        "prices": "Prices",
        "connect": "Connect",
        "webhookEndpoints": "Webhook Endpoints",
        "read": "; Read",
        "readForAccountVerification": "; Read (for account verification)",
        "writeForRealtimeSync": "; Write (for real-time sync)",
        "apiReferenceLink": "Stripe API reference"
      },
      "toasts": {
        "connectedTitle": "Stripe Connected",
        "connectedDescription": "Connected to {accountName}. Syncing your product catalog...",
        "disconnectedTitle": "Stripe Disconnected",
        "disconnectedDescription": "Your Stripe account has been disconnected. Synced catalog items are preserved.",
        "disconnectFailedTitle": "Disconnect Failed",
        "disconnectFailedDescription": "Failed to disconnect"
      },
      "confirm": {
        "title": "Disconnect Stripe?",
        "message": "Your synced catalog items will be preserved but no further syncs can be performed until you reconnect.",
        "confirmText": "Disconnect"
      }
    },
    "privacy": {
      "loading": "Loading...",
      "analytics": {
        "title": "Privacy-safe product analytics",
        "description": "Help improve Groot Finance with minimized usage events. We never send names, email addresses, financial values, or document contents.",
        "label": "Allow privacy-safe product analytics",
        "dnt": "Disabled because your browser has Do Not Track enabled."
      },
      "download": {
        "title": "Download My Data",
        "description": "Export all your personal and business data as a ZIP of CSV spreadsheets.",
        "generating": "Generating export...",
        "errorFetch": "Unable to fetch your data. Please try again.",
        "errorGenerate": "Failed to generate export. Please try again."
      },
      "consentHistory": {
        "title": "Consent History",
        "description": "Record of all consent actions for your account.",
        "empty": "No consent records found.",
        "colPolicy": "Policy",
        "colVersion": "Version",
        "colAccepted": "Accepted",
        "colSource": "Source",
        "colStatus": "Status",
        "revokedOn": "Revoked {date}",
        "active": "Active",
        "policyType": {
          "privacy_policy": "Privacy Policy",
          "terms_of_service": "Terms of Service"
        },
        "source": {
          "onboarding": "Onboarding",
          "invitation": "Invitation",
          "banner": "Banner",
          "settings": "Settings"
        }
      },
      "revoke": {
        "title": "Revoke Consent",
        "description": "Withdraw your consent to our Privacy Policy. This will immediately block your access.",
        "button": "Revoke Consent",
        "confirmHeading": "Are you sure?",
        "confirmTextPrefix": "Revoking consent will",
        "confirmTextBold": "immediately block your access",
        "confirmTextSuffix": "to Groot Finance until you re-consent.",
        "downloadFirst": "Download your data first",
        "beforeRevoking": "before revoking.",
        "cancel": "Cancel",
        "revoking": "Revoking...",
        "confirmRevoke": "Confirm Revoke",
        "error": "Failed to revoke consent. Please try again."
      }
    },
    "currency": {
      "operationalLabel": "Operational currency",
      "operationalHelp": "The currency your books, reports and totals are kept in. Normally follows your country.",
      "autoFromCountry": "auto from country",
      "noCountryDefault": "{country} has no default operational currency. We've kept your current currency; switch on the override below to choose the one you report in.",
      "overrideToggle": "Use a currency different from my country",
      "overrideNote": "Your country ({country}) usually uses {derived}. You've set a different operational currency, which is valid when your functional currency differs (e.g. reporting to a parent company). This drives all reporting.",
      "overrideNoteNoCountryDefault": "Your country ({country}) has no default currency in Groot. Pick the operational currency your books are kept in; it drives all reporting.",
      "restrictedNotice": "Only the business owner or Finance can change the operational currency."
    },
    "fiscalYear": {
      "label": "Financial year starts in",
      "help": "Report shortcuts such as This financial year and Last financial year use this month. Changing it does not move any posted entry or accounting period.",
      "restrictedNotice": "Only an owner or finance admin can change this.",
      "months": {
        "m1": "January",
        "m2": "February",
        "m3": "March",
        "m4": "April",
        "m5": "May",
        "m6": "June",
        "m7": "July",
        "m8": "August",
        "m9": "September",
        "m10": "October",
        "m11": "November",
        "m12": "December"
      }
    }
  },
  "x_acctmgmt_3": {
    "deleteBusiness": {
      "dangerZone": "Danger Zone",
      "deleteHeading": "Delete this business",
      "deleteDescription": "Delete this business workspace. Members lose access immediately. We keep a digital copy of your accounting records for the period in our Privacy Policy. It does not replace your own records, so export a copy first and keep your original documents yourself. This cannot be undone from the app.",
      "checking": "Checking...",
      "deleteButton": "Delete Business",
      "cannotDeleteTitle": "Cannot Delete Business",
      "cannotDeleteDescription": "This business still has other active members. Remove all members (or transfer ownership) before deleting it.",
      "gotIt": "Got it",
      "willHappen": "This will:",
      "bulletRemoveWorkspace": "Remove the workspace for you and everyone else",
      "bulletRetainRecords": "Keep a digital copy of the accounting records under the retention schedule in our Privacy Policy (not permanently erased). It does not replace your own records",
      "bulletNoNewAccess": "Prevent any further access or changes to this business",
      "exportFirstTitle": "Export your data first",
      "exportFirstDescription": "Download a full copy of this business's books and keep it with your original documents before deleting. Groot holds a digital copy only.",
      "exportLink": "Export business data",
      "typeToConfirmBefore": "Type the business name ",
      "typeToConfirmAfter": " to confirm:",
      "cancel": "Cancel",
      "confirmDelete": "Delete Business",
      "deleting": "Deleting...",
      "errorCheckEligibility": "Failed to check deletion eligibility",
      "errorCheckEligibilityRetry": "Failed to check deletion eligibility. Please try again.",
      "errorDeletionFailed": "Business deletion failed",
      "errorDeletionFailedRetry": "Business deletion failed. Please try again."
    },
    "exportBusiness": {
      "cardTitle": "Business data backup",
      "cardDescription": "Download this business's full books as a ZIP of CSV files (chart of accounts, journal entries, invoices, expense claims, customers, vendors and more).",
      "keepOwnCopy": "Keep your own copy of your books and your original documents, paper ones included. Groot stores digital copies and is not your record keeper. Export regularly, and before you close a period, change plan or delete a business.",
      "button": "Export business data",
      "generating": "Generating...",
      "errorFetch": "Could not load business data. Please try again.",
      "errorGenerate": "Could not generate the export. Please try again.",
      "summaryComplete": "Export complete. Every record was exported.",
      "summaryIncomplete": "Export finished with gaps. Some modules are incomplete; see below.",
      "countLine": "{exported} of {total}",
      "badgeComplete": "Complete",
      "badgeIncomplete": "Incomplete",
      "errorTooLarge": "This module is too large to export in one go. Contact support to get the rest of it.",
      "errorModule": "This module could not be fully exported. Please try again, or contact support.",
      "journalTotals": "Journal lines exported: debits {debit}, credits {credit}.",
      "modules": {
        "chart_of_accounts": "Chart of accounts (categories)",
        "ledger_accounts": "Chart of accounts (ledger)",
        "journal_entries": "Journal entries",
        "journal_lines": "Journal lines",
        "expense_claims": "Expense claims",
        "invoices": "Invoices",
        "customers": "Customers",
        "vendors": "Vendors",
        "leave_requests": "Leave requests",
        "payments": "Payments",
        "bank_transactions": "Bank transactions",
        "accounting_periods": "Accounting periods",
        "audit_events": "Audit trail",
        "accounting_changes": "Accounting changes"
      },
      "summaryChanged": "The books changed while exporting, so the files may not agree with each other. Export again.",
      "badgeUnverified": "Unverified",
      "consistencyNote": "Checked while exporting: no records were added after the export began, and no journal entry was corrected, added or removed. Removals of other records and edits to other existing records are not detected.",
      "notices": {
        "excludedSoftDeleted": "{count, plural, one {# deleted record} other {# deleted records}} not included",
        "excludedNotReportable": "{count, plural, one {# entry} other {# entries}} not included because the status is not reported (for example drafts)",
        "excludedOrphanLine": "{count, plural, one {# line} other {# lines}} not included because the parent entry is missing",
        "excludedOther": "{count, plural, one {# record} other {# records}} not included",
        "filterInactiveCustomers": "Inactive customers are not included.",
        "filterCustomersFromInvoices": "Customers named only on invoices are added.",
        "filterInactiveVendors": "Inactive vendors are not included.",
        "filterVendorsFromClaims": "Vendors named only on expense claims are added.",
        "filterActiveCategories": "Only active expense and cost of sales categories that have a ledger code are included.",
        "filterGeneric": "A filter was applied to this module. See manifest.json for details.",
        "auditCoverage": "Covers {from} to {to}. Events older than the retention period have been removed and are not included.",
        "shortenedRows": "{count, plural, one {# row has} other {# rows have}} text shortened to a size limit (see the Shortened column). Everything else in those rows is whole.",
        "filterRevisionSnapshots": "Whole before and after snapshots are not included. Each correction lists its reason and its field changes, up to 50 items per correction (see the Shortened column)."
      }
    }
  },
  "x_leavemgmt_0": {
    "status_draft": "Draft",
    "status_submitted": "Submitted",
    "status_approved": "Approved",
    "status_rejected": "Rejected",
    "status_cancelled": "Cancelled",
    "myLeaveRequestsTitle": "My Leave Requests",
    "requestCount": "{count, plural, one {# request} other {# requests}}",
    "noRequestsYet": "No leave requests yet",
    "applyUsingFormAbove": "Apply for leave using the form above",
    "unknownType": "Unknown Type",
    "dayCount": "{count, plural, one {# day} other {# days}}",
    "submitForApproval": "Submit for Approval",
    "cancelRequest": "Cancel Request",
    "cancelRequestConfirmTitle": "Cancel this leave request?",
    "cancelRequestConfirmMessage": "The request will be withdrawn and your approver will no longer see it.",
    "cancelRequestConfirmYes": "Yes, cancel request",
    "cancelRequestConfirmKeep": "Keep request",
    "viewAllRequests": "View all {count} requests",
    "applyForLeave": "Apply for Leave",
    "applyForLeaveDescription": "Submit a leave request for approval by your manager",
    "leaveTypeLabel": "Leave Type",
    "selectLeaveTypePlaceholder": "Select leave type...",
    "balanceRemaining": "Balance: {remaining} days remaining",
    "startDateLabel": "Start Date",
    "endDateLabel": "End Date",
    "businessDays": "Business Days",
    "excludesWeekendsHolidays": "Excludes weekends and public holidays",
    "notesOptionalLabel": "Notes (Optional)",
    "notesPlaceholder": "Add any additional details for your manager...",
    "cancel": "Cancel",
    "saving": "Saving...",
    "saveAsDraft": "Save as Draft",
    "draftShort": "Draft",
    "submitting": "Submitting...",
    "submitShort": "Submit",
    "errorSelectLeaveType": "Please select a leave type",
    "errorSelectStartDate": "Please select a start date",
    "errorSelectEndDate": "Please select an end date",
    "errorEndAfterStart": "End date must be after start date",
    "errorStartInPast": "Start date cannot be in the past",
    "errorZeroBusinessDays": "Selected dates result in 0 business days",
    "errorInsufficientBalance": "Insufficient balance: {remaining} days remaining",
    "yourOrganization": "Your Organization",
    "leaveReportsTitle": "Leave reports",
    "leaveReportsSubtitle": "View leave utilization, balance summaries, and absence trends",
    "generating": "Generating...",
    "showingDataFor": "Showing data for:",
    "tabBalanceSummary": "Balance summary",
    "tabUtilization": "Utilization",
    "tabAbsenceTrends": "Absence trends",
    "generatingReport": "Generating report...",
    "noBalanceData": "No balance data found for this period.",
    "colEmployee": "Employee",
    "colTeam": "Team",
    "colLeaveType": "Leave type",
    "colEntitled": "Entitled",
    "colUsed": "Used",
    "colAdj": "Adj.",
    "colCarryover": "C/O",
    "colRemaining": "Remaining",
    "overallUtilization": "Overall utilization",
    "utilizationHigh": "High",
    "utilizationMedium": "Medium",
    "utilizationLow": "Low",
    "noUtilizationData": "No utilization data found.",
    "colMembers": "Members",
    "colUtilization": "Utilization",
    "totalAbsenceDays": "Total absence days",
    "peakMonth": "Peak month",
    "noAbsenceData": "No absence data found for this period.",
    "colMonth": "Month",
    "colTotalDays": "Total days",
    "colBreakdown": "Breakdown",
    "breakdownItem": "{name}: {days}d",
    "howItWorksTitle": "How leave reports work",
    "howItWorksDescription": "Generate and export leave data reports for your team.",
    "stepsHeading": "Steps",
    "step1Title": "Pick a report",
    "step1Desc": "Choose Leave and absence, or Utilization.",
    "step2Title": "Choose a year",
    "step2Desc": "Use the year dropdown to view different periods. If your business uses a non-January leave year (e.g., April-March), the period adjusts automatically.",
    "step3Title": "Export the data",
    "step3Desc": "Click CSV for spreadsheet data or PDF for a formatted report with your business name and date range.",
    "reportTypesHeading": "Report types",
    "reportTypeBalanceDesc": "Shows each employee's entitled, used, remaining, and carry-over days per leave type.",
    "reportTypeUtilizationDesc": "Shows how much of the allocated leave each team has used, as a percentage.",
    "reportTypeTrendsDesc": "Monthly breakdown of total absence days, with peak month identification.",
    "goodToKnowHeading": "Good to know",
    "goodToKnow1": "• Managers see only their direct reports' data",
    "goodToKnow2": "• Admins and owners see all employees",
    "goodToKnow3": "• Reports generate on-demand (not cached)",
    "goodToKnow4": "• PDF exports include your business name and date range",
    "selectBusinessPrompt": "Please select a business to configure leave management.",
    "settingsTitle": "Leave Management Settings",
    "settingsSubtitle": "Configure leave types, public holidays, and entitlements for your organization",
    "tabLeaveTypes": "Leave Types",
    "tabPublicHolidays": "Public Holidays",
    "tabEmployeeBalances": "Employee Balances",
    "tabGeneral": "General",
    "leaveTypesHeading": "Leave Types",
    "leaveTypesSubtitle": "Define the types of leave available to employees",
    "addLeaveType": "Add Leave Type",
    "noLeaveTypesConfigured": "No leave types configured",
    "noLeaveTypesHint": "Add leave types like Annual Leave, Sick Leave, etc.",
    "active": "Active",
    "inactive": "Inactive",
    "defaultDaysLabel": "Default Days",
    "daysPerYear": "{count} days/year",
    "deductsBalanceLabel": "Deducts Balance",
    "yes": "Yes",
    "no": "No",
    "publicHolidaysHeading": "Public Holidays",
    "publicHolidaysSubtitle": "Configure public holidays for your region",
    "addCustom": "Add Custom",
    "noHolidaysConfigured": "No public holidays configured",
    "noHolidaysHint": "Add holidays like New Year, Chinese New Year, Hari Raya, etc.",
    "customMarker": "(custom)",
    "country_MY": "Malaysia",
    "country_SG": "Singapore",
    "country_ID": "Indonesia",
    "country_PH": "Philippines",
    "country_TH": "Thailand",
    "country_VN": "Vietnam",
    "employeeBalancesHeading": "Employee Balances",
    "employeeBalancesSubtitle": "View and manage leave entitlements for all employees",
    "importBalances": "Import Balances",
    "bulkEditCount": "Bulk Edit ({count})",
    "initializing": "Initializing...",
    "initializeAllBalances": "Initialize All Balances",
    "initializedResult": "Initialized {created} balances ({skipped} already existed)",
    "dismiss": "Dismiss",
    "noEmployeesFound": "No employees found",
    "noEmployeesHint": "Employee balances will appear here once team members are added.",
    "selectAllEmployees": "Select all employees",
    "selectedCount": "{selected} of {total} selected",
    "clearSelection": "Clear selection",
    "unknown": "Unknown",
    "customBadge": "Custom",
    "entitlements": "Entitlements",
    "role_owner": "Owner",
    "role_finance_admin": "Finance",
    "role_manager": "Manager",
    "role_employee": "Employee",
    "noBalancesInitialized": "No balances initialized. Click \"Initialize All Balances\" to set up.",
    "notAvailable": "N/A",
    "usedLabel": "Used: {used}",
    "carryoverLabel": "C/O: {carryover}",
    "adjustmentsLabel": "Adj: {adjustments}",
    "leaveYearConfigTitle": "Leave Year Configuration",
    "leaveYearConfigDescription": "Configure when your business leave year starts. Default is January (calendar year). Some SEA businesses use fiscal years like April-March.",
    "leaveYearStartMonthLabel": "Leave Year Start Month",
    "month_1": "January",
    "month_2": "February",
    "month_3": "March",
    "month_4": "April",
    "month_5": "May",
    "month_6": "June",
    "month_7": "July",
    "month_8": "August",
    "month_9": "September",
    "month_10": "October",
    "month_11": "November",
    "month_12": "December",
    "monthShort_1": "Jan",
    "monthShort_2": "Feb",
    "monthShort_3": "Mar",
    "monthShort_4": "Apr",
    "monthShort_5": "May",
    "monthShort_6": "Jun",
    "monthShort_7": "Jul",
    "monthShort_8": "Aug",
    "monthShort_9": "Sep",
    "monthShort_10": "Oct",
    "monthShort_11": "Nov",
    "monthShort_12": "Dec",
    "currentLeaveYearRange": "Current leave year: {startMonth} {startYear} - {endMonth} {endYear}",
    "usingCalendarYear": "Using calendar year (January - December)",
    "changeLeaveYearStartTitle": "Change Leave Year Start",
    "changeLeaveYearWarning": "Changing the leave year start month will affect how balances are calculated going forward. Existing balances for the current period may need manual adjustment.",
    "changeLeaveYearBoundaryNote": "The new boundary will take effect from the next leave year cycle.",
    "confirmChange": "Confirm Change",
    "editLeaveType": "Edit Leave Type",
    "configureLeaveTypeSettings": "Configure leave type settings",
    "nameRequiredLabel": "Name *",
    "leaveNamePlaceholder": "e.g., Annual Leave",
    "codeRequiredLabel": "Code *",
    "leaveCodePlaceholder": "e.g., AL",
    "defaultDaysPerYearLabel": "Default Days Per Year",
    "colorLabel": "Color",
    "deductsBalanceHint": "Subtract days from employee balance",
    "requiresApprovalLabel": "Requires Approval",
    "requiresApprovalHint": "Manager must approve requests",
    "activeLabel": "Active",
    "activeHint": "Available for employees to use",
    "yearEndCarryoverLabel": "Year-End Carryover",
    "yearEndCarryoverHint": "How unused days carry to next year",
    "carryoverNone": "No Carryover - Days expire at year end",
    "carryoverCapped": "Capped - Up to a maximum number of days",
    "carryoverUnlimited": "Unlimited - All unused days carry over",
    "maxCarryoverDaysLabel": "Max carryover days:",
    "save": "Save",
    "editHoliday": "Edit Holiday",
    "addCustomHoliday": "Add Custom Holiday",
    "addCustomHolidayHint": "Add a custom holiday for your organization",
    "holidayNameRequiredLabel": "Holiday Name *",
    "holidayNamePlaceholder": "e.g., Company Anniversary",
    "dateRequiredLabel": "Date *",
    "countryLabel": "Region",
    "addHoliday": "Add Holiday",
    "editLeaveEntitlements": "Edit Leave Entitlements",
    "setCustomLeaveDaysFor": "Set custom leave days for",
    "customEntitlementsOverrideNote": "Custom entitlements override the default leave type settings.",
    "resetToDefaults": "Reset to Defaults",
    "defaultDaysValue": "Default: {count} days",
    "daysUnit": "days",
    "saveEntitlements": "Save Entitlements",
    "bulkEditEntitlementsTitle": "Bulk Edit Entitlements",
    "applySameEntitlementsTo": "Apply same entitlements to {count} selected {count, plural, one {employee} other {employees}}",
    "bulkOverrideWarning": "This will override any existing custom entitlements for all selected employees.",
    "updatingEmployees": "Updating employees...",
    "updating": "Updating...",
    "applyToEmployees": "Apply to {count} {count, plural, one {Employee} other {Employees}}",
    "importCompleteToast": "Import complete: {created} created, {updated} updated, {skipped} skipped",
    "rowsSkippedToast": "{skipped, plural, one {# row skipped} other {# rows skipped}}. Error report downloaded.",
    "importFailedToast": "Import failed. Check console for details.",
    "pdfTitleBalance": "Leave balance summary",
    "pdfTitleUtilization": "Leave utilization report",
    "pdfTitleTrends": "Absence trends report",
    "pdfTitleDefault": "Leave report",
    "pdfPeriodLabel": "Period",
    "pdfGeneratedLabel": "Generated",
    "pdfTeamUnassigned": "Unassigned",
    "pdfTeamFallback": "Team",
    "colUtilizationPercent": "Utilization %",
    "pdfGeneratedBy": "Generated by Groot Finance",
    "periodSelectorLabel": "Reporting period",
    "periodLastFullMonthHint": "Last full month",
    "periodWholeLeaveYear": "Whole leave year ({label})",
    "periodMonthOption": "{month} {year}",
    "colUnpaidDays": "Unpaid days",
    "unpaidSubsetHint": "Unpaid days are part of the total absence days. They are the days to deduct from salary.",
    "breakdownItemUnpaid": "{name}: {days}d (unpaid)",
    "breakdownNone": "No leave taken",
    "noAbsencesInPeriodTitle": "No absences in this period",
    "noAbsencesInPeriodDesc": "Nobody you can see took approved leave in {period}. Every employee is listed below with zero days.",
    "noEmployeesInScopeTitle": "No employees to report on",
    "noEmployeesInScopeDesc": "This report covers the active team members you can see. Once employees are added, their absence days appear here.",
    "reportFailedTitle": "This report could not be generated",
    "retryReport": "Try again",
    "holidayCalendarUnresolvedTitle": "Public holiday calendar is missing",
    "holidayCalendarUnresolvedDesc": "No public holidays are loaded for {years} in {country}, so days that are public holidays are being counted as absences. These figures may be too high. Load the holiday calendar in Leave Management settings before using this for payroll.",
    "businessWideBreakdownHeading": "Business-wide monthly breakdown",
    "businessWideBreakdownHint": "Totals across everyone you can see, for each month of the leave year.",
    "stepPeriodTitle": "Choose the period",
    "stepPeriodDesc": "Absence Trends opens on the previous complete calendar month, the month payroll is run for. Pick any other month, or choose the whole leave year to also see the month-by-month breakdown. Balance Summary and Utilization are annual and follow the year dropdown.",
    "reportTypeTrendsEmployeeDesc": "One row per employee, with total absence days, unpaid days and a breakdown by leave type. Choosing a whole leave year also shows the business-wide month-by-month breakdown and the peak month.",
    "goodToKnowUnpaid": "• Unpaid days are included in the total, and come from how each leave type is configured rather than from its name",
    "goodToKnowHolidays": "• Weekends and public holidays are not absence days, so the report agrees with the days deducted from the employee's entitlement",
    "pdfMonthlyBreakdownHeading": "Monthly breakdown",
    "pdfEmployeeRowsUnavailable": "Employee rows are unavailable for this report. Please regenerate it.",
    "reportGenerationFailed": "Something went wrong while generating this report. Please try again in a moment.",
    "pdfExportFailed": "Could not create the PDF. Please try again in a moment.",
    "exportNothingToExport": "There is nothing to export for this period yet.",
    "unpaidLeaveLabel": "Unpaid leave",
    "unpaidLeaveHint": "Salary is deducted for these days. Separate from whether the leave uses up entitlement, so leave such as compassionate can be paid without deducting balance.",
    "saveLeaveTypeFailedToast": "Could not save the leave type. Please try again.",
    "holidayRegionMY": "Malaysia",
    "holidayRegionSG": "Singapore",
    "holidayRegionID": "Indonesia",
    "holidayRegionPH": "Philippines",
    "holidayRegionTH": "Thailand",
    "holidayRegionVN": "Vietnam",
    "holidayRegionBN": "Brunei",
    "holidayRegionHK": "Hong Kong SAR",
    "holidayRegionTW": "Taiwan",
    "holidayRegionJP": "Japan",
    "holidayRegionKR": "South Korea",
    "holidayRegionIN": "India",
    "holidayRegionAU": "Australia",
    "holidayRegionNZ": "New Zealand",
    "holidayRegionGB": "United Kingdom",
    "holidayRegionUS": "United States",
    "regionalHolidaysTitle": "Regional public holidays",
    "regionalHolidaysDescription": "Import a region's public holidays once per year so leave and absence reports stop counting them as days off work. Your own company closure days are separate and stay in the custom list below.",
    "regionalHolidaysAdminOnlyNote": "Only an owner or finance admin can import a regional holiday calendar, because the calendar is shared by every business in the region.",
    "regionLabel": "Region",
    "regionSelectPlaceholder": "Choose a region",
    "regionSourceDetectedNote": "Detected from your business profile. Holidays are imported for this region.",
    "regionSourceSavedNote": "Taken from the holiday region saved for this business, which can differ from where the business is registered.",
    "regionSourceDefaultNote": "Your business profile has no region yet, so {region} is assumed. Choose another region to import a different calendar.",
    "regionOverrideNote": "Overriding {detected}. Importing now brings in {selected} holidays instead. This choice applies to the imports you run here and is not saved to your business profile.",
    "regionUnsupportedTitle": "No holiday data for region {region}",
    "regionUnsupportedBody": "We have no public holiday calendar for the region on your business profile, so nothing can be imported for it. Choose a region above to import a different calendar, or add each non-working day yourself with Add custom below.",
    "importByYearLabel": "Import by year",
    "importByYearHint": "Import {region} holidays for a year, and re-import that year later to pick up any changes.",
    "importByYearNoRegionHint": "Choose a region above to import a holiday calendar.",
    "importCountsTrackedForNote": "The imported counts shown below are for {detected}, the region on your business profile.",
    "yearImportedCount": "{count} holidays imported",
    "yearNotImported": "Not imported yet",
    "importedBadge": "Imported",
    "notImportedBadge": "Not imported",
    "importYear": "Import",
    "reimportYear": "Re-import",
    "importingHolidays": "Importing",
    "showHolidayList": "Show holidays",
    "hideHolidayList": "Hide holidays",
    "holidayListPreviewNote": "The {region} holiday calendar for {year}. Import it to use it in leave and absence reports.",
    "holidayListUnavailableNote": "We have no holiday calendar for {region} in {year}, so there is nothing to show. Add each non-working day yourself with Add custom below.",
    "holidayCountMismatchNote": "You have {saved} holidays saved for {year}, but the {region} calendar now has {available}. Re-import this year to bring it up to date.",
    "holidayImportSuccessToast": "Imported {region} holidays for {year}: {added} added, {updated} updated.",
    "holidayImportRegionUnsupportedError": "We have no holiday calendar for that region. Choose another region, or add each non-working day yourself with Add custom.",
    "holidayImportNoDataError": "We have no holiday calendar for that region and year yet, so nothing was imported. Try another year, or add the days yourself with Add custom.",
    "holidayImportForbiddenError": "Only an owner or finance admin can import a holiday calendar.",
    "holidayImportSignedOutError": "Your session has expired. Please sign in again and retry the import.",
    "holidayImportFailedError": "Could not import the holiday calendar. Please try again in a moment.",
    "regionSaveSuccessToast": "Holiday region set to {region}. Import a year below to load its calendar.",
    "regionClearedSuccessToast": "Holiday region cleared. Holidays now follow your business profile region, {region}.",
    "regionClearedNoRegionToast": "Holiday region cleared. Your business profile has no region, so no holiday calendar is in effect. Choose a region to load one.",
    "regionSaveFailedToast": "Could not save the holiday region. Please try again in a moment.",
    "regionSaveUnsupportedError": "We have no holiday calendar for that region, so it cannot be saved. Choose another region, or add each non-working day yourself with Add custom.",
    "regionSaveForbiddenError": "Only an owner or finance admin can change the holiday region.",
    "regionSaveSignedOutError": "Your session has expired. Please sign in again and choose the region.",
    "regionClearAction": "Use my business profile region",
    "savingRegion": "Saving",
    "regionInEffectDetectedNote": "{region} is in effect, detected from your business profile. Holidays are imported for this region.",
    "regionInEffectOverrideNote": "{region} is in effect, saved for this business. It overrides your business profile region, which stays as it is for tax and invoicing.",
    "regionNotSetTitle": "No region set for this business",
    "regionNotSetBody": "Your business profile has no region recorded, so no holiday calendar is loaded and public holidays are counted as ordinary working days in leave and absence reports. Choose a region above to fix this.",
    "holidayImportNoRegionError": "Choose a region first. This business has no region recorded, so there is no holiday calendar to import.",
    "holidayImportSuccessWithRemovedToast": "Imported {region} holidays for {year}: {added} added, {updated} updated, {removed} removed as no longer public holidays.",
    "holidayCalendarNoRegionTitle": "No holiday region set for this business",
    "holidayCalendarNoRegionDesc": "This business has no region recorded, so no public holiday calendar could be loaded and public holidays are being counted as absences. These figures may be too high. Choose a region in Leave Management settings before using this for payroll.",
    "holidayCalendarRegionUnsupportedTitle": "No holiday data for region {region}",
    "holidayCalendarRegionUnsupportedDesc": "We have no public holiday calendar for {region}, so public holidays are being counted as absences and these figures may be too high. Choose a region we cover in Leave Management settings, or add each non-working day yourself as a custom holiday.",
    "regionSourceNoneNote": "Your business profile has no region yet, so no holiday calendar is loaded and public holidays are counted as working days. Choose a region to fix this.",
    "holidayNationalOnlyTitle": "National public holidays only",
    "holidayNationalOnlyBody": "An imported calendar covers national public holidays. State and regional days are not included, so a region can look complete when it is not. India, for example, has only 6 national days, without Diwali, Holi or Eid, because those are declared state by state. Open a year below to check the dates, then add anything missing as a company holiday in Public Holidays further down this tab.",
    "holidayNationalOnlyToastBody": "These are national public holidays only. State and regional days are not included, so check the dates and add anything missing as a company holiday below.",
    "holidayImportSuccessTotalToast": "{region} {year} now has {total} national public holidays: {added} added, {updated} updated.",
    "holidayImportSuccessTotalWithRemovedToast": "{region} {year} now has {total} national public holidays: {added} added, {updated} updated, {removed} removed as no longer public holidays.",
    "holidayListStoredNote": "{count} national public holidays are stored for {region} {year}. These are the days the absence report treats as non-working.",
    "holidayListNationalOnlyNote": "State and regional days are not in this list. Add any that apply to you as a company holiday below.",
    "holidayCountsTruncatedNote": "We could not total every stored holiday just now, so the counts below may be short. Reload the page, and re-import a year only if its dates are genuinely missing.",
    "holidayStatusUnavailableTitle": "We could not load your holiday settings",
    "holidayStatusUnavailableBody": "The region and imported years could not be read just now, so nothing is shown rather than something that may be wrong. Reload the page to try again.",
    "holidayCalendarNationalOnlyTitle": "National public holidays only",
    "holidayCalendarNationalOnlyDesc": "The {region} calendar used here covers national public holidays only. State and regional days are not included, so any state holiday your staff took off is counted as an absence day in these figures. Add the days that apply to you as company holidays in Leave Management settings, then generate this report again before using it for payroll.",
    "balanceAsAtLabel": "As at {date}",
    "balanceAsAtCaption": "Entitlement is the full year. Used and remaining are as at {date}.",
    "balanceReconciliationMismatch": "{count, plural, one {# balance does not match} other {# balances do not match}} the running total recorded on approval. The figures below are counted from approved leave requests. Please check these balances.",
    "groupLeaveBalanceAt": "Leave balance as at {date}",
    "groupPeriodOnly": "Days taken in {period}",
    "colPaidDays": "Paid days",
    "entitlementNotSetUp": "(entitlement not set up)",
    "totalsOfEmployees": "Total for {shown} of {total} {total, plural, one {employee} other {employees}}",
    "dayCountUnavailableBanner": "Day counts are unavailable because no public holiday calendar is configured for this period. Unpaid days would be overstated and pay understated, so these figures are not shown.",
    "tabLeaveAndAbsence": "Leave and absence",
    "utilizationEmptyTitle": "No employees to report on",
    "utilizationEmptyDesc": "Once people are active members with leave entitlement, their usage appears here.",
    "utilizationHint": "One row per employee for {year}. Sorted so the people who need attention come first.",
    "daysOwedLabel": "Unused leave days",
    "daysOwedHint": "Days your team is still entitled to take. Each one must eventually be taken or paid.",
    "atRiskLabel": "At risk of burnout",
    "atRiskHint": "Have used {rate}% or less of their leave.",
    "ofNMembers": "of {total}",
    "overallRateLabel": "Overall usage",
    "overallRateHint": "{used} of {entitled} days taken.",
    "reportsToInline": "Reports to {manager}",
    "usedOfEntitled": "{used} of {entitled}",
    "noEntitlementShort": "Not set up",
    "bandCount": "{count, plural, one {# person} other {# people}}",
    "band_over_entitlement": "Over entitlement",
    "bandDesc_over_entitlement": "Has taken more leave than entitled. Usually unpaid leave or a manual adjustment.",
    "band_at_risk": "At risk: has taken almost no leave",
    "bandDesc_at_risk": "Used {atRisk}% or less. Unused leave is fatigue accruing, and a liability the business carries.",
    "band_nearly_exhausted": "Nearly out of leave",
    "bandDesc_nearly_exhausted": "Used {nearly}% or more. May have nothing left before the year ends.",
    "band_healthy": "Taking leave at a healthy pace",
    "bandDesc_healthy": "Between the two thresholds above.",
    "band_no_entitlement": "No entitlement set up",
    "bandDesc_no_entitlement": "No leave types assigned, so no usage rate can be calculated. This is a setup gap, not a wellbeing signal.",
    "byManagerHeading": "By manager",
    "byManagerHint": "An average can hide one person taking no leave beside another taking all of theirs, so the at-risk count is always shown with it.",
    "atRiskBadge": "{count} at risk",
    "allEmployeesHeading": "All employees",
    "allEmployeesHint": "The full roster, for comparing one column across everyone. The CSV and PDF exports carry the monthly figures.",
    "rosterViewLabel": "Figures to show",
    "rosterViewBalance": "Balance to date",
    "rosterViewPeriod": "Days in the period",
    "mergedTableHintBalance": "One row per employee. Entitlement and remaining days build up over the whole leave year, counted as at {date}.",
    "mergedTableHintPeriod": "One row per employee. Paid and unpaid days cover {period} only.",
    "errorInsufficientBalanceDetail": "Not enough leave left. You have {remaining, plural, one {# day} other {# days}} available for {year}, and this request needs {requested, plural, one {# day} other {# days}}. Shorten the request, or ask an owner or finance admin to adjust the balance.",
    "errorLeaveModuleNotEnabled": "Leave management is not enabled on your plan. Contact support to turn it on.",
    "errorCreateRequestFailed": "Could not save this leave request. Please try again in a moment.",
    "errorUpdateRequestFailed": "Could not update this leave request. Please try again in a moment.",
    "errorSubmitRequestFailed": "Could not send this leave request for approval. Please try again in a moment.",
    "errorApproveRequestFailed": "Could not approve this leave request. Please try again in a moment.",
    "errorRejectRequestFailed": "Could not reject this leave request. Please try again in a moment.",
    "errorCancelRequestFailed": "Could not cancel this leave request. Please try again in a moment.",
    "unpaidAlreadyInPayRun": "The {period} pay run already deducts these {days, plural, one {# unpaid day} other {# unpaid days}}.",
    "unpaidAlreadyInPayRunNoAccess": "The {period} pay run already deducts these {days, plural, one {# unpaid day} other {# unpaid days}}. Only an owner or finance admin can open Payroll.",
    "openPayRun": "Open the pay run",
    "errorRequestOverlap": "You already have a leave request covering some of those dates. Pick different dates, or cancel the existing request first.",
    "errorSystemHolidayImmutable": "This is a built-in public holiday, so it can't be edited or removed. Only holidays you added yourself can be changed.",
    "errorHolidayRemoveFailed": "Could not remove this holiday. Nothing was changed. Please try again in a moment.",
    "errorHolidayUpdateFailed": "Could not update this holiday. Nothing was changed. Please try again in a moment.",
    "spanNote": "{counted, plural, one {# day counted} other {# days counted}} of {calendar} calendar days. {skipped, plural, one {# weekend or holiday day is} other {# weekend or holiday days are}} not deducted.",
    "spanNoteChanged": "Counted when approved: {stored, plural, one {# day} other {# days}}. Today's holiday calendar would count {counted, plural, one {# day} other {# days}}."
  },
  "roleBadge": {
    "owner": "Owner",
    "admin": "Admin",
    "finance_admin": "Finance",
    "manager": "Manager",
    "employee": "Employee"
  },
  "x_notif_0": {
    "title": "Notification Preferences",
    "saveButton": "Save Preferences",
    "columns": {
      "category": "Category",
      "inApp": "In-App",
      "email": "Email"
    },
    "category": {
      "approval": {
        "label": "Approval Requests",
        "description": "Expense claim submissions and approvals"
      },
      "anomaly": {
        "label": "Anomaly Alerts",
        "description": "Financial anomaly and spending alerts"
      },
      "compliance": {
        "label": "Compliance Warnings",
        "description": "Tax, receipt, and compliance gaps"
      },
      "insight": {
        "label": "AI Insights",
        "description": "Proactive financial intelligence"
      },
      "invoice_processing": {
        "label": "Invoice Processing",
        "description": "Document processing updates"
      },
      "email_delivery": {
        "label": "Customer emails",
        "description": "When an email to a customer bounces or is marked as spam"
      }
    },
    "deadline": {
      "einvoiceReject": {
        "label": "E-invoice reject deadline emails",
        "description": "One email a day, around 9 am, listing the supplier e-invoices whose reject window closes within the next day and a half."
      }
    },
    "digest": {
      "title": "Email Digest",
      "frequencyLabel": "Frequency:",
      "daily": "Daily",
      "weekly": "Weekly"
    },
    "toast": {
      "saved": {
        "title": "Preferences saved",
        "description": "Your notification preferences have been updated."
      },
      "error": {
        "title": "Error saving preferences",
        "description": "Please try again."
      }
    },
    "panel": {
      "title": "Notifications",
      "description": "Your recent notifications",
      "markAllRead": "Mark all read",
      "clearAll": "Clear all",
      "loading": "Loading...",
      "emptyTitle": "No notifications yet",
      "emptyDescription": "We'll notify you when something needs your attention",
      "loadMore": "Load more"
    },
    "relativeTime": {
      "justNow": "Just now",
      "minutesAgo": "{count}m ago",
      "hoursAgo": "{count}h ago",
      "daysAgo": "{count}d ago"
    },
    "copy": {
      "timesheetEntryEdited": {
        "titleAdded": "{who} added {hours} on {date}",
        "titleChanged": "{who} changed your time on {date}",
        "body": "Your hours on {date} were {before} and are now {after}.",
        "reason": "Reason: {reason}",
        "reviewerFallback": "Your manager",
        "titleDeduction": "{who} changed an attendance deduction on {date}",
        "titleUpdated": "{who} updated your time on {date}",
        "bodyStays": "Your hours on {date} stay at {hours}.",
        "bodyDeduction": "The deduction for that day changed from {before} to {after}.",
        "bodyTimes": "Your check-in or check-out time was changed.",
        "bodyOther": "Other details of that day, such as lateness or overtime, were recalculated.",
        "bodyPayable": "Your net payable for the pay period changed from {before} to {after}.",
        "bodySplitRegular": "More of that day is now paid as regular time and less as overtime: regular time went from {beforeRegular} to {afterRegular} and overtime from {beforeOvertime} to {afterOvertime}.",
        "bodySplitOvertime": "More of that day is now paid as overtime and less as regular time: regular time went from {beforeRegular} to {afterRegular} and overtime from {beforeOvertime} to {afterOvertime}.",
        "bodyRate": "The overtime rate for that day changed from {beforeRate} to {afterRate}.",
        "bodyTiers": "The regular time, overtime and overtime rates totalled on your timesheet were recalculated."
      },
      "salesOrderReadyToInvoice": {
        "title": "{orderNumber} is ready to invoice",
        "body": "{who} accepted this order for {customer}, {amount}. It is ready to invoice.",
        "bodyFlagged": "{count, plural, one {# line is priced away from the catalogue.} other {# lines are priced away from the catalogue.}}",
        "whoFallback": "A team member"
      },
      "emailDeliveryProblem": {
        "titleNotDelivered": "Email not delivered",
        "titleNotSent": "Email not sent",
        "titleSpam": "Email marked as spam",
        "bodyNotDelivered": "The email with {document} {number} to {recipient} was not delivered. Check the address and send it again.",
        "bodyNotDeliveredSeveral": "The email with {document} {number} was not delivered to one of its addresses. Check the addresses and send it again.",
        "bodyNotSent": "The email with {document} {number} to {recipient} was not sent, because this address bounced or reported spam before. Check the address with the customer.",
        "bodyNotSentSeveral": "The email with {document} {number} was not sent to one of its addresses, because that address bounced or reported spam before. Check the addresses with the customer.",
        "bodySpam": "The customer marked the email with {document} {number} as spam.",
        "documentInvoice": "invoice",
        "documentQuotation": "quotation",
        "documentReceipt": "receipt"
      }
    }
  },
  "x_salesreceipts_0": {
    "download": "Download",
    "downloading": "Downloading...",
    "toastDownloadFailed": "Failed to download receipt PDF",
    "paymentMethodBankTransfer": "Bank transfer",
    "paymentMethodCash": "Cash",
    "paymentMethodCard": "Card",
    "paymentMethodCheque": "Cheque",
    "paymentMethodOther": "Other",
    "defaultBusinessName": "Your Business",
    "defaultCustomerName": "Customer",
    "defaultRecipientName": "there",
    "emailSubject": "Payment receipt for invoice {invoiceNumber} from {businessName}",
    "envelopeTo": "To:",
    "envelopeFrom": "From:",
    "envelopeSubject": "Subject:",
    "paymentReceived": "Payment received",
    "onDate": "on {date}",
    "acknowledgement": "Hi {name}, thank you for your payment of {amount} {currency} on {date}. Please find your receipt attached.",
    "detailReceipt": "Receipt",
    "detailForInvoice": "For Invoice",
    "detailTo": "To",
    "detailFrom": "From",
    "detailPaymentMethod": "Payment Method",
    "pdfNote": "The full receipt is attached as a PDF for your records.",
    "footerSentVia": "Sent from {businessName} via Groot Finance",
    "resend": "Resend",
    "sendReceipt": "Send Receipt",
    "noEmailTooltip": "Customer has no email address on file",
    "toastResentTo": "Resent receipt to {email}",
    "toastSentTo": "Sent receipt to {email}",
    "toastSendFailed": "Failed to send receipt email",
    "dialogTitleResend": "Resend receipt email",
    "dialogTitleSend": "Send receipt email",
    "dialogDescription": "Review the email below before sending. The receipt PDF will be attached.",
    "cancel": "Cancel",
    "sending": "Sending...",
    "confirmAndSend": "Confirm and send",
    "pdfReceiptFrom": "Receipt from {merchant}",
    "pdfReceiptNumber": "Receipt #{receiptNumber}",
    "pdfAmountPaid": "Amount paid",
    "pdfDatePaid": "Date paid",
    "pdfPaymentMethod": "Payment method",
    "pdfPaymentMethodBankTransfer": "Bank Transfer",
    "pdfPaymentMethodCash": "Cash",
    "pdfPaymentMethodCard": "Card",
    "pdfPaymentMethodCheque": "Cheque",
    "pdfPaymentMethodOther": "Other",
    "pdfSummary": "Summary",
    "pdfPaymentForInvoice": "Payment for invoice {invoiceNumber}",
    "pdfBalanceOnInvoice": "Balance on invoice",
    "pdfReceivedFrom": "Received from",
    "pdfTinPrefix": "TIN: {tin}",
    "pdfBrnPrefix": "BRN: {brn}",
    "pdfNotes": "Notes",
    "pdfQuestionsEmailAndPhone": "If you have any questions, contact us at {email} or call at {phone}.",
    "pdfQuestionsEmailOnly": "If you have any questions, contact us at {email}.",
    "pdfQuestionsPhoneOnly": "If you have any questions, call at {phone}.",
    "pdfThankYou": "Thank you for your payment.",
    "pdfRegPrefix": "Reg: {reg}",
    "pdfLegalTinPrefix": "TIN: {tin}",
    "pdfDefaultBusinessName": "Your Business",
    "pdfErrors": {
      "notFound": "We couldn't find that receipt. Refresh the page and try again.",
      "forbidden": "You don't have permission to download this receipt.",
      "generic": "We couldn't prepare that PDF. Please try again in a moment."
    }
  },
  "x_inventory_0": {
    "receiveSplit": {
      "title": "Split across locations",
      "splitAction": "Split across locations",
      "useOneLocation": "Use one location",
      "addLocation": "Add location",
      "locationLabel": "Location {number}",
      "quantityLabel": "Quantity for location {number}",
      "removePart": "Remove location {number}",
      "allocated": "Allocated {allocated} of {total}",
      "allocatedWithUnit": "Allocated {allocated} of {total} {unit}",
      "bulkKeepsSplits": "Split lines keep their own locations.",
      "blockedSummary": "{count} split line(s) need fixing before you can receive.",
      "issues": {
        "location_missing": "Choose a location for every row.",
        "location_duplicate": "Use each location only once.",
        "quantity_invalid": "Every row needs a quantity above 0.",
        "under_allocated": "{remaining} still to allocate.",
        "over_allocated": "{remaining} more than this line has."
      }
    },
    "emptyStock": "No stock data for this item.",
    "stockByLocation": "Stock by Location",
    "total": "Total: {count}",
    "low": "Low",
    "receiveToInventory": "Receive to Inventory",
    "applyToAll": "Apply to all:",
    "selectLocation": "Select location",
    "itemNumber": "Item {number}",
    "qtyLine": "Qty: {quantity} × {currency} {price}",
    "track": "Track",
    "catalogItem": "Catalog Item",
    "catalogItemPlaceholder": "Search existing catalog item...",
    "mapInIncoming": "Map this line in Incoming",
    "matched": "Matched",
    "location": "Location",
    "itemsReady": "item(s) matched and ready to receive.",
    "itemsNeedMatch": "{count} tracked item(s) need a catalog match before receiving.",
    "cancel": "Cancel",
    "receiving": "Receiving...",
    "receiveItems": "Receive {count} Items",
    "receiveFailed": "Inventory receipt failed. Check the invoice, product, and location, then try again.",
    "modal": {
      "inventoryManagedInSql": "Stock managed in SQL Account",
      "inventoryManagedInSqlDescription": "Stock is managed in SQL Account for this business. Inventory is raised when the itemized Purchase Invoice is imported into SQL. Groot does not also raise it.",
      "done": "Done"
    },
    "howItWorksTitle": "How Inventory Tracking Works",
    "howItWorksIntro": "Track what you buy, where you store it, and what you sell. It all connects to your accounting.",
    "step1Title": "Set up locations",
    "step1Body": "Create warehouses, offices, or retail outlets where you store stock.",
    "step2Title": "Receive from AP invoices",
    "step2Body": "When you review a purchase invoice, click \"Receive to Inventory\" to stock in items at a location.",
    "step3Title": "Track stock levels",
    "step3Body": "See current quantities per product per location, with low-stock alerts.",
    "step4Title": "Fulfill with Delivery Orders",
    "step4Body": "Use Delivery Orders to reserve and issue stock. Existing businesses can keep invoice-send stock deduction in settings.",
    "step5Title": "Adjust for discrepancies",
    "step5Body": "Manual adjustments for damaged goods, stocktake corrections, or samples.",
    "movementTypes": "Movement Types",
    "stockIn": "Stock In",
    "stockInDesc": "Goods received from purchase",
    "stockOut": "Stock Out",
    "stockOutDesc": "Goods issued through Delivery Orders or compatibility invoice-send mode",
    "adjustment": "Adjustment",
    "adjustmentDesc": "Manual correction (damage, stocktake)",
    "tips": "Tips",
    "tip1": "Start with one default location. You can add more later.",
    "tip2": "Service items are automatically excluded from inventory tracking.",
    "tip3": "Draft sales invoices don't affect stock. Delivery Orders control committed and fulfilled quantities.",
    "tip4": "Voiding an invoice releases reservations or reverses posted Delivery Orders when linked.",
    "editLocation": "Edit Location",
    "addLocation": "Add Location",
    "nameLabel": "Name *",
    "namePlaceholder": "e.g., HQ, Warehouse A, Johor Branch",
    "addressLabel": "Address",
    "addressPlaceholder": "Physical address (optional)",
    "typeLabel": "Type",
    "typeWarehouse": "Warehouse",
    "typeOffice": "Office",
    "typeRetail": "Retail",
    "typeOther": "Other",
    "defaultLocation": "Default Location",
    "defaultLocationHint": "Auto-selected when receiving inventory",
    "saving": "Saving...",
    "update": "Update",
    "create": "Create",
    "transfer": "Transfer",
    "emptyMovements": "No movement history for this item.",
    "movementHistory": "Movement History",
    "packReceiving": {
      "previewTitle": "Pack preview",
      "sourceToBase": "{sourceQuantity} {sourceUom} -> {baseQuantity} {baseUom}",
      "confirmedPack": "Confirmed pack: {sourceQuantity} {purchaseUom} = {baseQuantity} {baseUom}",
      "baseQuantity": "Receives {quantity} {baseUom}",
      "netBaseUnitCost": "{cost}/{baseUom} net",
      "capitalizationTotal": "Capitalises {total}",
      "blockedTitle": "Review pack before receiving",
      "blockedSummary": "{count} line(s) need Products > Needs review before receiving.",
      "sourceEvidence": "Source line: {quantity} {sourceUom}",
      "suggestedPack": "Suggested pack: 1 {purchaseUom} = {baseQuantity} {baseUom}",
      "activeDefault": "Current default: 1 {purchaseUom} = {baseQuantity} {baseUom}",
      "reviewLink": "Open Products > Needs review",
      "reasons": {
        "no_vendor": "Confirm the supplier before Groot can decide which pack mapping applies.",
        "no_catalog_item": "Pick the Stock Item before receiving this supplier pack.",
        "missing_base_uom": "The Stock Item needs a base UOM before packs can become stock.",
        "missing_pack_contents": "Confirm how many base units are inside this supplier pack.",
        "ambiguous_pack_contents": "The source gives more than one plausible pack size. Confirm the real contents first.",
        "pack_changed": "The observed pack differs from the active supplier default. Review it before receiving.",
        "base_uom_conflict": "The supplier pack points at a different base UOM than the Stock Item.",
        "multiple_active_pack_mappings": "More than one active supplier pack matched. Review the defaults before receiving.",
        "unconfirmed_catalog_mapping": "Confirm the supplier item match before its pack can affect stock."
      }
    }
  },
  "x_inventory_1": {
    "title": "Stock Adjustment",
    "current": "Current",
    "adjustment": "Adjustment",
    "adjustmentPlaceholder": "+5 or -3",
    "newQty": "New Qty",
    "reasonLabel": "Reason *",
    "reasonPlaceholder": "e.g., Damaged in transit, Stocktake correction, Samples given away",
    "cancel": "Cancel",
    "adjusting": "Adjusting...",
    "confirmAdjustment": "Confirm Adjustment"
  },
  "x_payables_0": {
    "cancel": "Cancel",
    "close": "Close",
    "saving": "Saving...",
    "addVendor": "Add Vendor",
    "createVendor": "Create Vendor",
    "newVendor": "New Vendor",
    "backToVendorList": "Back to Vendor List",
    "searchPlaceholder": "Search vendors by name, email, or category...",
    "loadingVendors": "Loading vendors...",
    "totalCount": "{count} vendor{count, plural, one {} other {s}} total",
    "status": {
      "active": "Active",
      "prospective": "Prospective",
      "inactive": "Inactive"
    },
    "filter": {
      "allStatuses": "All Statuses"
    },
    "selfBilled": {
      "title": "Self-Billed E-Invoice",
      "description": "Auto-generate self-billed e-invoices for vendors who don't issue their own. Required for LHDN tax compliance when purchasing from exempt suppliers."
    },
    "form": {
      "namePlaceholder": "Vendor name *",
      "emailPlaceholder": "Email",
      "phonePlaceholder": "Phone",
      "categoryPlaceholder": "Category",
      "addressPlaceholder": "Street address"
    },
    "empty": {
      "noVendorsFound": "No vendors found",
      "noVendorsYet": "No vendors yet",
      "adjustSearch": "Try adjusting your search or filter.",
      "autoCreatedHint": "Vendors are auto-created from invoice processing, or add one manually."
    },
    "table": {
      "vendor": "Vendor",
      "code": "Code",
      "category": "Category",
      "paymentTerms": "Payment Terms",
      "contact": "Contact",
      "outstanding": "Outstanding",
      "status": "Status",
      "actions": "Actions"
    },
    "action": {
      "viewEdit": "View / Edit",
      "deactivate": "Deactivate",
      "reactivate": "Reactivate"
    },
    "paymentTerms": {
      "due_on_receipt": "Due on Receipt",
      "net_14": "Net 14",
      "net_15": "Net 15",
      "net_30": "Net 30",
      "net_60": "Net 60",
      "custom": "Custom"
    },
    "matchingSettings": {
      "title": "Matching Settings",
      "saveError": "Failed to save settings",
      "saveSettings": "Save Settings",
      "quantityTolerance": "Quantity Tolerance",
      "quantityToleranceHint": "Variances below this threshold are auto-approved",
      "priceTolerance": "Price Tolerance",
      "priceToleranceHint": "Price differences below this threshold are auto-approved",
      "poNumberPrefix": "PO Number Prefix",
      "grnNumberPrefix": "GRN Number Prefix",
      "autoMatch": "Auto-match",
      "autoMatchHint": "Automatically match invoices to POs by reference number"
    },
    "matchReview": {
      "title": "Match Review",
      "unknownPo": "Unknown PO",
      "unknownVendor": "Unknown Vendor",
      "threeWayMatch": "3-Way Match",
      "twoWayMatch": "2-Way Match",
      "notesRequired": "Notes are required for reject and hold actions",
      "reviewError": "Failed to review match",
      "aiEnhancedMatch": "AI-Enhanced Match (Tier 2)",
      "confidence": "{percent}% confidence",
      "optimizedModel": "Optimized model",
      "grootInsight": "Groot Insight",
      "varianceDiagnosis": "Variance Diagnosis",
      "grnIssue": "\"{item}\": Invoice claims {invQty} units but only {grnQty} were received via GRN",
      "lineN": "Line {n}",
      "deliveryVerified": "Delivery Verified: All invoice quantities confirmed by Goods Received Notes",
      "deliveryMismatch": "Delivery Mismatch: Invoice exceeds received quantities",
      "totalVariances": "Total Variances",
      "exceedsTolerance": "Exceeds Tolerance",
      "maxPriceVariance": "Max Price Variance",
      "maxQtyVariance": "Max Qty Variance",
      "aiConfidence": "AI confidence: {percent}%",
      "varianceBadge": "{label} ({percent}%)",
      "ok": "OK",
      "reviewNotes": "Review Notes",
      "reviewNotesPlaceholder": "Required for reject/hold actions...",
      "previousReviewNotes": "Previous Review Notes",
      "hold": "Hold",
      "reject": "Reject",
      "approve": "Approve",
      "table": {
        "item": "Item",
        "poQty": "PO Qty",
        "poPrice": "PO Price",
        "grnQty": "GRN Qty",
        "invQty": "Inv Qty",
        "invPrice": "Inv Price",
        "variances": "Variances"
      }
    },
    "variance": {
      "quantity_over_invoiced": "Over Invoiced",
      "quantity_under_invoiced": "Under Invoiced",
      "price_higher": "Price Higher",
      "price_lower": "Price Lower",
      "over_received": "Over Received",
      "missing_grn": "Missing GRN"
    },
    "paymentRecorder": {
      "title": "Record Payment",
      "unknownVendor": "Unknown",
      "vendor": "Vendor",
      "totalAmount": "Total Amount",
      "outstanding": "Outstanding",
      "invoiceNumber": "Invoice #",
      "paymentAmount": "Payment Amount *",
      "paymentDate": "Payment Date *",
      "paymentMethod": "Payment Method",
      "paymentReferenceLabel": "Bank Reference (optional)",
      "paymentReferencePlaceholder": "e.g. CHQ-100234 or TRF-20260803-01",
      "paymentReferenceHelp": "The cheque or transfer reference. Adding it lets bank reconciliation match this payment automatically.",
      "notes": "Notes",
      "notesPlaceholder": "Optional notes...",
      "recording": "Recording...",
      "recordPayment": "Record Payment",
      "postFirst": "Post this invoice to AP before recording payment.",
      "alreadyPaid": "This invoice is already fully paid.",
      "creditNote": "This is a credit note. It reduces what you owe, so there is nothing to pay on it.",
      "amountGreaterThanZero": "Amount must be greater than 0",
      "amountExceedsOutstanding": "Amount cannot exceed outstanding balance ({amount})",
      "dateRequired": "Payment date is required",
      "errors": {
        "bankAccountNotFound": "That bank account is not in your chart of accounts. Pick one from the list, or add it in Accounting → Chart of Accounts.",
        "bankAccountInactive": "That bank account is archived. Pick an active one.",
        "bankAccountWrongType": "That account can't hold money. Pick a bank or cash account.",
        "bankAccountIsHeading": "That account is a heading with sub-accounts. Pick one of its sub-accounts instead.",
        "postingAccountNotConfigured": "Your chart of accounts is missing an account this payment needs. Add or designate it on Accounting → Chart of Accounts, then try again.",
        "postingAccountIsHeading": "An account this payment posts to is a heading with sub-accounts, so it can't take postings. Designate one of its sub-accounts on Accounting → Chart of Accounts.",
        "bankAccountRequired": "Choose the bank account this money moves through before recording the payment.",
        "postFirst": "Post this invoice to AP before recording payment.",
        "alreadyPaid": "This invoice is already fully paid.",
        "creditNote": "This is a credit note. It reduces what you owe, so there is nothing to pay on it.",
        "notACredit": "That document is a bill, not a credit note, so it can't be used to reduce this payment. Add it to the invoices you are paying instead.",
        "exceedsOutstanding": "Payment amount cannot exceed the outstanding balance.",
        "fullApRequired": "Full AP is required to record Purchase Invoice payments.",
        "notAuthorized": "You need finance access to record Purchase Invoice payments.",
        "generic": "Failed to record payment. Please check the invoice and try again.",
        "onHold": "This invoice is on payment hold. Release it before paying.",
        "amountNotPositive": "Enter an amount greater than 0.",
        "invoiceNotFound": "One of the selected invoices is no longer available. Refresh and try again.",
        "holdReasonTooLong": "That hold reason is too long. Keep it under 500 characters.",
        "totalMismatch": "The total leaving the bank does not match what you allocated. Nothing was recorded.",
        "noAllocations": "Tick at least one invoice to pay.",
        "tooManyAllocations": "That is too many invoices for one payment. Split it into smaller runs.",
        "duplicateAllocation": "The same invoice was selected twice. Refresh and try again.",
        "currencyMismatch": "All invoices in one payment must share a currency. Pay the others separately.",
        "vendorMismatch": "All invoices in one payment must belong to the same supplier.",
        "creditsOnlyRun": "This run only has credit notes in it. Add the bills the credits should come off, or record the refund separately if the supplier is paying you back.",
        "openingContraNotPayable": "This carried-forward supplier balance is a debit, so it cannot be paid as an accounts-payable invoice.",
        "vendorRosterScanIncomplete": "The supplier list is too large to verify this payment safely. Contact support before recording the payment.",
        "invoiceLedgerLineCap": "A selected invoice has too many journal lines to verify its payable balance safely. Contact support before recording this payment.",
        "openingLedgerBasisMissing": "A selected invoice has no posted payable balance that can be cleared safely. Refresh the invoice and contact support if it remains unavailable.",
        "openingItemNotFound": "One of the carried-forward invoices is no longer available. Refresh and try again.",
        "openingItemVendorInvalid": "A carried-forward invoice no longer belongs to an active supplier. Update the supplier record before paying it.",
        "openingRequestInvalid": "This carried-forward payment could not be identified safely. Refresh and try again.",
        "openingRequestReused": "This carried-forward payment was already recorded. Refresh to see the latest balances.",
        "openingItemAmountInvalid": "The amount for a carried-forward invoice must be positive and no greater than its outstanding balance.",
        "fxRateUnresolvedNoAddon": "There is no exchange rate for this currency on that day. Enter the amount your bank debited.",
        "fxRateUnresolved": "There is no exchange rate for this currency on that day. Enter the amount your bank debited, or add a rate under Accounting → Chart of Accounts → Currencies & rates.",
        "apHomeAmountInvalid": "Enter the amount your bank debited as a positive number with at most two decimals.",
        "apHomeAmountNotApplicable": "A home-currency amount only applies when a foreign bill is paid from a home-currency bank account. Clear that amount or pick another account.",
        "apFxRunMixedBasis": "These bills cannot be paid together, because some were booked at an exchange rate and some were not. Pay them in separate payments.",
        "apFxRunOpeningItems": "Carried-forward opening invoices cannot be paid in the same payment as foreign bills booked at an exchange rate. Pay them separately.",
        "apFxLedgerBasisMissing": "The books carry nothing further to clear for one of these bills. Refresh the page, and contact support if it stays this way.",
        "apFxPlanUnavailable": "This payment could not be priced, so nothing was recorded. Refresh and try again.",
        "apPaymentCurrencyMismatch": "This bill is in a different currency from the selected bank account. Pick a home-currency account, or one in the currency of the bill."
      },
      "onHold": "This invoice is on payment hold. Release it before paying.",
      "fx": {
        "homeDebitedLabel": "{currency} debited",
        "homeDebitedLabelGeneric": "Amount debited in your home currency",
        "estimatedAt": "Estimated at the {date} rate",
        "estimatedManual": "Estimated at your own rate for {date}",
        "impliedRate": "Works out to {rate} per {currency}",
        "working": "Working out the amount...",
        "rateMissing": "No exchange rate was found for that day. Enter the amount your bank debited.",
        "realisedLoss": "{amount} realised loss",
        "realisedGain": "{amount} realised gain",
        "noDifference": "No exchange difference",
        "carriedVsPaid": "The books carry {carried}; the bank is paid {paid}.",
        "foreignBank": "Paid from your {currency} account, valued in the books at {amount} (rate {rate}).",
        "fromBankLine": "Taken from the bank line"
      },
      "bankLine": {
        "title": "Pay from bank line",
        "intro": "This payment is created from the bank statement line, and the line is matched as soon as you confirm.",
        "statementAmount": "Amount debited by the bank",
        "statementAmountHelp": "Taken from the statement. It sets the {homeCurrency} amount of this payment.",
        "payFrom": "Paid from",
        "payFromHelp": "The bank account this statement line is on.",
        "loading": "Loading the bank line...",
        "confirm": "Confirm payment",
        "unavailable": "This bank line is not available. Close this and open it again from Bank and Cash.",
        "reasons": {
          "not_found": "This bank line is no longer available.",
          "not_debit": "Only a bank debit can be used to pay a bill.",
          "bank_currency_unsupported": "This bank account is not in your home currency, so a payment cannot be created from its lines yet.",
          "bank_unlinked": "This bank account is not linked to your chart of accounts yet.",
          "already_matched": "This bank line has already been matched."
        },
        "errors": {
          "notApplicable": "A payment can be created from a bank line only for a foreign-currency bill. Pick a foreign-currency bill, or record this payment without the bank line.",
          "accountMismatch": "The payment must be made from the bank account this line is on.",
          "amountMismatch": "The bank line shows {amount}, which is different from the amount on this payment. Close this and open the bank line again, then confirm.",
          "humanRequired": "A payment from a bank line has to be confirmed by a person in the app."
        },
        "banner": {
          "text": "Paying from a bank line: choose the foreign-currency bill this payment is for.",
          "cancel": "Cancel"
        }
      }
    },
    "paymentMethod": {
      "bank_transfer": "Bank Transfer",
      "cash": "Cash",
      "cheque": "Cheque",
      "card": "Card",
      "other": "Other"
    },
    "drilldown": {
      "unpaidBills": "{count} unpaid bill{count, plural, one {} other {s}}",
      "noUnpaidBills": "No unpaid bills for this vendor",
      "daysOverdue": "{days}d overdue",
      "daysRemaining": "{days}d remaining",
      "pay": "Pay",
      "table": {
        "reference": "Reference",
        "amount": "Amount",
        "outstanding": "Outstanding",
        "dueDate": "Due Date",
        "status": "Status",
        "action": "Action"
      },
      "held": "On hold",
      "payBySupplier": "Pay supplier"
    },
    "agingIncompleteWarning": "Totals exclude amounts in {currencies} because no exchange rate is set. Add a manual exchange rate on Accounting → Chart of Accounts to include them.",
    "vendor": {
      "itemsSupplied": {
        "title": "Items supplied",
        "businessInformation": "Business information",
        "empty": "No purchased items have been recorded for this supplier yet.",
        "itemCode": "Item code",
        "description": "Description",
        "latestPrice": "Latest price",
        "latestQuantity": "Last quantity",
        "catalogItem": "Product catalog",
        "mapped": "Mapped",
        "draft": "Needs review",
        "loadMore": "Load more",
        "error": "We couldn't load supplier items. Your existing information is unchanged.",
        "retry": "Try again",
        "grootSku": "Groot SKU",
        "pack": "Pack conversion",
        "packConversion": "{baseQuantity} {baseUnitCode} per {purchaseUnitCode}",
        "noPack": "No confirmed pack",
        "status": "Status",
        "statusMapped": "Mapped",
        "statusInactive": "Inactive",
        "statusRefused": "Refused",
        "statusUnmapped": "Not mapped",
        "lastSource": "Last observed source",
        "openSource": "Open source",
        "mapToStockItem": "Map to Stock Item",
        "changeStockItem": "Change Stock Item",
        "openStockItem": "Open Stock Item",
        "actions": "Actions",
        "unavailable": "This supplier's items could not be loaded for your account.",
        "statusDuplicateSuperseded": "Superseded duplicate",
        "statusSourceDeleted": "Discarded invoice"
      }
    },
    "viewCurrency": {
      "label": "View in",
      "indicativeNote": "Converted at today's rate (indicative)",
      "rateUnavailable": "Rate unavailable, so amounts are shown in {currency}"
    },
    "payRun": {
      "back": "Back",
      "unassignedVendor": "Unassigned supplier",
      "openSummary": "{count} open · {amount}",
      "heldSummary": "{count} on hold",
      "selectAll": "Select all payable",
      "clear": "Clear",
      "empty": "No open bills for this supplier",
      "hold": "Hold",
      "release": "Release",
      "paymentSection": "Payment details",
      "allocated": "Allocated across {count} invoice{count, plural, one {} other {s}}",
      "paymentTotal": "Total leaving the bank",
      "creditsApplied": "Credits applied",
      "submit": "Pay {count} invoice{count, plural, one {} other {s}} · {amount}",
      "success": "Recorded {amount} across {count} invoice{count, plural, one {} other {s}}.",
      "selectInvoice": "Select invoice {reference}",
      "amountFor": "Amount to pay for invoice {reference}",
      "column": {
        "age": "Age",
        "payAmount": "Pay"
      },
      "badge": {
        "held": "On hold",
        "notPosted": "Not posted",
        "settled": "Settled",
        "creditNote": "Credit note",
        "creditAvailable": "Credit available",
        "creditUsed": "Credit used",
        "otherCurrency": "{currency}: pay separately"
      },
      "errors": {
        "selectAtLeastOne": "Tick at least one invoice to pay.",
        "lineOutOfRange": "One line is more than that invoice still owes. Lower it and try again.",
        "overpayment": "The payment is {amount} more than the invoices you ticked. Allocate it, or lower the total.",
        "underpayment": "The payment is {amount} less than the invoices you ticked. Reduce a line, or raise the total."
      },
      "reversalTitle": "Recent carried-forward payments",
      "reversalDescription": "Reverse the complete payment when it covered both current and carried-forward invoices.",
      "loadOlderRuns": "Load older payments",
      "loadingOlderRuns": "Loading older payments",
      "reversalReasonPlaceholder": "Reason for reversing this payment",
      "reversalReasonRequired": "Enter a reason before reversing the payment.",
      "reversePayment": "Reverse payment",
      "reversalSuccess": "The complete supplier payment was reversed.",
      "reversalFailed": "This complete supplier payment could not be reversed. Nothing was changed. Refresh and try again.",
      "truncated": "This list may be incomplete because you have more open supplier bills than one screen can load. Pay what is shown, then reload."
    },
    "affiliate": {
      "status": {
        "inactive": "Inactive",
        "pending": "Pending approval",
        "rejected": "Rejected"
      },
      "tag": "Affiliate",
      "filter": "Affiliates"
    },
    "paymentHistory": {
      "bankPaid": "Bank paid {amount} at {rate} per {currency}",
      "estimated": "Estimated",
      "voidLabel": "Void",
      "noVoucher": "No voucher"
    },
    "paymentFxNote": {
      "estimated": "Estimated",
      "truedUpLoss": "Stated, trued up {amount} (loss)",
      "truedUpGain": "Stated, trued up {amount} (gain)"
    }
  },
  "x_payables_1": {
    "poSettings": "Purchase order settings",
    "errorReceiptQuantity": "The received quantity is greater than the quantity still open on this order. Check the line quantities and try again.",
    "errorPoChanged": "This purchase order changed while you were receiving it. Close this form, review the latest order, and try again.",
    "vendorPriceAlerts": "Vendor Price Alerts",
    "activeCount": "{count} active",
    "highImpactCount": "{count} high impact",
    "statusPlaceholder": "Status",
    "allStatus": "All Status",
    "active": "Active",
    "dismissed": "Dismissed",
    "severityPlaceholder": "Severity",
    "allSeverity": "All Severity",
    "standard": "Standard",
    "highImpact": "High Impact",
    "alertTypePlaceholder": "Alert Type",
    "allTypes": "All Types",
    "priceIncrease": "Price Increase",
    "trailingAvgSpike": "Trailing Avg Spike",
    "newCharge": "New Charge",
    "frequencyChange": "Frequency Change",
    "reset": "Reset",
    "noPriceAlerts": "No price alerts found",
    "noPriceAlertsHint": "Alerts appear here when price anomalies are detected from purchase invoices",
    "goodsReceivedNotes": "Goods Received Notes",
    "createGRN": "Create GRN",
    "noGoodsReceivedNotes": "No goods received notes found",
    "createFirstGRN": "Create your first GRN",
    "grnNumber": "GRN Number",
    "vendor": "Vendor",
    "poNumber": "PO Number",
    "date": "Date",
    "items": "Items",
    "purchaseOrders": "Purchase Orders",
    "purchaseOrdersLoadFailed": "Purchase orders could not be loaded. Refresh and try again.",
    "createPO": "Create PO",
    "searchPONumber": "Search PO number...",
    "allStatuses": "All Statuses",
    "noPurchaseOrders": "No purchase orders found",
    "createFirstPO": "Create your first PO",
    "totalAmount": "Total Amount",
    "status": "Status",
    "lines": "Lines",
    "poStatusDraft": "Draft",
    "poStatusIssued": "Issued",
    "poStatusPartial": "Partial",
    "poStatusReceived": "Received",
    "poStatusInvoiced": "Invoiced",
    "poStatusClosed": "Closed",
    "poStatusCancelled": "Cancelled",
    "matchRecords": "Match Records",
    "filterAll": "All",
    "noMatchRecords": "No match records found",
    "invoiceVendor": "Invoice / Vendor",
    "matchType": "Match Type",
    "variances": "Variances",
    "invoicePrefix": "Inv: {number}",
    "threeWay": "3-Way",
    "twoWay": "2-Way",
    "matchStatusAutoApproved": "Auto Approved",
    "matchStatusPendingReview": "Pending Review",
    "matchStatusApproved": "Approved",
    "matchStatusDisputed": "Disputed",
    "matchStatusOnHold": "On Hold",
    "errorSelectVendor": "Please select a vendor",
    "errorAddLineItem": "Add at least one line item",
    "errorLineItemDescription": "All line items must have a description",
    "errorCreateGRN": "Failed to create GRN",
    "errorPoNotReceivable": "This purchase order is a draft, cancelled or closed, so goods can't be received against it. Issue the purchase order first, or pick a different one.",
    "createGoodsReceivedNote": "Create Goods Received Note",
    "purchaseOrderOptional": "Purchase Order (optional)",
    "standaloneGRN": "Standalone GRN (no PO)",
    "vendorRequired": "Vendor *",
    "selectVendor": "Select vendor...",
    "grnDateRequired": "GRN Date *",
    "lineItems": "Line Items",
    "importCSV": "Import CSV",
    "csvColumnsHint": "CSV columns: Description, Quantity Received, Condition",
    "addLine": "+ Add Line",
    "loadingPOLineItems": "Loading PO line items...",
    "loadMorePurchaseOrders": "Load more purchase orders",
    "loadingMorePurchaseOrders": "Loading more purchase orders…",
    "addLineItemsOrImport": "Add line items or import from CSV",
    "ordered": "Ordered: {qty}",
    "receivedQtyRequired": "Received Qty *",
    "rejectedQty": "Rejected Qty",
    "condition": "Condition",
    "conditionGood": "Good",
    "conditionDamaged": "Damaged",
    "conditionRejected": "Rejected",
    "notes": "Notes",
    "notesPlaceholder": "Optional notes...",
    "cancel": "Cancel",
    "saving": "Saving..."
  },
  "x_payables_2": {
    "title": "Aged Payables by Vendor",
    "emptyState": "No outstanding payables",
    "totalRow": "Total",
    "billCount": "{count, plural, one {# bill} other {# bills}}",
    "column": {
      "vendor": "Vendor",
      "current": "Current",
      "days1to30": "1-30 days",
      "days31to60": "31-60 days",
      "days61to90": "61-90 days",
      "days90plus": "90+ days",
      "total": "Total"
    },
    "upcoming": {
      "title": "Upcoming Payments",
      "periodLabel": "{days} days",
      "emptyState": "No payments due in the next {days} days",
      "daysOverdue": "{days}d overdue",
      "dueToday": "Due today",
      "daysRemaining": "{days}d",
      "payButton": "Pay",
      "column": {
        "vendor": "Vendor",
        "amount": "Amount",
        "dueDate": "Due Date",
        "days": "Days",
        "action": "Action"
      }
    },
    "unmatched": {
      "title": "Unmatched Documents",
      "emptyState": "No unmatched documents found",
      "badgeUnmatched": "Unmatched",
      "statusOpen": "Open",
      "daysShort": "{days}d",
      "daysAgo": "{days}d ago",
      "tab": {
        "posWithoutInvoices": "POs without Invoices",
        "invoicesWithoutPos": "Invoices without POs",
        "posWithoutGrns": "POs without GRNs"
      },
      "sort": {
        "mostOverdue": "Most overdue first",
        "newest": "Newest first",
        "oldest": "Oldest first"
      },
      "column": {
        "reference": "Reference",
        "poNumber": "PO Number",
        "vendor": "Vendor",
        "date": "Date",
        "amount": "Amount",
        "age": "Age",
        "status": "Status"
      }
    },
    "po": {
      "paymentTerms": "Payment terms",
      "deliveryTerms": "Delivery terms",
      "exchangeRate": "Exchange rate",
      "dimensions": "Reporting dimensions",
      "notSet": "Not set",
      "unknownRateSource": "Source not recorded",
      "openApInvoice": "Open AP invoice",
      "revise": "Revise",
      "submit": "Submit",
      "approve": "Approve",
      "accept": "Accept",
      "convertToInvoice": "Convert to AP invoice",
      "notFoundTitle": "Purchase order not found",
      "notFoundBody": "This order may have been removed or may belong to another business.",
      "backToOrders": "Back to purchase orders",
      "errors": {
        "stale": "This purchase order changed. Review the latest version and try again.",
        "invalidStatus": "This action is no longer available for the purchase order's current status.",
        "notAuthorized": "Only an authorized purchase approver can perform this action.",
        "actionFailed": "We couldn't update this purchase order. Review its current status and try again.",
        "loadFailed": "This purchase order could not be loaded. Close it and try again."
      },
      "unknownVendor": "Unknown Vendor",
      "poDate": "PO Date",
      "deliveryDate": "Delivery Date",
      "currency": "Currency",
      "totalAmount": "Total Amount",
      "lineItems": "Line Items",
      "notes": "Notes",
      "linkedGrns": "Linked GRNs ({count})",
      "linkedMatches": "Linked Matches ({count})",
      "issuePo": "Issue PO",
      "recordGrn": "Record GRN",
      "cancelPo": "Cancel PO",
      "status": {
        "draft": "Draft",
        "issued": "Issued",
        "partial": "Partial",
        "received": "Received",
        "invoiced": "Invoiced",
        "closed": "Closed",
        "cancelled": "Cancelled"
      },
      "column": {
        "item": "Item",
        "qty": "Qty",
        "received": "Received",
        "price": "Price",
        "total": "Total"
      },
      "match": {
        "threeWay": "3-Way Match",
        "twoWay": "2-Way Match"
      }
    },
    "vendor": {
      "detail": {
        "identitySection": "Identity & Tax",
        "contactSection": "Contact",
        "addressSection": "Address",
        "supplierCode": "Supplier Code",
        "companyName2": "Company Name 2",
        "brn": "Business Registration No. (BRN)",
        "tin": "Tax ID (TIN)",
        "sstRegistration": "SST Registration",
        "gstRegistration": "GST Registration",
        "businessNature": "Business Nature",
        "creditLimit": "Credit Limit",
        "defaultCurrency": "Default Currency",
        "branchName": "Branch"
      },
      "statusActive": "Active",
      "statusInactive": "Inactive",
      "save": "Save",
      "edit": "Edit",
      "outstandingPayables": "Outstanding Payables",
      "unpaidBills": "{count, plural, one {# unpaid bill} other {# unpaid bills}}",
      "paymentTerms": "Payment Terms",
      "notSet": "Not set",
      "daysPlaceholder": "Days",
      "customDaysSuffix": " ({days} days)",
      "contactPerson": "Contact Person",
      "streetAddress": "Street address",
      "contactNamePlaceholder": "Contact name",
      "website": "Website",
      "notes": "Notes",
      "bankDetails": "Bank Details",
      "lhdnExemptBadge": "LHDN Exempt (self-billing required)",
      "lhdnExemptToggle": "LHDN Exempt Vendor",
      "lhdnExemptHelp": "Self-billed e-invoices will be generated for purchases from this vendor.",
      "priceAlerts": "Price Alerts",
      "moreAlerts": "+{count} more alerts (view in Action Center)",
      "noIntelligenceYet": "No supplier intelligence yet. It appears once invoices from this vendor are processed.",
      "paymentTermsOption": {
        "dueOnReceipt": "Due on Receipt",
        "net14": "Net 14",
        "net15": "Net 15",
        "net30": "Net 30",
        "net60": "Net 60",
        "custom": "Custom"
      },
      "bankField": {
        "bankName": "Bank Name",
        "accountHolderName": "Account Holder Name",
        "accountNumber": "Account Number",
        "routingCode": "Routing Code"
      },
      "requestInfo": {
        "dialogTitle": "Request info update",
        "dialogDescription": "Ask {name} to review and update their own business details. Choose how to reach them.",
        "emailLabel": "Send via email",
        "emailHint": "We'll email a secure update link to {email}.",
        "emailDisabledNoAddress": "No email address on file. Add one in Edit Details first, or use the QR code.",
        "emailLastSent": "Last sent {hours, plural, one {# hour} other {# hours}} ago.",
        "emailCta": "Send email",
        "emailSending": "Sending…",
        "qrLabel": "Show QR code",
        "qrHint": "Display a QR code and link to share, print, or screenshot.",
        "qrCta": "Show QR code",
        "toastSuccess": "Update request sent to {email}.",
        "toastFailed": "Couldn't send the email. Please try again.",
        "close": "Close",
        "confirmTitle": "Send update request?",
        "confirmBody": "We'll email a secure update link to {email}. They can review and update their own business details.",
        "confirmCta": "Send email",
        "cancel": "Cancel"
      },
      "requestInfoButton": "Request info update",
      "delete": {
        "button": "Delete vendor",
        "confirmTitle": "Delete this vendor?",
        "confirmBody": "This permanently deletes {name} and can't be undone. Vendors with linked bills or transactions can't be deleted. Deactivate them instead.",
        "blockedToast": "This vendor can't be deleted because it has linked bills or transactions. Deactivate it instead.",
        "success": "Vendor deleted",
        "cancel": "Cancel"
      },
      "relatedPartyToggle": "Related party",
      "relatedPartyHelp": "A director, shareholder, or a business under common control. Amounts owed are disclosed separately from trade and other creditors.",
      "openBills": "View and pay open bills",
      "noBankDetails": "No bank details on file",
      "accountSavedSecurely": "Saved securely",
      "duplicateAccountWarning": "Same account number as {names}",
      "removeAccount": "Remove account number",
      "removeAccountConfirm": "Remove the saved account number? Payments to this supplier will need a new number.",
      "removeAccountYes": "Yes, remove",
      "removeAccountKeep": "Keep it",
      "removeAccountDone": "Account number removed",
      "removeAccountFailed": "We could not remove the account number. Please try again.",
      "bankOffer": {
        "action": "Use as vendor bank details",
        "title": "Use as vendor bank details",
        "description": "Check these details against the bill, then save them to {vendor}. Nothing is saved until you confirm.",
        "cardTitle": "A bill lists bank details for this supplier",
        "cardBody": "{bank}, account ending {last4}, from {source}.",
        "fromBill": "bill {number}",
        "fromRecentBill": "a recent bill",
        "unnamedBank": "Bank not named",
        "replacesWarning": "This replaces the account ending {last4} on file. Confirm the change with the supplier before you save.",
        "replacesWarningNoDigits": "This replaces the account on file. Confirm the change with the supplier before you save.",
        "sealedHint": "The account number is stored encrypted. Only the last four digits are shown afterwards.",
        "save": "Save bank details",
        "cancel": "Cancel",
        "saved": "Bank details saved for {vendor}.",
        "failed": "The bank details could not be saved. Check them and try again."
      },
      "bankSave": {
        "vaultUnavailable": "We could not save the account number securely just now. Nothing was saved. Please try again in a few minutes.",
        "invalidNumber": "That account number cannot be saved. Check it and try again. It can be up to 64 characters long.",
        "staleForm": "This page is out of date. Refresh it, then enter the account number again."
      }
    },
    "statement": {
      "button": "Statement",
      "buttonFor": "Statement for {name}"
    }
  },
  "x_payables_3": {
    "errorExchangeRatePositive": "Enter an exchange rate greater than zero in Edit exchange rate.",
    "paymentTerms": "Payment terms",
    "paymentTermsPlaceholder": "For example, Net 30",
    "deliveryTerms": "Delivery terms",
    "deliveryTermsPlaceholder": "For example, DDP Kuala Lumpur",
    "exchangeRate": "Exchange rate",
    "exchangeRatePlaceholder": "Supplier currency to home currency",
    "rateSource": "Rate source",
    "reportingDimensions": "Reporting dimensions",
    "project": "Project",
    "department": "Department",
    "location": "Location",
    "notSet": "Not set",
    "revisionReason": "Reason for revision",
    "revisionReasonPlaceholder": "Explain the commercial change for the audit history",
    "errorRevisionReason": "Explain why this purchase order is changing.",
    "errorInvalidDimension": "Choose a project, department and location from this business.",
    "errorPoChanged": "This purchase order changed. Close this form, review the latest version, and try again.",
    "errorReceivedLinesLocked": "Received line quantities cannot be revised. Create a follow-up order for the remaining change.",
    "errorFinalCannotRevise": "This purchase order is final and can no longer be revised.",
    "errorInvalidLineItems": "Complete every line with a description, positive quantity and non-negative price.",
    "errorCurrencyMismatch": "Every line must use the purchase order currency.",
    "errorAcceptedReissue": "An accepted purchase order cannot be edited in place. Cancel it and issue a replacement order.",
    "errorReceivedAdjustment": "A received purchase order cannot be edited in place. Record a receiving adjustment, or cancel and reissue the remaining commitment.",
    "spendByCategory": "Spend by Category",
    "noCategoryData": "No category data available",
    "topVendorsBySpend": "Top Vendors by Spend",
    "totalLabel": "Total: {amount}",
    "noSpendData": "No spend data available",
    "transactionCount": "{count, plural, one {# transaction} other {# transactions}}",
    "totalMatches": "Total Matches",
    "autoApproved": "Auto Approved",
    "pendingReview": "Pending Review",
    "disputed": "Disputed",
    "threeWayMatching": "3-Way Matching",
    "autoMatchRateLabel": "Auto-match rate:",
    "aiMatchingIntelligence": "AI Matching Intelligence",
    "automationRate": "Automation Rate",
    "timeSaved": "Time Saved",
    "hoursValue": "{hours}h",
    "estReviewHours": "est. review hours",
    "avgAiConfidence": "Avg AI Confidence",
    "noVendorsYet": "No Vendors Yet",
    "priceDataAutoCaptured": "Price data is automatically captured when invoices are processed.",
    "chooseVendor": "Choose a vendor...",
    "suggestMatches": "Suggest Matches",
    "crossVendorGroupsCount": "Cross-Vendor Groups ({count})",
    "vendorsCount": "{count, plural, one {# vendor} other {# vendors}}",
    "badgeAiSuggested": "AI Suggested",
    "badgeConfirmed": "Confirmed",
    "badgeManual": "Manual",
    "priceIntelligenceTitle": "Price Intelligence",
    "priceIntelligenceEmptyDescription": "Select a vendor above to view tracked items, price trends, and cross-vendor comparisons. Click \"{action}\" to let AI find similar items across vendors.",
    "trackedItems": "Tracked Items",
    "noPriceDataForVendor": "No price data for this vendor yet.",
    "pricesRecordedOnProcess": "Prices are recorded when invoices from this vendor are processed.",
    "codeLabel": "Code: {code}",
    "observationCount": "{count, plural, one {# observation} other {# observations}}",
    "priceTrend": "Price Trend",
    "crossVendorComparison": "Cross-Vendor Comparison",
    "loadingComparison": "Loading comparison...",
    "noOtherVendorsSupply": "No other vendors supply this item.",
    "cheapest": "Cheapest",
    "errorSelectVendor": "Please select a vendor",
    "errorEnterPoDate": "Please enter a PO date",
    "errorLineDescriptionRequired": "All line items must have a description",
    "errorQuantityPositive": "All quantities must be greater than 0",
    "errorSaveFailed": "Failed to save purchase order",
    "errorOnlyDraftEditable": "This purchase order has already been issued, so it can no longer be edited. Close this form and raise a new purchase order, or ask an owner to cancel this one.",
    "editPurchaseOrder": "Edit Purchase Order",
    "createPurchaseOrder": "Create Purchase Order",
    "nextPoNumber": "Next: {number}",
    "vendorRequired": "Vendor *",
    "searchVendors": "Search vendors...",
    "selectVendor": "Select vendor...",
    "poDateRequired": "PO Date *",
    "deliveryDate": "Delivery Date",
    "currency": "Currency",
    "lineItemsRequired": "Line Items *",
    "importCsv": "Import CSV",
    "csvColumnsHint": "CSV columns: Description, Quantity, Unit Price",
    "addLine": "Add Line",
    "itemCode": "Item code",
    "descriptionRequired": "Description *",
    "qty": "Qty",
    "uom": "UOM",
    "unitPrice": "Unit price",
    "discountType": "Discount type",
    "discountValue": "Discount value",
    "noDiscount": "No discount",
    "discountPercentage": "Percentage",
    "discountFixed": "Fixed amount",
    "taxRate": "Tax %",
    "totalWithCurrency": "Total: {currency} {amount}",
    "notes": "Notes",
    "optionalNotes": "Optional notes...",
    "cancel": "Cancel",
    "saving": "Saving...",
    "updatePo": "Update PO",
    "saveAsDraft": "Save as Draft"
  },
  "x_payables_4": {
    "title": "Monthly Spend Trend",
    "empty": "No trend data available",
    "txnCount": "{count} txns"
  },
  "x_billing_0": {
    "loadFailed": "We could not load your subscription details.",
    "viewPlans": "View Plans",
    "retry": "Retry",
    "dayProgress": "Day {used}/{total}",
    "celebration": {
      "title": "Welcome to Pro!",
      "subtitle": "Your upgrade is complete"
    },
    "status": {
      "active": "Active",
      "trial": "Trial",
      "pastDue": "Past Due",
      "canceled": "Canceled"
    },
    "successBanner": {
      "title": "Welcome to your new plan!",
      "subtitle": "Your subscription is now active. Enjoy your upgraded features!"
    },
    "canceledBanner": {
      "message": "Checkout was canceled. Your subscription has not changed."
    },
    "countryDeclaration": {
      "title": "Set Up Payment Profile",
      "description": "Verify your business identity to activate your subscription. Your billing currency will be locked based on your registered region.",
      "beforeSubscribe": "Before you subscribe, verify your business identity. Your billing currency will be locked based on your registered region.",
      "registeredCountryLabel": "Registered Region",
      "countryOptions": {
        "MY": "Malaysia",
        "SG": "Singapore",
        "TW": "Taiwan"
      },
      "registration": {
        "MY": {
          "label": "Tax Identification Number (TIN)",
          "placeholder": "e.g. IG24210777100",
          "hint": "Your LHDN TIN. We verify it against MyInvois to confirm your business."
        },
        "SG": {
          "label": "Unique Entity Number (UEN)",
          "placeholder": "e.g. 200012345X",
          "hint": "Your ACRA UEN. We verify the format to confirm your business."
        },
        "TW": {
          "label": "Uniform Business Number (統一編號)",
          "placeholder": "e.g. 12345675",
          "hint": "Your 8-digit Taiwan Uniform Business Number. We verify the checksum to confirm your business."
        }
      },
      "currencyPreview": {
        "prefix": "Your billing currency will be permanently set to",
        "suffix": ". Your operational currency can still be changed in business settings."
      },
      "verifyingButton": "Verifying...",
      "verifyButton": "Verify & Lock Currency",
      "errors": {
        "verificationFailed": "Verification failed",
        "setCountryFailed": "Failed to set region",
        "nameMismatch": "This registration number is registered to a different business. Please use your own business's registration number, or update your business name to match your official registered name."
      }
    },
    "currentPlan": {
      "title": "Current Plan",
      "description": "Your subscription details",
      "planLabel": "Plan",
      "priceLabel": "Price",
      "priceValue": "{currency} {price}/month",
      "billingCurrencyLabel": "Billing Currency",
      "trialPeriodLabel": "Trial Period",
      "trialExpired": "Expired",
      "daysLeft": "{days} days left",
      "nextBillingDateLabel": "Next Billing Date",
      "cancelAtPeriodEnd": "Subscription will cancel at end of period",
      "manageSubscription": "Manage Subscription",
      "portalUnavailable": "We couldn't open the billing portal. Please try again.",
      "upgradeYourPlan": "Upgrade Your Plan",
      "comparePlans": "Compare Plans"
    },
    "ocrUsage": {
      "title": "OCR Usage",
      "description": "Document processing credits this month",
      "documentsProcessed": "documents processed",
      "unlimitedEnterprise": "Unlimited OCR scans with your Enterprise plan",
      "scansUsed": "{used} / {limit} scans used",
      "approachingLimit": "You're approaching your OCR limit. Consider upgrading for more scans."
    },
    "planFeatures": {
      "title": "Plan Features",
      "description": "What's included in your {plan} plan",
      "showLess": "Show less",
      "seeAll": "See all features"
    },
    "card": {
      "unableToLoad": "Unable to load subscription info",
      "heading": "Subscription",
      "freeTrialUpgradeAnytime": "Free trial • Upgrade anytime",
      "pricePerMonth": "{currency} {price}/month",
      "manage": "Manage",
      "ocrScansThisMonth": "OCR Scans this month",
      "scanLimitReached": "Scan limit reached",
      "limitReachedUpgrade": "Limit reached - upgrade to continue scanning"
    },
    "banner": {
      "dismissAriaLabel": "Dismiss banner",
      "proTrialActive": "Pro Trial Active",
      "unlockProFeatures": "Unlock Pro Features",
      "trialExpired": "Trial expired",
      "descriptionPro": "You have full Pro access during your trial. Subscribe to a plan to continue after it ends.",
      "descriptionTrial": "Your trial includes full features. Subscribe to a plan before it expires.",
      "features": {
        "ocrScans": "100+ OCR scans/month",
        "advancedReports": "Advanced reports",
        "prioritySupport": "Priority support"
      }
    },
    "countdown": {
      "freeTrial": "Free Trial",
      "trialExpired": "Trial Expired",
      "daysRemaining": "{days} days remaining",
      "dayOf": "Day {day} of {total}",
      "ends": "Ends {date}",
      "expiredMessage": "Your trial has ended. Upgrade now to continue using all features.",
      "urgentMessage": "Your trial ends soon! Upgrade to keep your data and features.",
      "upgradeNow": "Upgrade Now"
    },
    "assistedActivation": {
      "fullAccessTrial": "Full Access Trial",
      "onboardingTitle": "Your 14-day Full Access Trial",
      "onboardingDescription": "Try Invoicing and Expense Claims with your own records. No card required.",
      "startTrial": "Start Full Access Trial",
      "dashboardDescription": "Try both workflows now. Tell us what you would like to continue with before the trial ends.",
      "chooseCta": "Choose what to continue with",
      "chooseCtaShort": "Choose workflows",
      "trialPrice": "No charge during trial",
      "requestActivation": "Request activation",
      "fallbackName": "Groot Finance customer",
      "fallbackCompany": "Groot Finance business",
      "dialogTitle": "Choose what to continue with",
      "dialogDescription": "Tell us what fits your business. Your full-access trial continues while our team prepares the right plan.",
      "workflowLabel": "Which workflows would you like to keep?",
      "workflow": {
        "supplier-invoices": {
          "label": "Invoicing",
          "description": "Supplier and customer invoices"
        },
        "expense-claims": {
          "label": "Expense Claims",
          "description": "Employee claims and approvals"
        },
        "both": {
          "label": "Both workflows",
          "description": "Invoicing and Expense Claims"
        }
      },
      "cadenceLabel": "Billing preference",
      "cadence": {
        "month": "Monthly",
        "year": "Annual"
      },
      "volumeLabel": "Approximate monthly documents",
      "volume": {
        "up-to-300": "Up to 300",
        "301-to-1000": "301 to 1,000",
        "over-1000-or-unsure": "More than 1,000 / Not sure"
      },
      "emailLabel": "Reply-to email",
      "emailHint": "We will use this address to confirm the plan and activation date.",
      "noteLabel": "Anything else we should know? (optional)",
      "notePlaceholder": "Tell us about timing, integrations or anything unusual about your setup.",
      "submit": "Send plan request",
      "sending": "Sending request...",
      "error": "We could not send your request. Please try again or email hello@hellogroot.com.",
      "loadingBusiness": "Loading your business details...",
      "successTitle": "Request received",
      "successTrial": "Your full-access trial continues as normal, and we will contact you before it ends.",
      "successPaused": "Your data is safe, and we will contact you to activate the right plan.",
      "privacyPrefix": "We use these details only to follow up on this request. See our",
      "privacyLink": "Privacy Policy",
      "pageTitle": "Choose what to continue with",
      "pageDescription": "Your trial includes Invoicing and Expense Claims. Tell us which workflows you want after the trial.",
      "pausedTitle": "Let us activate the right plan",
      "pausedDescription": "Your trial has ended and your data is safe. Send your preference and our team will help you continue.",
      "ownerOnlyTitle": "The account owner needs to choose",
      "ownerOnlyDescription": "Ask the account owner to open Billing and send the plan request."
    },
    "lock": {
      "signOut": "Sign Out",
      "native": {
        "title": "Access Limited",
        "ownerMessage": "Your organization's access is currently inactive. Manage your account to restore access for your team.",
        "memberMessage": "Your organization's access is currently inactive. Please contact your account administrator to restore access.",
        "manageAccount": "Manage Account",
        "dataPreserved": "Your data is preserved."
      },
      "web": {
        "canceled": {
          "title": "Subscription Ended",
          "message": "Your subscription has been canceled. Choose a plan to restore access to Groot Finance. Your data is safe and waiting for you."
        },
        "unpaid": {
          "title": "Payment Required",
          "message": "Your subscription payment is overdue. Please update your payment method or choose a plan to continue."
        },
        "paused": {
          "title": "Free Trial Ended",
          "message": "Your 14-day Pro trial has ended. Choose a plan to continue using Groot Finance. Your data is safe and waiting for you."
        },
        "choosePlan": "Choose a Plan",
        "dataPreserved": "Your data is preserved. Pick up right where you left off."
      }
    }
  },
  "x_billing_1": {
    "errorLoadUsage": "Unable to load usage data",
    "badgeUnlimited": "Unlimited",
    "badgeLimitReached": "Limit Reached",
    "badgeApproachingLimit": "Approaching Limit",
    "badgeGood": "Good",
    "ocrScans": "OCR Scans",
    "ocrUsage": "OCR Usage",
    "ocrUsageDescription": "Document scanning credits for {plan} plan",
    "scansUsedThisMonth": "Scans used this month",
    "slashUnlimited": "/ Unlimited",
    "percentUsed": "{percent}% used",
    "remaining": "{count} remaining",
    "limitReachedTitle": "Limit reached!",
    "runningLowTitle": "Running low on scans",
    "limitReachedDescription": "Upgrade your plan to continue processing documents.",
    "runningLowDescription": "Consider upgrading to get more OCR scans.",
    "upgradePlan": "Upgrade Plan",
    "paymentFailedTitle": "Payment Failed",
    "paymentFailedDescription": "We couldn't process your last payment. Please update your payment method to avoid service interruption.",
    "updatePaymentMethod": "Update Payment Method",
    "subscriptionExpiredTitle": "Subscription Expired",
    "subscriptionExpiredDescription": "Your {plan} subscription has expired. Renew now to restore full access to your account.",
    "renewSubscription": "Renew Subscription",
    "subscriptionEndingTitle": "Subscription Ending",
    "subscriptionEndingDescription": "Your subscription is set to cancel on {date}. You'll retain access until then.",
    "manageSubscription": "Manage Subscription",
    "renewsToday": "Your subscription renews today.",
    "renewsTomorrow": "Your subscription renews tomorrow.",
    "renewsInDaysWithDate": "Your {plan} subscription renews in {days} days ({date}).",
    "renewsInDays": "Your {plan} subscription renews in {days} days.",
    "renewsOnDate": "Your {plan} subscription renews on {date}.",
    "renewalDueSoon": "Renewal Due Soon",
    "upcomingRenewal": "Upcoming Renewal",
    "ensurePaymentMethod": "Please ensure your payment method is up to date to avoid interruption.",
    "errorFetchInvoices": "Failed to fetch invoices",
    "errorUnknown": "Unknown error",
    "statusPaid": "Paid",
    "statusOpen": "Open",
    "statusDraft": "Draft",
    "statusVoid": "Void",
    "statusUncollectible": "Uncollectible",
    "invoiceHistory": "Invoice History",
    "invoiceHistoryDescription": "Your past invoices and receipts",
    "retry": "Retry",
    "noInvoicesYet": "No invoices yet",
    "noInvoicesDescription": "Invoices will appear here after your first payment",
    "invoiceFallbackNumber": "Invoice {id}",
    "paidAgo": "• Paid {ago}",
    "viewInvoice": "View invoice",
    "downloadPdf": "Download PDF",
    "loading": "Loading...",
    "loadMore": "Load More",
    "defaultFeature": "document scanning",
    "usageLimitReached": "Usage Limit Reached",
    "usageLimitReachedPrefix": "You've used all {limit} {feature} credits for this month on the",
    "usageLimitReachedSuffix": "plan.",
    "currentUsage": "Current Usage",
    "usageScans": "{used}/{limit} scans",
    "upgradeToPlan": "Upgrade to {plan}",
    "recommended": "Recommended",
    "pricePerMonth": "{currency} {price}/month",
    "unlimited": "Unlimited",
    "ocrScansPerMonth": "OCR scans/month",
    "maybeLater": "Maybe Later",
    "viewUpgradeOptions": "View Upgrade Options"
  },
  "x_siChild_0": {
    "filters": {
      "vendor": "Vendor",
      "allVendors": "All vendors",
      "from": "From",
      "to": "To"
    },
    "trend": {
      "title": "Purchase Cost Trend"
    },
    "history": {
      "title": "Purchase History",
      "recordsBadge": "{count} records",
      "empty": "No purchase records found for the selected filters.",
      "columns": {
        "date": "Date",
        "vendor": "Vendor",
        "qty": "Qty",
        "unitPrice": "Unit Price",
        "netUnitCost": "Net cost",
        "netUnitCostHint": "Last-paid basis",
        "listPrice": "List price",
        "discount": "Discount",
        "total": "Total",
        "invoiceNumber": "Invoice #",
        "netBaseUnitCost": "Net cost per base unit",
        "netBaseUnitCostHint": "Compares purchases after pack conversion",
        "sourcePack": "Source pack"
      },
      "sourcePackBase": "Receives {base}"
    },
    "emptyState": {
      "title": "No purchase data available",
      "description": "Purchase prices will appear here once AP invoices with matching items are processed through Vendor Intelligence."
    },
    "changeLog": {
      "loading": "Loading change history...",
      "empty": "No self-service updates yet.",
      "emptyValue": "(empty)",
      "revert": "Revert",
      "badges": {
        "adminRevert": "Admin Revert",
        "selfService": "Self-Service",
        "reverted": "Reverted"
      },
      "fields": {
        "businessName": "Business Name",
        "contactPerson": "Contact Person",
        "contactPersonPosition": "Position",
        "email": "Email",
        "phone": "Phone",
        "phone2": "Phone 2",
        "fax": "Fax",
        "addressLine1": "Address Line 1",
        "addressLine2": "Address Line 2",
        "addressLine3": "Address Line 3",
        "city": "City",
        "stateCode": "State",
        "postalCode": "Postal Code",
        "countryCode": "Region",
        "tin": "TIN",
        "brn": "BRN",
        "idType": "ID Type",
        "sstRegistration": "SST Registration",
        "website": "Website",
        "businessNature": "Business Nature"
      }
    },
    "cards": {
      "totalReceivables": "Total Receivables",
      "overdue": "Overdue",
      "currentNotDue": "Current (Not Due)",
      "activeCustomers": "Active Customers"
    },
    "aging": {
      "title": "Customer Aging Breakdown",
      "empty": "No outstanding receivables.",
      "total": "Total",
      "buckets": {
        "current": "Current",
        "days1to30": "1-30 Days",
        "days31to60": "31-60 Days",
        "days61to90": "61-90 Days",
        "days90plus": "90+ Days"
      },
      "columns": {
        "bucket": "Aging Bucket",
        "amount": "Amount",
        "percentOfTotal": "% of Total"
      },
      "incompleteWarning": "Totals exclude amounts in {currencies} because no exchange rate is set. Add a manual exchange rate on Accounting → Chart of Accounts to include them."
    },
    "topCustomers": {
      "title": "Top Customers by Outstanding",
      "columns": {
        "customer": "Customer",
        "outstanding": "Outstanding",
        "current": "Current",
        "days1to30": "1-30",
        "days31to60": "31-60",
        "days61to90": "61-90",
        "days90plus": "90+"
      }
    },
    "noBusinessSelected": "No business selected",
    "exportCsv": "Export CSV",
    "header": {
      "title": "E-Invoice Compliance",
      "subtitle": "LHDN MyInvois submission analytics"
    },
    "dateRange": {
      "thisMonth": "This Month",
      "last3Months": "Last 3 Months",
      "last6Months": "Last 6 Months",
      "allTime": "All Time"
    },
    "status": {
      "valid": "Valid",
      "invalid": "Invalid",
      "pending": "Pending",
      "cancelled": "Cancelled",
      "rejected": "Rejected"
    },
    "events": {
      "submitted": "submitted to LHDN",
      "validated": "validated by LHDN",
      "rejected": "rejected by LHDN",
      "cancelled": "cancelled"
    },
    "metrics": {
      "totalSubmitted": "Total Submitted",
      "totalSubmittedSub": "of {count} eligible",
      "validationRate": "Validation Rate",
      "validationRateSub": "{count} validated",
      "rejectionRate": "Rejection Rate",
      "rejectionRateSub": "{count} rejected",
      "complianceScore": "Compliance Score",
      "complianceScoreSub": "submitted / eligible"
    },
    "charts": {
      "monthlyVolume": "Monthly Volume",
      "statusBreakdown": "Status Breakdown",
      "noSubmissionData": "No submission data for selected period",
      "noSubmissions": "No submissions yet",
      "legend": {
        "submitted": "Submitted",
        "validated": "Validated",
        "rejected": "Rejected"
      }
    },
    "topErrors": {
      "title": "Top Validation Errors",
      "empty": "No validation errors recorded",
      "columns": {
        "code": "Code",
        "message": "Message",
        "count": "Count"
      }
    },
    "recentActivity": {
      "title": "Recent Activity",
      "empty": "No recent activity"
    },
    "relativeTime": {
      "seconds": "{count}s ago",
      "minutes": "{count} min ago",
      "hours": "{count}h ago",
      "days": "{count}d ago",
      "months": "{count}mo ago"
    },
    "csv": {
      "metric": "Metric",
      "value": "Value",
      "totalSubmitted": "Total Submitted",
      "validated": "Validated",
      "rejected": "Rejected",
      "invalid": "Invalid",
      "cancelled": "Cancelled",
      "pending": "Pending",
      "totalEligible": "Total Eligible",
      "complianceScore": "Compliance Score",
      "avgValidationTime": "Avg Validation Time (ms)",
      "notAvailable": "N/A",
      "monthlyBreakdownHeader": "--- Monthly Breakdown ---",
      "month": "Month",
      "submitted": "Submitted",
      "topErrorsHeader": "--- Top Errors ---",
      "errorCode": "Error Code",
      "message": "Message",
      "count": "Count",
      "recentActivityHeader": "--- Recent Activity ---",
      "invoiceNumber": "Invoice Number",
      "event": "Event",
      "timestamp": "Timestamp",
      "details": "Details"
    },
    "itemOptions": "Item options",
    "taxRate": "Tax rate",
    "selectTax": "Select tax",
    "taxRates": {
      "noTax": "No Tax",
      "custom": "Custom"
    },
    "itemDiscount": "Item discount",
    "discount": {
      "none": "No discount",
      "percentage": "Percentage (%)",
      "fixed": "Fixed amount"
    },
    "supplyPeriod": {
      "label": "Service/supply period",
      "to": "to",
      "help": "Date range for the service or supply period"
    },
    "discountableLabel": "Eligible for invoice-level discount",
    "saveAndAddAnother": "Save and add another item",
    "viewCurrency": {
      "label": "View in",
      "indicativeNote": "Indicative conversion at today's rate",
      "rateUnavailable": "Rate unavailable, so amounts are shown in {currency}"
    }
  },
  "x_siChild_1": {
    "clearanceBankAccountHelp": "The bank account that cleared this cheque or GIRO.",
    "bankAccountErrors": {
      "notFound": "That bank account is not in your chart of accounts. Pick one from the list, or add it in Accounting → Chart of Accounts.",
      "inactive": "That bank account is archived. Pick an active one.",
      "wrongType": "That account can't hold money. Pick a bank or cash account.",
      "isHeading": "That account is a heading with sub-accounts. Pick one of its sub-accounts instead."
    },
    "postingAccountErrors": {
      "notConfigured": "Your chart of accounts is missing an account this posting needs. Add or designate it on Accounting → Chart of Accounts, then try again."
    },
    "emailMetaToLabel": "To:",
    "emailMetaFromLabel": "From:",
    "emailMetaSubjectLabel": "Subject:",
    "emailSubject": "Invoice {invoiceNumber} from {companyName}",
    "defaultCompanyName": "Your Company",
    "defaultCustomerName": "Customer",
    "defaultItemName": "Item",
    "amountDue": "Amount due",
    "dueDate": "Due {date}",
    "invoiceLabel": "Invoice",
    "toLabel": "To",
    "fromLabel": "From",
    "itemsHeading": "Items",
    "subtotal": "Subtotal",
    "tax": "Tax",
    "total": "Total",
    "amountPaid": "Amount paid",
    "payThisInvoice": "Pay this invoice",
    "downloadInvoicePdf": "Download invoice PDF",
    "sentByFooter": "This invoice was sent by {companyName}",
    "createCreditNoteTitle": "Create Credit Note",
    "maxCreditable": "Max creditable: {amount}",
    "reasonLabel": "Reason *",
    "reasonPlaceholder": "e.g., Goods returned, pricing adjustment...",
    "lineItemsLabel": "Line Items",
    "descriptionPlaceholder": "Description",
    "qtyPlaceholder": "Qty",
    "pricePlaceholder": "Price",
    "addLineItem": "Add Line Item",
    "notesLabel": "Notes (optional)",
    "notesPlaceholder": "Additional notes...",
    "creditNoteTotal": "Credit Note Total",
    "creating": "Creating...",
    "createCreditNoteButton": "Create Credit Note",
    "cancel": "Cancel",
    "errorReasonRequired": "Credit note reason is required",
    "errorLineItemRequired": "At least one line item is required",
    "errorTotalGreaterThanZero": "Credit note total must be greater than 0",
    "errorTotalExceedsMax": "Credit note total ({total}) exceeds remaining creditable amount ({max})",
    "errorCreateFailed": "Failed to create credit note",
    "paymentHistoryTitle": "Payment History ({count})",
    "reversalBadge": "Reversal",
    "paymentBadge": "Payment",
    "editPaymentNote": "Edit payment note",
    "editPaymentNoteTitle": "Edit payment note",
    "editPaymentNoteDescription": "Update supporting notes without changing the payment amount, date, method, allocation, or ledger posting.",
    "paymentNoteLabel": "Payment note",
    "paymentNotePlaceholder": "Supporting note for this payment",
    "paymentMetadataReasonLabel": "Reason for change",
    "paymentMetadataReasonPlaceholder": "Explain why this note is being corrected",
    "paymentMetadataAuditHint": "The previous note and your reason will remain in the audit trail.",
    "savePaymentMetadata": "Save change",
    "savingPaymentMetadata": "Saving...",
    "paymentMetadataSaveFailed": "We could not save the payment note. Refresh and try again.",
    "paymentMethodBankTransfer": "Bank Transfer",
    "paymentMethodCash": "Cash",
    "paymentMethodCard": "Card",
    "paymentMethodCheque": "Cheque",
    "paymentMethodChequeCleared": "Cheque / GIRO - cleared",
    "paymentMethodPostDatedChequeGiro": "Post-dated cheque / GIRO",
    "paymentMethodOther": "Other",
    "referencePrefix": "Ref: {reference}",
    "clearancePending": "Pending clearance",
    "clearanceCleared": "Cleared",
    "clearanceBounced": "Bounced",
    "clearanceCancelled": "Cancelled",
    "instrumentDateShort": "Instrument: {date}",
    "expectedClearanceDateShort": "Expected clearance: {date}",
    "clearanceDateShort": "Cleared: {date}",
    "clearanceFailureDateShort": "Outcome: {date}",
    "instrumentDateCompact": "Instrument {date}",
    "expectedClearanceDateCompact": "Expected {date}",
    "clearanceDateCompact": "Cleared {date}",
    "clearanceFailureDateCompact": "Outcome {date}",
    "markCleared": "Mark cleared",
    "markBounced": "Bounced",
    "markCancelled": "Cancelled",
    "markClearedDialogTitle": "Mark Payment Cleared",
    "markClearedDialogMessage": "This will move the amount from Cheque / GIRO Clearing to the bank account using today's date.",
    "markBouncedDialogTitle": "Mark Payment Bounced",
    "markBouncedDialogMessage": "This will restore the invoice balance and reverse the Cheque / GIRO Clearing entry using today's date.",
    "markCancelledDialogTitle": "Mark Payment Cancelled",
    "markCancelledDialogMessage": "This will restore the invoice balance and reverse the Cheque / GIRO Clearing entry using today's date.",
    "confirmMarkCleared": "Confirm cleared",
    "confirmMarkBounced": "Confirm bounced",
    "confirmMarkCancelled": "Confirm cancelled",
    "updatingClearance": "Updating...",
    "reverse": "Reverse",
    "receiptLabel": "Receipt {receiptNumber}",
    "receiptVoid": {
      "badge": "Void",
      "reason": {
        "payment_reversed": "Payment reversed",
        "cheque_bounced": "Cheque bounced",
        "cheque_cancelled": "Cheque cancelled"
      }
    },
    "errorReverseFailed": "Failed to reverse payment",
    "reversalErrors": {
      "requestConflict": "This reversal request was already used with different details. Refresh the payment history, then try again.",
      "alreadyReversed": "This payment has already been reversed, so it cannot be reversed again. Refresh the page to see the reversal that was recorded.",
      "notCleared": "This payment was already marked bounced or cancelled, so there is nothing left to reverse. Refresh the page to see its current status.",
      "paymentHistoryCap": "This invoice has too much payment history to reverse safely. Contact support."
    },
    "errorClearanceActionFailed": "Failed to update payment clearance",
    "reversePaymentDialogTitle": "Reverse Payment",
    "reversePaymentDialogMessage": "This will create a reversal entry and restore the invoice balance. This action cannot be undone.",
    "reversing": "Reversing...",
    "confirmReversal": "Confirm Reversal",
    "statusDelivered": "Delivered",
    "statusFailed": "Failed",
    "statusPending": "Pending",
    "buyerDeliveryLabel": "Buyer Delivery:",
    "sentOn": "Sent on {timestamp}",
    "sentToPrefix": "to",
    "currencyLabel": "Currency",
    "taxModeLabel": "Tax Mode",
    "taxExclusive": "Tax Exclusive",
    "taxInclusive": "Tax Inclusive",
    "currencyChangeWarning": "Changing currency may affect line item prices. Continue?",
    "changeCurrency": "Change currency",
    "errorRestockLocationRequired": "Choose a restock location or select no stock movement.",
    "restockDispositionLabel": "Stock return",
    "restockNoMovement": "No stock movement",
    "restockRestockable": "Restock as available",
    "restockDamaged": "Return as unavailable",
    "restockLocationLabel": "Restock location",
    "restockLocationPlaceholder": "Select location",
    "pointsAwarded": "Points awarded",
    "pointsAdjusted": "Points adjusted",
    "pointsCurrentAward": "Current award",
    "clearanceReasonLabel": "Reason",
    "clearanceReasonPlaceholder": "Why was this cheque or GIRO bounced or cancelled?",
    "clearanceReasonRequired": "Enter a reason before changing the cheque or GIRO outcome.",
    "reversalPointsReasonRequired": "Enter a reason for changing awarded points.",
    "reversalPointsTitle": "Loyalty points awarded with this payment",
    "reversalPointsDescription": "Set the final points that should remain after the reversal. Leave unchanged to keep the current balance.",
    "clearancePointsDescription": "Set the final points that should remain after this cheque/GIRO is bounced or cancelled. Leave unchanged to keep the current award.",
    "reversalFinalPoints": "Final awarded points",
    "reversalOriginalPoints": "Originally {points} points",
    "reversalCurrentPoints": "Current {points} points",
    "reversalPointsReason": "Reason",
    "reversalPointsReasonPlaceholder": "Why should the awarded points change?",
    "officialReceiptAbsent": {
      "withReason": "No Official Receipt: {reason}",
      "unknown": "Recorded without an Official Receipt",
      "reason": {
        "pending_clearance": "waiting for bank clearance",
        "external_receipt": "receipt from another system"
      }
    },
    "restockCostHint": "Restocked goods come back at the cost the sale took them out at, and that cost of sale is reversed.",
    "errorRestockExceedsSold": "You cannot restock more than this invoice sold, less earlier returns. Lower the quantity or choose No stock movement.",
    "errorRestockNothingLeftStock": "None of these items left stock when the invoice was issued, so there is nothing to put back. Choose No stock movement.",
    "errorRestockCostUnreadable": "Groot cannot read the cost the sale posted for these goods, so it will not guess. Choose No stock movement and adjust the stock separately.",
    "errorRestockSaleReversed": "This invoice's stock was already put back when it was voided, so it cannot be restocked again.",
    "errorRestockCustomerHeld": "These goods are in customer-held stock. Release or void that stock instead of restocking it.",
    "reversalReasonPlaceholder": "Why is this payment being reversed?",
    "reversalReasonRequired": "Enter a reason for reversing this payment.",
    "errorRestockUnitMismatch": "The units on this invoice and on the deliveries that sent these goods cannot be converted into each other, so the quantity to put back cannot be worked out. Choose No stock movement and adjust the stock separately."
  },
  "x_siChild_2": {
    "templateLabel": "Template",
    "templateModern": "Modern",
    "templateClassic": "Classic",
    "memoLabel": "Memo",
    "memoPlaceholder": "Notes visible on the invoice...",
    "paymentInstructionsLabel": "Payment instructions",
    "paymentInstructionsPlaceholder": "Bank details, payment methods...",
    "signatureNameLabel": "Signature name",
    "signatureNamePlaceholder": "Authorized signatory name",
    "defaultsSaved": "Defaults saved",
    "saving": "Saving...",
    "saveAsDefaults": "Save as invoice defaults",
    "defaultsSavedHint": "These values will auto-populate on new invoices.",
    "saveDefaultsHint": "Saves memo, payment instructions, and signature as defaults for new invoices.",
    "noSalesTitle": "No sales recorded for this item yet",
    "noSalesDescription": "Sales prices are captured automatically when you issue sales invoices.",
    "filterCustomer": "Customer",
    "filterAllCustomers": "All customers",
    "filterFrom": "From",
    "filterTo": "To",
    "exportCsv": "Export CSV",
    "priceTrend": "Price Trend",
    "salesHistory": "Sales History",
    "recordsCount": "{count} records",
    "colDate": "Date",
    "colCustomer": "Customer",
    "colQty": "Qty",
    "colUnitPrice": "Unit Price",
    "colTotal": "Total",
    "colInvoiceNumber": "Invoice #",
    "promoPrice": "$0 (promo)",
    "sectionCustomer": "Customer",
    "sectionCurrencyTax": "Currency & Tax",
    "sectionItems": "Items",
    "sectionFulfillment": "Fulfillment",
    "sectionPaymentCollection": "Payment collection",
    "sectionAdditionalOptions": "Additional options",
    "fulfillment": {
      "title": "Inventory fulfillment",
      "description": "Choose whether stock leaves company-owned inventory immediately or is held operationally for the customer after invoicing.",
      "deliveryOrderPolicyTitle": "Delivery Order controls stock",
      "deliveryOrderPolicyDescription": "This business deducts stock from Delivery Orders. Create and send the invoice normally, then choose standard delivery or a customer-held destination when creating the Delivery Order.",
      "modeLabel": "Fulfillment mode",
      "standard": "Standard delivery",
      "customerHeld": "Customer-held stock",
      "destinationLabel": "Destination",
      "destinationPlaceholder": "Select customer-held location",
      "createDestination": "Create",
      "newCustomerDestination": "Select an existing customer from the directory before choosing customer-held stock. Typed invoice details are not customer master data.",
      "thisCustomer": "this customer",
      "customerHeldCreateFailed": "Customer-held stock location could not be created."
    },
    "subtotal": "Subtotal",
    "discount": "Discount",
    "tax": "Tax",
    "total": "Total",
    "pleaseFixFollowing": "Please fix the following:",
    "expired": "Expired",
    "timeRemainingHoursMinutes": "{hours}h {minutes}m remaining",
    "timeRemainingMinutes": "{minutes}m remaining",
    "rejectEInvoiceTitle": "Reject E-Invoice",
    "rejectDescription": "Reject the received e-invoice via LHDN. This action cannot be undone.",
    "rejectDescriptionWithSupplier": "Reject the received e-invoice from {supplierName} via LHDN. This action cannot be undone.",
    "rejectionWindowExpired": "Rejection window has expired",
    "rejectionWindowRemaining": "Rejection window: {time}",
    "rejectionReasonLabel": "Rejection Reason",
    "rejectionReasonPlaceholder": "Enter the reason for rejecting this e-invoice...",
    "rejectionWindowExpiredError": "The 72-hour rejection window has expired. This document can no longer be rejected.",
    "rejectFailed": "Failed to reject e-invoice",
    "rejectErrors": {
      "notRejectable": "This e-invoice can no longer be rejected because its status has changed. Refresh the page to see where it stands now.",
      "localSyncFailed": "LHDN has rejected this e-invoice and that cannot be undone, but Groot could not update its status here. Refresh the page. If it still shows as valid, contact support so we can reconcile it.",
      "rateLimited": "LHDN is limiting requests right now. Wait a moment, then reject again."
    },
    "rejectSuccess": "E-invoice rejected successfully",
    "cancel": "Cancel",
    "rejectEInvoiceButton": "Reject E-Invoice",
    "cancellationWindowExpired": "Cancellation window expired (72 hours after validation).",
    "cancellationFailed": "Cancellation failed",
    "cancelSuccess": "E-invoice cancelled successfully",
    "cancelFailed": "Failed to cancel e-invoice",
    "cancelEInvoiceTitle": "Cancel E-Invoice",
    "hoursRemainingInWindow": "{hours}h remaining in cancellation window.",
    "cancellationReasonPlaceholder": "Enter cancellation reason (required)...",
    "confirmCancel": "Confirm Cancel",
    "back": "Back",
    "cancelEInvoiceButton": "Cancel E-Invoice ({hours}h left)",
    "invoiceNumberLabel": "Invoice number",
    "invoiceNumberAutoPlaceholder": "Auto: {number}",
    "invoiceNumberHelp": "Must be unique. Leave blank to number it automatically.",
    "invoiceNumberEdit": "Edit",
    "invoiceNumberUseAuto": "Use automatic",
    "invoiceNumberLockedHelp": "From your numbering settings."
  },
  "x_siChild_3": {
    "paymentCollection": {
      "invoiceDate": "Invoice date",
      "paymentTerms": "Payment terms",
      "dueDate": "Due date",
      "saleTypeLabel": "How this is paid",
      "saleTypeCredit": "On credit (invoice)",
      "saleTypeCash": "Cash sale (paid now)",
      "saleTypeCreditHelp": "The customer still owes you. This posts to Accounts Receivable, and you record the payment when the money arrives.",
      "saleTypeCashHelp": "You have already been paid. This posts straight to your bank or cash account, and opens no receivable.",
      "receivedIntoLabel": "Received into",
      "receivedIntoHelp": "The bank or cash account this money landed in. This is the account the sale is debited to."
    },
    "customerSelector": {
      "searchPlaceholder": "Search customers...",
      "searching": "Searching...",
      "noCustomersMatching": "No customers matching \"{query}\"",
      "noCustomersYet": "No customers yet",
      "createNamed": "Create \"{name}\" as new customer",
      "createNew": "Create new customer",
      "newCustomer": "New customer",
      "newTag": "(new)",
      "clearCustomer": "Clear customer",
      "businessNameLabel": "Customer / Business Name",
      "businessNamePlaceholder": "Business name",
      "contactPersonLabel": "Contact Person",
      "contactPersonPlaceholder": "Contact name",
      "emailLabel": "Email",
      "phoneLabel": "Phone",
      "phonePlaceholder": "Phone number",
      "tinLabel": "TIN",
      "addressLabel": "Address",
      "streetAddressPlaceholder": "Street address",
      "cityPlaceholder": "City",
      "postalCodePlaceholder": "Postal code",
      "statePlaceholder": "State...",
      "stateProvincePlaceholder": "State / Province",
      "extraFieldsHint": "For BRN, SST, and Peppol fields, edit full details in the Customer Directory.",
      "saving": "Saving...",
      "saveToDirectory": "Save to Customer Directory",
      "infoModified": "Customer info modified",
      "saveChanges": "Save Changes",
      "countryPlaceholder": "Select country",
      "saveFailed": "This customer could not be saved to your directory. Check the details and try again."
    },
    "debitNote": {
      "title": "Create Debit Note",
      "subtitle": "Add additional charges to this invoice (e.g., price increase, surcharges).",
      "errorReasonRequired": "Debit note reason is required",
      "errorLineItemRequired": "At least one line item is required",
      "errorTotalPositive": "Debit note total must be greater than 0",
      "errorCreateFailed": "Failed to create debit note",
      "reasonLabel": "Reason *",
      "reasonPlaceholder": "e.g., Price increase, additional services, surcharge...",
      "lineItemsLabel": "Line Items",
      "descriptionPlaceholder": "Description",
      "qtyPlaceholder": "Qty",
      "pricePlaceholder": "Price",
      "taxRatePlaceholder": "Tax %",
      "addLineItem": "Add Line Item",
      "notesLabel": "Notes (optional)",
      "notesPlaceholder": "Additional notes...",
      "taxLabel": "Tax",
      "totalLabel": "Debit Note Total",
      "creating": "Creating...",
      "submit": "Create Debit Note",
      "cancel": "Cancel"
    },
    "feeRules": {
      "title": "Fee Classification Rules",
      "allPlatforms": "All Platforms",
      "addNewRule": "Add New Rule",
      "keywordPlaceholder": "Keyword (e.g., commission fee)",
      "add": "Add",
      "ruleCount": "{count, plural, one {# rule} other {# rules}}",
      "seedDefaults": "Seed Default Rules",
      "loading": "Loading rules...",
      "emptyState": "No rules configured. Click \"{action}\" to start with common platform fee mappings.",
      "unknownAccount": "Unknown",
      "noAccountsAvailable": "No expense accounts are available yet. Add an expense account on Accounting - Chart of Accounts, then come back to create a rule.",
      "toastRuleAdded": "Rule added",
      "toastRuleAddedDesc": "\"{keyword}\" → {code}",
      "toastError": "Error",
      "toastRuleRemoved": "Rule removed",
      "toastSeeded": "Default rules seeded",
      "toastRulesExist": "Rules already exist",
      "toastSeededDesc": "{count} rules added"
    },
    "reconciliation": {
      "severityError": "Error",
      "severityWarning": "Warning",
      "severityInfo": "Info",
      "feeConfidenceTooltip": "Fee confidence: {pct}%",
      "newBadge": "NEW",
      "aiConfidenceTooltip": "AI confidence: {pct}%",
      "aiBadge": "AI",
      "helpTitle": "AR Reconciliation Workflow",
      "helpImportLabel": "Import behavior:",
      "helpImportBody": "New orders are appended. Existing order references are skipped (not replaced). To update existing orders, delete them first before re-importing.",
      "helpWorkflowLabel": "Standard workflow:",
      "helpWorkflowBody": "Import → Review matches → Reconcile line items → Close period → Export to accounting system (Xero, QuickBooks, etc.)",
      "heading": "AR Reconciliation",
      "subheading": "Import sales statements and reconcile against invoices",
      "feeRulesButton": "Fee Rules",
      "autoApproveButton": "Auto-Approve",
      "exportCsvButton": "Export CSV",
      "importing": "Importing...",
      "importButton": "Import Sales Statement",
      "cardTotalOrders": "Total Orders",
      "cardMatched": "Matched",
      "cardUnmatched": "Unmatched",
      "cardVariance": "Variance",
      "cardGrossTotal": "Gross Total",
      "cardPlatformFees": "Platform Fees",
      "cardAutoMatchRate": "Auto-Match Rate",
      "cardAiPrecision": "AI Precision",
      "cardLearnedAliases": "Learned Aliases",
      "cardHoursSaved": "Est. Hours Saved",
      "filtersLabel": "Filters:",
      "dateFromPlaceholder": "From",
      "dateToPlaceholder": "To",
      "periodPresets": "Period Presets",
      "preset": {
        "Today": "Today",
        "ThisWeek": "This Week",
        "ThisMonth": "This Month",
        "LastMonth": "Last Month"
      },
      "filter": {
        "all": "All",
        "matched": "Matched",
        "unmatched": "Unmatched",
        "variance": "Variance",
        "partial": "Partial",
        "conflict": "Conflict"
      },
      "filterAiPending": "AI Pending",
      "filterAiPendingCount": "AI Pending ({count})",
      "needsReviewButton": "Needs Review",
      "needsReviewTooltip": "Show only orders with fees needing review (confidence < 90%)",
      "reopenPeriod": "Reopen Period",
      "closePeriod": "Close Period",
      "tableTitle": "Imported Sales Orders",
      "emptyTitle": "No sales orders imported yet",
      "emptyHint": "Click \"{action}\" to get started",
      "colSelect": "Select",
      "colOrderRef": "Order Ref",
      "colDate": "Date",
      "colProduct": "Product",
      "colCustomer": "Customer",
      "colGross": "Gross",
      "colFee": "Fee",
      "colFeeConfidence": "Fee Confidence",
      "colFeeConfidenceTitle": "Fee classification confidence",
      "colNet": "Net",
      "colPlatform": "Platform",
      "colMethod": "Method",
      "colStatus": "Status",
      "itemsCount": "{count} items",
      "status": {
        "matched": "Matched",
        "unmatched": "Unmatched",
        "variance": "Variance",
        "partial": "Partial",
        "conflict": "Conflict"
      },
      "aiMatchesSelected": "{count, plural, one {# AI match} other {# AI matches}} selected",
      "approveSelected": "Approve Selected ({count})",
      "rejectSelected": "Reject Selected",
      "cancel": "Cancel",
      "detailTitle": "Order vs Invoice Comparison",
      "salesOrderSection": "Sales Order",
      "fieldReference": "Reference",
      "fieldDate": "Date",
      "fieldCustomer": "Customer",
      "fieldGrossAmount": "Gross Amount",
      "fieldPlatformFee": "Platform Fee",
      "fieldNetAmount": "Net Amount",
      "fieldConfidence": "Confidence",
      "feeBreakdown": "Fee Breakdown",
      "feeLearningTitle": "Review fee meaning",
      "feeLearningBody": "Confirm what each fee means and where this business posts it. These corrections train only this business.",
      "feeCategory": "Fee meaning",
      "feeCategoryCommission": "Commission",
      "feeCategoryShipping": "Shipping",
      "feeCategoryService": "Service",
      "feeCategoryMarketing": "Marketing",
      "feeCategoryPaymentProcessing": "Payment processing",
      "feeCategoryPlatform": "Platform",
      "feeAccount": "Posting account",
      "feeSave": "Save correction",
      "feeSaving": "Saving...",
      "feeSavedTitle": "Fee correction saved",
      "feeSavedDesc": "Future learning is isolated to this business.",
      "feeSaveFailed": "Fee correction wasn't saved",
      "feeAccountNotPostable": "That account isn't an active expense account in this business's chart, so the correction wasn't saved. Pick another account from the list, or set the platform fee account on Accounting → Chart of Accounts → Payment & posting.",
      "lineItemsCount": "Line Items ({count})",
      "itemFallback": "Item {num}",
      "qtyLine": "Qty: {qty} × {price}",
      "matchedInvoiceSection": "Matched Invoice",
      "fieldInvoiceNumber": "Invoice # (click icon to open)",
      "fieldTotalAmount": "Total Amount",
      "fieldStatus": "Status",
      "noMatchedInvoice": "No matched invoice",
      "varianceDetailsSection": "Variance Details",
      "varColField": "Field",
      "varColOrder": "Order",
      "varColInvoice": "Invoice",
      "varColDiff": "Diff",
      "varColSeverity": "Severity",
      "varianceAmountLabel": "Variance: {amount}",
      "aiSuggestionSection": "AI Match Suggestion",
      "confidenceLabel": "Confidence:",
      "approve": "Approve",
      "reject": "Reject",
      "viaMethod": "via {method}",
      "method": {
        "exact_reference": "exact reference",
        "fuzzy": "fuzzy match",
        "manual": "manual",
        "line_item": "line items",
        "ai_suggested": "AI match",
        "auto_agent": "Verified by Groot"
      },
      "reconciling": "Reconciling...",
      "reconcileLineItems": "Reconcile Line Items",
      "reconcileTooltipTitle": "Deep line-by-line comparison",
      "reconcileTooltipBody": "Compares quantity, unit price, and total for each product. May change status to \"partial\" if discrepancies are found (e.g., missing items, quantity mismatches).",
      "reconcileTooltipNote": "This provides more accurate reconciliation than header-level matching",
      "unmatch": "Unmatch",
      "reverseConfirm": "This will reverse the auto-approved journal entry and create a CRITICAL_FAILURE training example. Continue?",
      "reverseAutoMatch": "Reverse Auto-Match",
      "selectInvoiceToMatch": "Select an invoice to match:",
      "unexpectedError": "An unexpected error occurred",
      "toastImportedTitle": "Imported {count} orders",
      "toastImportedSkippedDesc": "Skipped {skipped} existing orders. To update existing data, delete old orders first then re-import.",
      "toastImportSuccessTitle": "Successfully imported {count} orders",
      "toastImportSuccessDesc": "Running automatic matching against invoices...",
      "toastImportFailedTitle": "Import failed",
      "toastDiscrepanciesTitle": "Line item discrepancies found",
      "toastDiscrepanciesDesc": "Found {errors, plural, one {# error} other {# errors}} and {warnings, plural, one {# warning} other {# warnings}}. Status changed to \"{status}\". Review variance details below.",
      "toastReconcileCompleteTitle": "Line item reconciliation complete",
      "toastReconcileMinorDesc": "Found {warnings, plural, one {# minor variance} other {# minor variances}}. Status: \"{status}\".",
      "toastLineItemsMatchTitle": "Line items match perfectly",
      "toastLineItemsMatchDesc": "All quantities, prices, and totals align between order and invoice.",
      "toastReconcileFailedTitle": "Reconciliation failed",
      "toastReconcileFailedDesc": "Failed to reconcile line items",
      "toastAiApprovedTitle": "{count, plural, one {# AI match} other {# AI matches}} approved",
      "toastAiApprovedDesc": "Orders have been matched to their AI-suggested invoices.",
      "toastApprovalFailedTitle": "Approval failed",
      "toastApprovalFailedDesc": "Failed to approve AI matches",
      "toastAiRejectedTitle": "AI suggestions rejected",
      "toastAiRejectedDesc": "Orders returned to unmatched state.",
      "toastAiSuggestionRejected": "AI suggestion rejected",
      "toastAutoApprovalPausedTitle": "Auto-approval paused",
      "toastAutoApprovalPausedDesc": "{count} critical failures in 30 days. Auto-approval has been disabled. Re-enable in Settings.",
      "toastAutoMatchReversedTitle": "Auto-match reversed",
      "toastAutoMatchReversedDesc": "Journal entry reversed. Critical failure logged for AI learning.",
      "toastReversalFailedTitle": "Reversal failed",
      "toastReversalFailedDesc": "Failed to reverse",
      "errorOrderNotMatched": "This order isn't matched to an invoice yet, so there are no line items to compare. Match it to an invoice first, then reconcile.",
      "errorNotAutoApprovedMatch": "Only a match Groot approved automatically can be reversed here. To undo a manual match, use Unmatch instead.",
      "toastMatchFailedTitle": "Match failed",
      "toastMatchFailedDesc": "We couldn't match this order to that invoice. Nothing was changed.",
      "toastUnmatchFailedTitle": "Unmatch failed",
      "toastUnmatchFailedDesc": "This order is still matched to its invoice. Nothing was changed.",
      "toastClosePeriodFailedTitle": "Period wasn't closed",
      "toastClosePeriodFailedDesc": "The period is still open. Nothing was changed.",
      "toastReopenPeriodFailedTitle": "Period wasn't reopened",
      "toastReopenPeriodFailedDesc": "The period is still closed. Nothing was changed.",
      "toastAiRejectFailedTitle": "Nothing was rejected",
      "toastAiRejectFailedDesc": "They all still have their AI suggestion, and nothing was changed.",
      "toastAiRejectPartialTitle": "Some were not rejected",
      "toastAiRejectPartialDesc": "{succeeded} of {total} returned to unmatched. The other {failed} are still selected so you can try again.",
      "platformConfirmTitle": "Confirm the marketplace",
      "platformConfirmRecognisedBody": "We read this file and it matches a {format} export. Confirm the marketplace so the {format} fee rules are applied to every fee on it.",
      "platformConfirmUndeterminedBody": "We read this file but could not tell which marketplace it came from, so please choose it below. We never guess from the file name: a renamed export would send your fees to the wrong rules without saying so.",
      "platformConfirmAmbiguousBody": "This file matches more than one format ({formats}), so we will not choose for you. Pick the marketplace it came from.",
      "platformConfirmFileLabel": "File: {file}",
      "platformChooseLabel": "Marketplace",
      "platformRecognisedBadge": "Recognised from the file",
      "platformFeeRulesNote": "The fee rules you have set up for the marketplace you pick are applied to every fee on this statement. Nothing is imported until you confirm.",
      "platformConfirmButton": "Confirm and import",
      "platformName": {
        "lazada": "Lazada",
        "tiktok_shop": "TikTok Shop",
        "foodpanda": "Foodpanda",
        "other": "Another marketplace"
      },
      "settlementHold": {
        "badge": "Held: foreign-currency invoice",
        "title": "Not posted: this order settles a foreign-currency invoice",
        "detail": "Automatic settlement could not price this order against its foreign-currency invoice: there is no exchange rate for the settlement date, or the order's currency, amount or variance does not fit the invoice. Nothing was posted for this order. Record the receipt against the invoice from Receive payment, with the amount your bank received."
      }
    },
    "fieldErrors": {
      "invoiceDate": "Pick an invoice date",
      "dueDate": "Pick a due date"
    }
  },
  "x_siChild_4": {
    "agingLabels": {
      "current": "Current",
      "days1to30": "1-30",
      "days31to60": "31-60",
      "days61to90": "61-90",
      "days90plus": "90+"
    },
    "agingSummary": "Aging Summary",
    "viewFullReport": "View Full Report",
    "total": "Total",
    "overdueOnly": "Overdue Only",
    "sortBy": "Sort by",
    "sortOutstandingAmount": "Outstanding Amount",
    "sortDaysOverdue": "Days Overdue",
    "sortCustomerName": "Customer Name",
    "countSelected": "{count} selected",
    "confirmBulkSend": "Will send to {count, plural, one {# customer} other {# customers}}{skipped}. Proceed?",
    "confirmBulkSendSkipped": " ({count} with no email skipped)",
    "bulkSendResult": "Sent: {sent}, Skipped (no email): {skipped}, Errors: {errors}",
    "bulkSendFailed": "Failed to send bulk emails.",
    "requestInfoUpdate": "Request Info Update",
    "clear": "Clear",
    "noOutstandingReceivables": "No Outstanding Receivables",
    "allInvoicesPaid": "All invoices have been paid. Great work!",
    "daysOverdueBadge": "{days}d overdue",
    "openBadge": "{count} open",
    "fullyPaid": "Fully paid",
    "openInvoicesCount": "{count} open {count, plural, one {invoice} other {invoices}}",
    "outstandingLabel": "Outstanding:",
    "lifetimeLabel": "Lifetime: {amount}",
    "title": "Auto-Approval Settings",
    "settingsSavedTitle": "Auto-approval settings saved",
    "settingsSavedDescription": "Threshold: {threshold}%, Min cycles: {minCycles}",
    "settingsSavedDisabled": "Auto-approval is disabled",
    "settingsSaveFailedTitle": "Failed to save settings",
    "unknownError": "Unknown error",
    "autoApprovalPaused": "Auto-approval paused",
    "criticalFailuresExceeded": "3+ critical failures detected in 30 days. Review reversed matches before re-enabling.",
    "enableAutoApproval": "Enable Auto-Approval",
    "enableAutoApprovalDescription": "Automatically approve and post high-confidence AI matches",
    "confidenceThreshold": "Confidence Threshold",
    "confidenceThresholdDescription": "Minimum AI confidence score for auto-approval (0.90 - 1.00)",
    "minimumLearningCycles": "Minimum Learning Cycles",
    "minimumLearningCyclesDescription": "How many times the AI must correctly match a vendor/customer alias before auto-approving (1-50)",
    "tripleLockGate": "Triple-Lock Gate",
    "lock1": "Lock 1: Auto-approve is enabled",
    "lock2": "Lock 2: AI confidence ≥ {threshold}%",
    "lock3": "Lock 3: Alias matched correctly ≥ {minCycles} times",
    "tripleLockNote": "All three locks must pass for auto-approval. Split matches always require review.",
    "saving": "Saving...",
    "saveSettings": "Save Settings",
    "cancel": "Cancel",
    "unableToLoadMargin": "Unable to load margin data.",
    "latestPurchaseCost": "Latest Purchase Cost",
    "fromVendor": "from {vendor}",
    "noPurchaseDataYet": "No purchase data yet",
    "noVendorMappings": "No vendor mappings",
    "latestSellingPrice": "Latest Selling Price",
    "toCustomer": "to {customer}",
    "noSalesRecorded": "No sales recorded",
    "grossMargin": "Gross Margin",
    "needBothData": "Need both purchase and selling data",
    "noPurchaseCostAvailable": "No purchase cost available",
    "noVendorMappingsConfigured": "No vendor mappings configured",
    "noVendorMappingsConfiguredHint": "Go to the Purchase History tab to link vendor items to this catalog item for margin analysis.",
    "noSalesRecordedHint": "Add this item to a sales invoice to track selling prices and calculate margins.",
    "priceComparisonOverTime": "Price Comparison Over Time",
    "noBuyerEmail": "No buyer email address found",
    "einvoiceDelivered": "E-invoice delivered to {email}",
    "einvoiceSendFailed": "Failed to send e-invoice",
    "sending": "Sending...",
    "sendToBuyer": "Send to Buyer",
    "copy": "Copy",
    "lhdnEinvoice": "LHDN e-Invoice",
    "earlyAccess": "Early Access",
    "availableWithCertificate": "Available with LHDN digital certificate",
    "noLhdnSubmissionYet": "No LHDN submission yet.",
    "lhdnValidationErrorsTitle": "LHDN validation errors",
    "lhdnValidationNoDetails": "Validation failed and LHDN returned no error details.",
    "availableForPaying": "Available for paying customers",
    "reviewRequiredTitle": "Review Required: Journal Entry May Need Reversal",
    "reviewRequiredBody": "This invoice has a posted journal entry. The {action} means the AR entry may no longer be valid.",
    "actionRejection": "rejection",
    "actionCancellation": "cancellation",
    "buyerRejected": "Buyer Rejected",
    "cancelledByBuyer": "Cancelled by Buyer",
    "reasonLabel": "Reason:",
    "rejectedAt": "Rejected at: {date}",
    "cancelledAt": "Cancelled at: {date}",
    "documentUuid": "Document UUID",
    "longId": "Long ID",
    "submissionId": "Submission ID",
    "validated": "Validated",
    "einvoiceNotValidated": "This invoice has not been validated by LHDN yet. Validate it first, then send it to your buyer.",
    "einvoiceMyOnly": "LHDN e-invoicing is available to Malaysian businesses only.",
    "einvoiceDeliveryUnresolved": "An earlier delivery of this e-invoice is still unresolved. Reconcile it before sending again.",
    "einvoiceDeliveryUnconfirmed": "We could not confirm whether this e-invoice was delivered. Do not resend it until you have checked the delivery record.",
    "fxSellingConverted": "Selling price converted from {from} to {to} at the rate for {date}.",
    "fxPurchaseConverted": "Purchase cost converted from {from} to {to} at the rate for {date}.",
    "fxSellingRateMissing": "No {from} to {to} exchange rate for {date}, so the selling price could not be converted and no margin is shown. Add that rate on Accounting → Chart of Accounts.",
    "fxPurchaseRateMissing": "No {from} to {to} exchange rate for {date}, so the purchase cost could not be converted and no margin is shown. Add that rate on Accounting → Chart of Accounts.",
    "fxCostChangeWithheld": "No {from} to {to} exchange rate for {date}, so the earlier purchase cost cannot be compared with the latest one and no cost change is shown. Add that rate on Accounting → Chart of Accounts.",
    "fxPriceChangeWithheld": "No {from} to {to} exchange rate for {date}, so the two most recent selling prices cannot be compared and no margin warning is shown. Add that rate on Accounting → Chart of Accounts.",
    "marginBelowCost": "Selling below cost: losing {percent}% on every unit sold.",
    "marginCostRosePriceFlat": "Margin has fallen. Cost is up {percent}% and the selling price has not changed.",
    "statementTransactionDescriptions": {
      "invoiceIssued": "Invoice issued",
      "carriedForwardInvoice": "Carried-forward invoice",
      "paymentReceived": "Payment received: {method}",
      "paymentReversal": "Payment reversal: {method}",
      "openingReceipt": "Opening receipt",
      "openingReceiptReversal": "Opening receipt reversal",
      "creditNoteIssued": "Credit note issued",
      "debitNoteIssued": "Debit note issued",
      "customerRefund": "Refund of customer credit"
    },
    "detailTransactionDescriptions": {
      "invoice": "Invoice {reference}",
      "carriedForwardInvoice": "Carried-forward invoice {reference}",
      "payment": "Payment: {method}",
      "paymentReversal": "Payment reversal: {method}",
      "openingReceipt": "Opening receipt",
      "openingReceiptReversal": "Opening receipt reversal",
      "creditNote": "Credit note {reference}",
      "debitNote": "Debit note {reference}",
      "customerRefund": "Refund {reference}"
    },
    "inCreditBadge": "In credit"
  },
  "x_siChild_5": {
    "companyLogo": "Company logo",
    "regLabel": "Reg:",
    "regNoLabel": "Reg. No:",
    "tinLabel": "TIN:",
    "taxIdLabel": "Tax ID:",
    "sstRegLabel": "SST Reg:",
    "sstLabel": "SST:",
    "brnLabel": "BRN:",
    "idTypeLabel": "ID Type:",
    "invoiceTitle": "INVOICE",
    "billTo": "Bill To",
    "invoiceDetails": "Invoice Details",
    "invoiceDate": "Invoice Date:",
    "dueDate": "Due Date:",
    "paymentTerms": "Payment Terms:",
    "currency": "Currency:",
    "taxMode": "Tax Mode:",
    "itemCode": "Item Code",
    "code": "Code",
    "rowNumber": "#",
    "description": "Description",
    "qty": "Qty",
    "unitPrice": "Unit Price",
    "tax": "Tax",
    "taxInclusive": "Tax (Inclusive)",
    "amount": "Amount",
    "discount": "Discount",
    "unitLabel": "Unit:",
    "discountLabel": "Discount:",
    "subtotal": "Subtotal",
    "total": "Total",
    "amountPaid": "Amount Paid",
    "balanceDue": "Balance Due",
    "notes": "Notes",
    "paymentInstructions": "Payment Instructions",
    "acceptedPaymentMethods": "Accepted Payment Methods",
    "additionalInformation": "Additional Information",
    "paymentMethodQrAlt": "{label} QR Code",
    "updateBusinessDetailsAlt": "Update business details",
    "scanToUpdateEn": "Scan to update your business details",
    "scanToUpdateMs": "Imbas untuk kemaskini maklumat perniagaan anda",
    "authorizedSignature": "Authorized Signature",
    "thankYouForBusiness": "Thank you for your business.",
    "validatedByLhdn": "Validated by LHDN",
    "documentUuidLabel": "Document UUID:",
    "validatedLabel": "Validated:",
    "pdfDownloadFailedTitle": "PDF download failed",
    "pdfDownloadFailedDescription": "We couldn't generate the invoice PDF. Please try again.",
    "gstRegLabel": "GST Reg:",
    "regLabelBrn": "SSM/BRN:",
    "regLabelUen": "UEN:",
    "regLabelGui": "統一編號:",
    "gstLabel": "GST:",
    "creditNoteTitle": "CREDIT NOTE",
    "debitNoteTitle": "DEBIT NOTE",
    "refundNoteTitle": "REFUND NOTE",
    "noteDetails": "Note Details",
    "noteDate": "Note Date:",
    "originalInvoice": "Original Invoice:",
    "adjustmentReason": "Reason",
    "officialReceiptTitle": "OFFICIAL RECEIPT",
    "receivedFrom": "Received From",
    "receiptDetails": "Receipt Details",
    "receiptNumber": "Receipt No.:",
    "datePaid": "Date Paid:",
    "paymentMethod": "Payment Method:",
    "paymentReference": "Reference:",
    "taxInvoiceLabel": "Tax invoice:",
    "documentLabel": "Document:",
    "amountReceived": "Amount Received",
    "amountInWords": "Amount in words:",
    "inPaymentOf": "In payment of",
    "documentNumber": "Document",
    "amountApplied": "Amount Applied",
    "balanceAfter": "Balance After",
    "paidBefore": "Paid before",
    "paidWithThisReceipt": "Paid with this receipt",
    "totalReceived": "Total received",
    "itemsShownOfTotal": "Showing {shown} of {total} items. See {number} for the full list.",
    "itemsNotListed": "The items are not listed here. See {number} for the full list.",
    "andMoreDocuments": "and {count} more",
    "computerGeneratedReceipt": "Computer-generated receipt. No signature required.",
    "notATaxInvoice": "This acknowledges money received; it is not a tax invoice.",
    "voidStamp": "VOID",
    "voidNotice": "This receipt is void and is not proof of payment.",
    "receiptPayerFallback": "Customer",
    "methodCash": "Cash",
    "methodBankTransfer": "Bank transfer",
    "methodCard": "Card",
    "methodCheque": "Cheque",
    "methodOther": "Other",
    "paymentReferenceLine": "Payment reference: {reference}",
    "paymentReferenceHelp": "Enter this in the payment reference field when you pay.",
    "customerPo": "Your PO:"
  },
  "x_analytics_0": {
    "hero": {
      "loading": "Loading automation rate...",
      "title": "AI Automation Rate",
      "periodToday": "Today",
      "periodThisWeek": "This week",
      "periodThisMonth": "This month",
      "periodAllTime": "All time",
      "optionToday": "Today",
      "optionThisWeek": "This Week",
      "optionThisMonth": "This Month",
      "optionAllTime": "All time",
      "collectingData": "(collecting data)",
      "documentsAutomated": "{automated} of {total} documents automated",
      "reviewedByYou": "{count} reviewed by you",
      "minutesSaved": "~{minutes} minutes saved {period}"
    },
    "trend": {
      "loading": "Loading trend data...",
      "title": "Automation Rate Trend",
      "notEnoughData": "Tracking automation trends. Check back after 2 weeks of AI activity",
      "lastWeeks": "Last {weeks} weeks",
      "modelOptimized": "Model optimized",
      "tooltipDecisions": "{total} decisions, {reviewed} reviewed",
      "lowSampleSize": "Low sample size (<10 decisions)",
      "modelOptimizedThisWeek": "Model optimized this week",
      "noActivity": "No AI activity this week"
    },
    "dashboard": {
      "title": "Financial Dashboard",
      "subtitle": "{period} • Displayed in {currency}",
      "updatedAt": "• Updated {time}",
      "periodLast60Days": "Last 60 Days",
      "periodCurrentQuarter": "Current Quarter",
      "periodCurrentYear": "Current Year",
      "refreshData": "Refresh data",
      "errorTitle": "Error Loading Financial Data",
      "retry": "Retry",
      "noChange": "No change",
      "directionUp": "up",
      "directionDown": "down",
      "trendText": "{change}% {direction}",
      "totalIncome": "Total Income",
      "totalExpenses": "Total Expenses",
      "netProfit": "Net Profit",
      "transactions": "Transactions",
      "profitMargin": "Profit Margin",
      "totalCount": "Total count",
      "noTrend": "No trend",
      "vsPrevPeriod": "vs. prev period"
    },
    "aging": {
      "totalOutstanding": "Total Outstanding",
      "bucket0to30": "0-30 days",
      "bucketCurrentFull": "Current (0-30 days)",
      "bucket31to60": "31-60 days",
      "bucket61to90": "61-90 days",
      "bucket90plus": "90+ days",
      "riskLabel": "{risk} risk",
      "risk_low": "low",
      "risk_medium": "medium",
      "risk_high": "high",
      "risk_critical": "critical",
      "currentHealthy": "Current (healthy):",
      "atRisk": "At risk (60+ days):",
      "avgRiskScore": "Avg Risk Score:",
      "highRiskItems": "High-Risk Items:"
    },
    "receivables": {
      "title": "Aged Receivables",
      "emptyTitle": "No outstanding receivables",
      "emptySubtitle": "All invoices are paid or no income transactions pending"
    },
    "payables": {
      "title": "Aged Payables",
      "currencyEquivalent": "{currency} equivalent",
      "emptyTitle": "No outstanding payables",
      "emptySubtitle": "All bills are paid or no expense transactions pending"
    },
    "viewCurrency": {
      "label": "View in",
      "indicativeNote": "Indicative conversion at today's rate",
      "rateUnavailable": "Rate unavailable, so amounts are shown in {currency}"
    }
  },
  "x_analytics_1": {
    "featureArMatching": "AR Matching",
    "featureBankReconciliation": "Bank Reconciliation",
    "featureFeeClassification": "Fee Classification",
    "compactCardTitle": "{feature} AI",
    "confidenceLabel": "Confidence:",
    "editRateLabel": "Edit Rate:",
    "loadingAiPerformance": "Loading AI performance...",
    "aiPerformanceTitle": "AI Performance",
    "aiPerformanceMetricsTitle": "AI Performance Metrics",
    "aiPerformanceEmptyDescription": "Metrics will appear here once you start using AI features like AR matching, bank reconciliation, or fee classification.",
    "distributionNoEdit": "No Edit",
    "distributionEdited": "Edited",
    "distributionMissing": "Missing",
    "updatedAt": "Updated {time}",
    "refreshMetricsTitle": "Refresh metrics",
    "periodThisMonth": "This Month",
    "periodLast3Months": "Last 3 Months",
    "periodAllTime": "All Time",
    "hoursValue": "{value}h",
    "hoursSaved": "Hours Saved",
    "decisionsSummary": "{automated} automated, {review} needed review",
    "overallConfidence": "Overall Confidence",
    "editRate": "Edit Rate",
    "noEditRate": "No-Edit Rate",
    "automationRate": "Automation Rate",
    "financialAnalyticsTitle": "Financial Analytics",
    "retry": "Retry",
    "financialDashboardTitle": "Financial Dashboard",
    "updatedDot": "• Updated {time}",
    "loadingAnalytics": "Loading analytics...",
    "refreshAnalytics": "Refresh analytics",
    "currencyLabel": "Currency: {symbol} {code}",
    "currenciesTracked": "{count} currencies tracked",
    "noAnalyticsData": "No analytics data available",
    "totalIncome": "Total Income",
    "totalExpenses": "Total Expenses",
    "netProfit": "Net Profit",
    "profitMargin": "Profit Margin",
    "noChange": "No change",
    "directionUp": "up",
    "directionDown": "down",
    "trendChange": "{value}% {direction}",
    "noTrend": "No trend",
    "vsPrevPeriod": "vs. prev period",
    "currencyBreakdownTitle": "Currency Breakdown",
    "noCurrencyData": "No currency data available",
    "completeTransactionsHint": "Complete some transactions to see breakdown",
    "amountLabel": "Amount: {value}",
    "shareLabel": "Share: {value}%",
    "netPositive": "Net Positive",
    "netNegative": "Net Negative",
    "currencyCount": "{count, plural, one {# currency} other {# currencies}}",
    "homeCurrency": "Home Currency",
    "totalVolume": "Total Volume",
    "aiPerformanceUnavailableTitle": "Metrics are unavailable",
    "aiPerformanceUnavailableDescription": "We could not load your AI performance data, so these numbers are not shown. This is not the same as having no activity. Try refreshing, and contact support if it keeps happening."
  },
  "x_analytics_2": {
    "expenseCategories": "Expense Categories",
    "noCategoryData": "No category data available",
    "recordExpensesHint": "Record some expenses to see breakdown",
    "amountLabel": "Amount: {amount}",
    "shareLabel": "Share: {share}%",
    "topCount": "Top {count} {count, plural, one {category} other {categories}}",
    "totalCategories": "Total Categories",
    "largestExpense": "Largest Expense",
    "notAvailable": "N/A",
    "totalAmount": "Total Amount",
    "topCategories": "Top Categories:",
    "actionCenter": "Action Center",
    "allLookingGood": "All looking good!",
    "noUrgentActions": "No urgent actions needed at this time",
    "itemCount": "{count} {count, plural, one {item} other {items}}",
    "priorityItems": "Priority items: {high} high, {medium} medium",
    "lastUpdated": "Last updated: {time}",
    "loading": "Loading...",
    "priority_high": "high",
    "priority_medium": "medium",
    "priority_low": "low",
    "criticalComplianceTitle": "Critical Compliance Issues",
    "criticalComplianceDesc": "{count} {count, plural, one {transaction} other {transactions}} with critical compliance violations requiring immediate attention.",
    "reviewComplianceLabel": "Review Compliance",
    "complianceReviewNeededTitle": "Compliance Review Needed",
    "complianceReviewNeededDesc": "{count} cross-border {count, plural, one {transaction requires} other {transactions require}} compliance review.",
    "reviewTransactionsLabel": "Review Transactions",
    "overduePaymentsTitle": "Overdue Payments",
    "overduePaymentsDesc": "You have {count} overdue {count, plural, one {transaction} other {transactions}} requiring immediate attention.",
    "reviewOverdueLabel": "Review Overdue",
    "upcomingDueTitle": "Upcoming Due Dates",
    "upcomingDueDesc": "{count} {count, plural, one {payment is} other {payments are}} due within the next 7 days.",
    "viewCalendarLabel": "View Calendar",
    "awaitingPaymentTitle": "Awaiting Payment",
    "awaitingPaymentDesc": "{count} {count, plural, one {transaction is} other {transactions are}} waiting for payment confirmation.",
    "updateStatusLabel": "Update Status",
    "negativeProfitTitle": "Negative Profit Alert",
    "negativeProfitDesc": "Your expenses exceed income by {amount}. Review your spending patterns.",
    "reviewExpensesLabel": "Review Expenses",
    "incomeDecliningTitle": "Income Declining",
    "incomeDecliningDesc": "Income has decreased by {percent}% compared to last period.",
    "analyzeRevenueLabel": "Analyze Revenue",
    "expensesRisingTitle": "Expenses Rising",
    "expensesRisingDesc": "Expenses have increased by {percent}% compared to last period.",
    "controlCostsLabel": "Control Costs",
    "profitGrowthTitle": "Strong Profit Growth",
    "profitGrowthDesc": "Profit increased by {percent}%. Consider investing in growth opportunities.",
    "exploreGrowthLabel": "Explore Growth",
    "multiCurrencyExposureTitle": "Multi-Currency Exposure",
    "multiCurrencyExposureDesc": "You have exposure to {count} currencies. Consider hedging foreign exchange risk.",
    "reviewFxRiskLabel": "Review FX Risk",
    "improveCategorizationTitle": "Improve Categorization",
    "improveCategorizationDesc": "Most expenses are uncategorized. Better categorization helps with insights.",
    "categorizeTransactionsLabel": "Categorize Transactions",
    "healthyMarginTitle": "Healthy Profit Margin",
    "healthyMarginDesc": "Your profit margin is {percent}%. You're maintaining strong profitability."
  },
  "x_utilities_0": {
    "toggleTheme": "Toggle theme",
    "conversionError": "Conversion error",
    "retryConversion": "Retry conversion",
    "converting": "Converting...",
    "refreshExchangeRate": "Refresh exchange rate",
    "rate": "Rate: 1 {from} = {rate} {to}",
    "updated": "Updated: {date}"
  },
  "x_onboardingChild_0": {
    "trialEndsToday": "Your trial ends today",
    "trialEndsInOneDay": "Your trial ends in 1 day",
    "trialEndsInDays": "Your trial ends in {days} days",
    "endsOn": "Ends {date}",
    "dayProgress": "Day {current}/{total}",
    "percentOfTrialUsed": "{percent}% of trial used",
    "upgradeNow": "Upgrade Now",
    "dismissTrialBanner": "Dismiss trial banner",
    "customizeCogsCategories": "Customize COGS categories",
    "customizeCogsCategoriesDescription": "Add categories for direct costs of producing your products/services",
    "addNewCategory": "Add new category",
    "typeCategoryNamePlaceholder": "Type category name...",
    "add": "Add",
    "maximumCategoriesReached": "Maximum {max} categories reached",
    "yourCategoriesCount": "Your categories ({count}/{max})",
    "removeCategory": "Remove {category}",
    "suggestedForYourBusiness": "Suggested for your business",
    "back": "Back",
    "skip": "Skip",
    "useDefaults": "Use Defaults",
    "continue": "Continue",
    "whatTypeOfBusiness": "What type of business do you run?",
    "whatTypeOfBusinessDescription": "This helps us suggest relevant categories",
    "selected": "Selected",
    "describeYourBusinessType": "Describe your business type",
    "describeYourBusinessTypePlaceholder": "e.g., Consulting, Healthcare, Education...",
    "businessTypes": {
      "fnb": {
        "label": "Food & Beverage",
        "description": "Restaurants, cafes, food stalls, catering services"
      },
      "retail": {
        "label": "Retail",
        "description": "Stores, shops, e-commerce, merchandise sales"
      },
      "services": {
        "label": "Professional Services",
        "description": "Consulting, agencies, freelancing, professional firms"
      },
      "manufacturing": {
        "label": "Manufacturing",
        "description": "Factories, production facilities, assembly operations"
      },
      "gig": {
        "label": "Gig / e-hailing driver",
        "description": "Grab / ride-hailing drivers, delivery riders, solo gig workers"
      },
      "other": {
        "label": "Other",
        "description": "Other business types requiring custom category setup"
      }
    },
    "customizeExpenseCategories": "Customize expense categories",
    "customizeExpenseCategoriesDescription": "Add categories for operating expenses like rent, utilities, marketing",
    "addExpenseCategories": "Add Expense Categories",
    "expenseCategoryNamePlaceholder": "e.g., Office Rent, Marketing...",
    "categoriesUsedOfMax": "{count}/{max} categories",
    "yourCategories": "Your Categories",
    "categoryAlreadyExists": "Category already exists",
    "addAtLeastOneCategoryOrSkip": "Please add at least one category or skip this step"
  },
  "x_apikeys_0": {
    "errorNameRequired": "Please enter a name for the API key",
    "errorPermissionRequired": "Please select at least one permission",
    "errorBusinessContext": "Business context not available",
    "errorCreateFailed": "Failed to create API key",
    "createModalTitle": "Create API Key",
    "keyNameLabel": "Key Name",
    "keyNamePlaceholder": "e.g., Production API Key",
    "keyNameHint": "A descriptive name to identify this key",
    "permissionsLabel": "Permissions",
    "selectAll": "Select All",
    "clear": "Clear",
    "tool_detect_anomalies_name": "Detect Anomalies",
    "tool_detect_anomalies_description": "Find unusual transactions",
    "tool_forecast_cash_flow_name": "Forecast Cash Flow",
    "tool_forecast_cash_flow_description": "Predict future cash flow",
    "tool_analyze_vendor_risk_name": "Analyze Vendor Risk",
    "tool_analyze_vendor_risk_description": "Assess vendor concentration risk",
    "tool_create_proposal_name": "Create Proposal",
    "tool_create_proposal_description": "Create payment proposals (requires approval)",
    "tool_confirm_proposal_name": "Confirm Proposal",
    "tool_confirm_proposal_description": "Confirm pending proposals",
    "tool_cancel_proposal_name": "Cancel Proposal",
    "tool_cancel_proposal_description": "Cancel pending proposals",
    "rateLimitLabel": "Rate Limit",
    "rateLimitUnit": "requests per minute",
    "expirationLabel": "Expiration",
    "expirationNever": "Never",
    "expiration30Days": "30 days",
    "expiration90Days": "90 days",
    "expiration1Year": "1 year",
    "cancel": "Cancel",
    "creating": "Creating...",
    "createKey": "Create Key",
    "saveKeyTitle": "Save Your API Key",
    "saveKeyWarning": "This is the only time you will see this key. Please copy and store it securely. You will not be able to retrieve it later.",
    "copied": "Copied!",
    "copyToClipboard": "Copy to Clipboard",
    "copyFailed": "Couldn't copy the key. Select it and copy it manually.",
    "securityNoticeLabel": "Security Notice:",
    "securityNoticeBody": "Treat this key like a password. Do not share it or commit it to version control.",
    "savedMyKey": "I've Saved My Key",
    "statusActive": "Active",
    "statusRevoked": "Revoked",
    "rateValue": "Rate: {rate}/min",
    "expiresValue": "Expires: {date}",
    "createdValue": "Created: {time}",
    "lastUsedValue": "Last used: {time}",
    "allPermissions": "All Permissions",
    "morePermissions": "+{count} more",
    "revoke": "Revoke",
    "selectBusinessPrompt": "Please select a business to manage API keys.",
    "headerTitle": "API Keys",
    "headerSubtitle": "Manage API keys for external integrations (Claude Desktop, Zapier, etc.)",
    "createApiKey": "Create API Key",
    "mcpEndpointTitle": "MCP Server Endpoint",
    "mcpEndpointDescription": "Use this endpoint with your API key to connect Claude Desktop, Cursor, or other MCP clients.",
    "viewDocumentation": "View Documentation",
    "loading": "Loading API keys...",
    "emptyTitle": "No API Keys Yet",
    "emptyDescription": "Create an API key to connect external AI tools to your financial data.",
    "createFirstApiKey": "Create Your First API Key",
    "activeKeysHeading": "Active Keys ({count})",
    "revokedKeysHeading": "Revoked Keys ({count})",
    "errorKeyCollision": "We couldn't create that key just now. Please try again, and a new key will be generated."
  },
  "x_chat_5": {
    "title": "Budget Status",
    "total": "Total",
    "over": "Over",
    "exportCsvAria": "Export CSV",
    "exportCsvTitle": "Export as CSV",
    "status": {
      "onTrack": "On Track",
      "warning": "Warning",
      "overspent": "Overspent"
    },
    "csv": {
      "category": "Category",
      "budgetLimit": "Budget Limit",
      "currentSpend": "Current Spend",
      "remaining": "Remaining",
      "percentUsed": "% Used",
      "status": "Status"
    },
    "leave": {
      "title": "Leave Request",
      "submitted": "Submitted",
      "cancelledTitle": "Leave request cancelled",
      "confirmTitle": "Confirm Leave Request",
      "leaveType": "Leave Type",
      "period": "Period",
      "periodValue": "{start} to {end}",
      "workingDays": "Working Days",
      "daysCount": "{count, plural, one {# day} other {# days}}",
      "currentBalance": "Current Balance",
      "afterDeduction": "After Deduction",
      "daysValue": "{count, plural, one {# day} other {# days}}",
      "insufficientWarning": "Warning: Insufficient leave balance. Request will be submitted for manager review.",
      "submitRequest": "Submit Request",
      "cancel": "Cancel",
      "historicalNote": "This leave request preview may have already been actioned."
    }
  },
  "x_expense_6": {
    "status": {
      "draft": "Draft",
      "submitted": "Submitted",
      "approved": "Approved",
      "rejected": "Rejected",
      "reimbursed": "Reimbursed"
    },
    "field": {
      "vendor": "Vendor",
      "amount": "Amount",
      "transactionDate": "Transaction Date",
      "submitter": "Submitter",
      "reference": "Reference",
      "businessPurpose": "Business Purpose"
    },
    "value": {
      "unknown": "Unknown"
    },
    "header": {
      "title": "Duplicate Comparison",
      "subtitle": "Review and resolve this potential duplicate"
    },
    "matchInfo": {
      "confidence": "Confidence:",
      "percent": "{value}%",
      "matchedFields": "Matched Fields:",
      "crossUser": "Cross-User"
    },
    "card": {
      "originalClaim": "Original Claim",
      "matchedClaim": "Matched Claim"
    },
    "dismiss": {
      "prompt": "Why is this not a duplicate?",
      "placeholder": "e.g., Separate transactions at same vendor, different items purchased..."
    },
    "action": {
      "cancel": "Cancel",
      "dismissing": "Dismissing...",
      "dismissAsNotDuplicate": "Dismiss as Not Duplicate",
      "notADuplicate": "Not a Duplicate",
      "confirming": "Confirming...",
      "confirmDuplicate": "Confirm Duplicate"
    },
    "resolved": {
      "dismissed": "Dismissed",
      "confirmedDuplicate": "Confirmed Duplicate",
      "reason": "Reason: {reason}"
    }
  },
  "x_invoices_1": {
    "adjustmentsTitle": "Adjustments ({count})",
    "voidAdjustment": "Void",
    "voidAdjustmentTitle": "Void this adjustment?",
    "voidAdjustmentDescription": "This will remove {invoiceNumber} from the payable balance and create a reversal journal entry. This cannot be undone.",
    "voidAdjustmentSuccessTitle": "Adjustment voided",
    "voidAdjustmentSuccessDescription": "A reversal journal entry has been created.",
    "voidAdjustmentFailedTitle": "Adjustment could not be voided",
    "voidAdjustmentFailedDescription": "Review the adjustment and try again.",
    "cancel": "Cancel",
    "lhdnStatusLabel": "LHDN: {status}",
    "originalAmount": "Original Amount",
    "totalCredited": "Total Credited",
    "totalDebited": "Total Debited",
    "netPayable": "Net Payable",
    "drawerTitle": "LHDN E-Invoice Detection",
    "drawerDescription": "Groot automatically detects and verifies LHDN e-invoices when you upload supplier invoices.",
    "howItWorks": "How It Works",
    "step1Title": "Upload your supplier invoice",
    "step1Description": "Upload the PDF or image you received from your supplier by email, WhatsApp, or any other channel.",
    "step2Title": "Automatic e-invoice detection",
    "step2Description": "Groot scans the document. If it finds an LHDN MyInvois QR code, it extracts the document ID and verifies it against LHDN within seconds.",
    "step3Title": "See the status",
    "step3Description": "A badge appears on the invoice showing its LHDN status. Click into the detail view for full verification info.",
    "step4Title": "Reject if needed (72-hour window)",
    "step4Description": "If the e-invoice is incorrect, click 'Reject E-Invoice' and enter a reason. You have 72 hours from LHDN validation to reject.",
    "statusBadges": "Status Badges",
    "badgeValidatedLabel": "LHDN ✓",
    "badgeValidatedDescription": "Validated and past the 72h window",
    "badgeTimeLeftLabel": "48h left",
    "badgeTimeLeftDescription": "Within rejection window",
    "badgeRejectedLabel": "Rejected",
    "badgeRejectedDescription": "You rejected this e-invoice",
    "goodToKnow": "Good to Know",
    "goodToKnow1": "Your supplier sends the e-invoice to you, not LHDN",
    "goodToKnow2": "Regular invoices (without LHDN QR) work exactly as before",
    "goodToKnow3": "After 72 hours, the e-invoice is final and cannot be rejected",
    "goodToKnow4": "Rejected invoices are kept for your records (read-only)",
    "settingsHint": "To enable LHDN verification, connect your MyInvois account in",
    "settingsLink": "Settings → Business → e-Invoice",
    "zoomOut": "Zoom Out",
    "zoomIn": "Zoom In",
    "resetView": "Reset View",
    "regionsDetected": "{count} regions detected",
    "retrying": "Retrying... ({count}/2)",
    "loadingImage": "Loading image...",
    "failedToLoadImage": "Failed to load image",
    "clickToRetry": "Click to retry",
    "noText": "No text",
    "documentPreview": "Document Preview",
    "pdfDocument": "PDF Document",
    "imageDocument": "Image Document",
    "fileSizeMb": "{size} MB",
    "copyContent": "Copy content",
    "timeRemainingHours": "{hours}h {minutes}m remaining",
    "timeRemainingMinutes": "{minutes}m remaining",
    "statusRejected": "E-Invoice Rejected",
    "statusCancelled": "E-Invoice cancelled by the supplier",
    "statusValidated": "LHDN Validated E-Invoice",
    "statusPending": "LHDN Verification Pending",
    "statusFailed": "LHDN Verification Failed",
    "documentUuid": "Document UUID",
    "validated": "Validated",
    "myInvois": "MyInvois",
    "viewOnLhdnPortal": "View on LHDN Portal",
    "rejectionReason": "Rejection Reason:",
    "rejectEInvoice": "Reject E-Invoice",
    "windowClosed": "72-hour rejection window has closed. This e-invoice is now final.",
    "openInNewTab": "Open in a new tab",
    "pageOfTotal": "Page {current} of {total}",
    "previousPage": "Previous page",
    "nextPage": "Next page"
  },
  "x_chat_0": {
    "richPanel": {
      "ariaLabel": "Rich content panel",
      "close": "Close panel",
      "noTableData": "No table data available",
      "noChartData": "No chart data available",
      "noDashboardData": "No dashboard data available"
    },
    "attachment": {
      "unsupportedFormat": "{name}: unsupported format. Use JPEG, PNG, HEIC, PDF, CSV, XLS, or XLSX.",
      "fileTooLarge": "{name}: file too large ({size} MB). Maximum is 10 MB.",
      "attachImage": "Attach image",
      "attachReceiptPhoto": "Attach a receipt photo or document",
      "attachStatementOrReceipt": "Attach a bank statement, receipt, or invoice",
      "removeFile": "Remove {name}",
      "tooManyReceipts": "A message can carry up to {max} receipts. I added what fits and left {count} out. Send the rest in another message.",
      "tooManyDocuments": "A message with a statement or another document can carry up to {max} files. I added what fits and left {count} out. Send the rest in another message."
    },
    "correction": {
      "type": {
        "intent": {
          "label": "Wrong intent",
          "description": "Groot misunderstood what you were asking for"
        },
        "toolSelection": {
          "label": "Wrong data source",
          "description": "Groot used the wrong tool or data source"
        },
        "parameterExtraction": {
          "label": "Wrong details",
          "description": "Groot got the dates, amounts, or other details wrong"
        },
        "other": {
          "label": "Something else",
          "description": "Tell us what went wrong"
        }
      },
      "intent": {
        "personalData": "My own data",
        "generalKnowledge": "General knowledge"
      },
      "tool": {
        "getInvoices": "Purchase invoices",
        "getSalesInvoices": "Sales invoices",
        "getTransactions": "Transactions",
        "getVendors": "Vendors",
        "getApAging": "AP aging",
        "getArSummary": "AR summary",
        "analyzeCashFlow": "Cash flow analysis",
        "detectAnomalies": "Anomaly detection",
        "getEmployeeExpenses": "Employee expenses",
        "getTeamSummary": "Team summary",
        "searchRegulatoryKnowledgeBase": "Regulatory knowledge base",
        "searchDocuments": "Documents"
      },
      "error": {
        "submitFailed": "Submit failed. Please retry.",
        "couldNotRecord": "Could not record feedback. Please retry.",
        "submitFailedRetry": "Submit failed. Please retry."
      },
      "thanksLearning": "Thanks! Groot is learning",
      "gotItBetter": "Got it. Groot will do better.",
      "couldNotSave": "Couldn't save: {error}",
      "dismiss": "Dismiss",
      "wasThisHelpful": "Was this helpful?",
      "goodResponse": "Good response",
      "reportIncorrect": "Report incorrect response",
      "privacyTooltip": "Your feedback helps Groot learn. We never share your data; corrections stay private to your business.",
      "selectSource": "Select the correct data source",
      "otherPlaceholder": "Tell us what went wrong…",
      "correctValuePlaceholder": "Enter the correct value…",
      "submit": "Submit"
    },
    "citation": {
      "page": "Page {page}",
      "confidence": "{percent}% confidence",
      "closeDetails": "Close citation details",
      "relevantContent": "Relevant content",
      "documentAccess": "Document access",
      "viewOfficialDocument": "View official document",
      "viewPdfDocument": "View PDF document",
      "documentPreview": "Document preview",
      "pdfDocument": "PDF document",
      "highlighted": "Highlighted",
      "openFullPdf": "Open full PDF",
      "pdfPreviewTitle": "PDF document preview",
      "pdfPreviewUnavailable": "PDF preview unavailable",
      "pdfPreviewUnavailableDesc": "This document can't be previewed here. Open it directly to view the full content.",
      "openPdfDocument": "Open PDF document",
      "urlPrefix": "URL: {url}",
      "citationLocation": "Location: {x}, {y}",
      "governmentWebsite": "Government website",
      "officialSource": "Official source",
      "openWebsite": "Open website",
      "loadingWebsitePreview": "Loading website preview…",
      "officialWebsiteTitle": "Official website preview",
      "websitePreviewUnavailable": "Website preview unavailable",
      "websitePreviewUnavailableDesc": "This website can't be embedded here. Visit it directly to view the full content.",
      "visitOfficialWebsite": "Visit official website",
      "noPreviewAvailable": "No preview available",
      "noPreviewAvailableDesc": "There's no document or website available to preview for this citation.",
      "metadata": "Metadata",
      "citationId": "Citation ID",
      "referenceIndex": "Reference index",
      "confidenceScore": "Confidence score"
    }
  },
  "x_chat_1": {
    "consent": {
      "title": "AI Assistant",
      "subtitle": "Before you start, here's how your data is handled.",
      "shared": {
        "title": "What data is shared",
        "body": "Your chat messages and relevant business context (e.g. expense summaries, invoice data) are sent to process your request."
      },
      "processor": {
        "title": "Who processes it",
        "body": "Your request is processed by trusted AI service providers through secure, paid business APIs. Your data is not used to train AI models."
      },
      "protection": {
        "title": "How it's protected",
        "body": "All data is encrypted in transit. We use paid business APIs, and our providers do not use your data to train their models."
      },
      "privacyLink": "Read our Privacy Policy",
      "accept": "I Agree and Start Chatting",
      "decline": "No Thanks"
    },
    "switcher": {
      "newChat": "New Chat",
      "newConversation": "New Conversation",
      "loading": "Loading...",
      "empty": "No conversations yet",
      "deleteLabel": "Delete {title}"
    },
    "renderer": {
      "clickToEnlarge": "Click to enlarge",
      "close": "Close",
      "viewCitation": "View citation {index}"
    },
    "expenseApproval": {
      "title": "Expense Approval",
      "statusApproved": "Approved",
      "statusRejected": "Rejected",
      "claimCount": "{count, plural, one {# claim} other {# claims}}",
      "submitted": "Submitted {date}",
      "moreClaims": "+{count} more",
      "historicalHint": "This is from a previous session. Ask \"what needs my approval?\" for up-to-date actions.",
      "approve": "Approve",
      "reject": "Reject",
      "confirmApprove": "Approve {currency} {amount} from {name}?",
      "confirmReject": "Reject {currency} {amount} from {name}?",
      "yes": "Yes",
      "cancel": "Cancel",
      "processing": "Processing...",
      "operationFailed": "Operation failed",
      "tryAgain": "Try again",
      "claimLevel": {
        "title": "Claim approvals",
        "subtitle": "{count, plural, one {# claim awaiting decision} other {# claims awaiting decisions}}",
        "reportTitle": "Report",
        "riskSummary": "{total, plural, one {{flagged} of # claim needs attention} other {{flagged} of # claims need attention}}",
        "allClearSummary": "{total, plural, one {# claim is clear} other {All # claims are clear}}",
        "pendingOnlyHint": "Only pending claims can be decided from this card.",
        "historicalHint": "Refresh approvals before deciding claims from an older card."
      },
      "claims": {
        "title": "Claims",
        "claim": "Claim",
        "claimNumber": "Claim {index}",
        "count": "{count, plural, one {# claim} other {# claims}}",
        "pendingCount": "{count, plural, one {# pending} other {# pending}}",
        "clearCount": "{count, plural, one {# clear} other {# clear}}",
        "flaggedCount": "{count, plural, one {# flagged} other {# flagged}}",
        "fields": {
          "amount": "Amount",
          "vendor": "Vendor",
          "merchant": "Merchant",
          "date": "Expense date",
          "category": "Category",
          "description": "Description",
          "status": "Status",
          "submitter": "Submitter",
          "submittedAt": "Submitted",
          "waitingDays": "Waiting time",
          "total": "Report total"
        },
        "fallbacks": {
          "amountUnavailable": "Amount unavailable",
          "vendorUnavailable": "Vendor unavailable",
          "dateUnavailable": "Date unavailable",
          "categoryUnavailable": "Category unavailable",
          "descriptionUnavailable": "No description",
          "currencyUnavailable": "Currency unavailable",
          "unknownSubmitter": "Unknown submitter",
          "reportTitleUnavailable": "Untitled report",
          "valueUnavailable": "Unavailable"
        },
        "status": {
          "pending": "Pending",
          "submitted": "Pending approval",
          "approved": "Approved",
          "rejected": "Rejected",
          "returned": "Returned",
          "paid": "Paid",
          "stale": "Already decided",
          "unavailable": "Status unavailable"
        }
      },
      "risk": {
        "title": "Risk signals",
        "needsReview": "Needs review",
        "clear": "No known issues",
        "duplicate": {
          "label": "Duplicate check",
          "statusLabel": "Duplicate status",
          "clear": "No duplicate found",
          "none": "No duplicate found",
          "suspected": "Possible duplicate",
          "confirmed": "Confirmed duplicate",
          "unavailable": "Duplicate status unavailable",
          "unknown": "Duplicate status unavailable",
          "warning": "Possible duplicate - review before approving",
          "unavailableWarning": "Duplicate check unavailable - approval needs an override reason",
          "summarySuspected": "{count, plural, one {# possible duplicate} other {# possible duplicates}}",
          "summaryUnavailable": "{count, plural, one {# unavailable duplicate check} other {# unavailable duplicate checks}}"
        },
        "policy": {
          "label": "Policy check",
          "statusLabel": "Policy status",
          "passed": "Policy checks passed",
          "failed": "Policy failed",
          "unavailable": "Policy status unavailable",
          "unknown": "Policy status unavailable",
          "issue": "Policy issue",
          "issues": "Policy issues",
          "issueCount": "{count, plural, one {# policy issue} other {# policy issues}}",
          "failedCount": "{count, plural, one {# policy failure} other {# policy failures}}",
          "noIssues": "No policy issues",
          "unavailableWarning": "Policy check unavailable - approval needs an override reason",
          "issueTypes": {
            "amountLimit": "Amount exceeds policy limit",
            "missingReceipt": "Receipt is missing",
            "missingCategory": "Category is missing",
            "missingDate": "Expense date is missing",
            "missingMerchant": "Vendor or merchant is missing",
            "categoryRestricted": "Category is restricted by policy",
            "receiptRequired": "Receipt is required",
            "managerApprovalRequired": "Manager approval required",
            "outsidePolicy": "Outside expense policy",
            "unknown": "Policy issue needs review"
          }
        },
        "overrideFlags": {
          "policyFailed": "Policy failed",
          "policyUnavailable": "Policy unavailable",
          "duplicateSuspected": "Possible duplicate",
          "duplicateUnavailable": "Duplicate status unavailable"
        }
      },
      "override": {
        "required": "Override reason required",
        "badge": "Needs reason",
        "promptTitle": "Add override reason",
        "promptDescription": "Explain why this flagged claim should still be approved.",
        "sharedPromptTitle": "Add shared override reason",
        "sharedPromptDescription": "This reason will be saved on every flagged claim approved in this batch.",
        "label": "Override reason",
        "sharedLabel": "Shared override reason",
        "placeholder": "Briefly explain the business reason for approving this flagged claim.",
        "sharedPlaceholder": "Briefly explain the business reason for approving these flagged claims.",
        "validationRequired": "Enter an override reason before approving.",
        "validationMinLength": "Use at least {min} characters.",
        "validationTooLong": "Keep the reason under {max} characters.",
        "reasonSaved": "Override reason saved",
        "requiredForPolicyFailed": "Approval needs a reason because policy checks failed.",
        "requiredForPolicyUnavailable": "Approval needs a reason because policy status is unavailable.",
        "requiredForDuplicateSuspected": "Approval needs a reason because this may be a duplicate.",
        "requiredForDuplicateUnavailable": "Approval needs a reason because duplicate status is unavailable."
      },
      "actions": {
        "approveClaim": "Approve claim",
        "rejectClaim": "Reject claim",
        "approveAll": "Approve all",
        "rejectAll": "Reject all",
        "confirmApproveClaim": "Approve this claim?",
        "confirmRejectClaim": "Reject this claim?",
        "confirmApproveAll": "Approve {count, plural, one {# pending claim} other {# pending claims}}?",
        "confirmRejectAll": "Reject {count, plural, one {# pending claim} other {# pending claims}}?",
        "submitApproval": "Submit approval",
        "submitRejection": "Submit rejection",
        "cancel": "Cancel",
        "retry": "Retry",
        "refresh": "Refresh",
        "processing": "Processing...",
        "approving": "Approving...",
        "rejecting": "Rejecting...",
        "approvingAll": "Approving claims...",
        "rejectingAll": "Rejecting claims...",
        "disabledStale": "Already decided",
        "disabledNotPending": "Only pending claims can be decided"
      },
      "results": {
        "claimApproved": "Claim approved.",
        "claimRejected": "Claim rejected.",
        "allApproved": "{count, plural, one {# claim approved.} other {# claims approved.}}",
        "allRejected": "{count, plural, one {# claim rejected.} other {# claims rejected.}}",
        "partialSuccess": "{success} succeeded, {failed} failed.",
        "partialFailure": "Some claim decisions could not be completed.",
        "bulkNoEligibleClaims": "No pending claims are eligible for this action.",
        "staleClaim": "This claim was already decided elsewhere.",
        "cardUpdated": "Card updated with latest statuses."
      },
      "errors": {
        "loadFailed": "Approval details could not be loaded. Try again in a moment.",
        "decisionFailed": "This decision could not be completed. Try again or refresh the card.",
        "approveFailed": "This claim could not be approved. Try again or refresh the card.",
        "rejectFailed": "This claim could not be rejected. Try again or refresh the card.",
        "bulkFailed": "Some claims could not be updated. Refresh to see the latest statuses.",
        "unauthorized": "You are not allowed to view or decide these approvals.",
        "forbidden": "You do not have permission to decide this claim.",
        "notFound": "This claim is no longer available.",
        "stale": "This claim was already decided elsewhere. Refresh to see the latest status.",
        "overrideRequired": "Add an override reason before approving this flagged claim.",
        "policyOverrideRequired": "Add an override reason before approving a claim with policy issues.",
        "duplicateOverrideRequired": "Add an override reason before approving a possible duplicate.",
        "network": "Network error while updating the claim. Try again.",
        "unavailable": "Approval service is unavailable right now. Try again in a moment.",
        "unknown": "Something went wrong while updating the claim.",
        "tryAgain": "Try again",
        "notAuthenticated": "You are not allowed to view or decide these approvals.",
        "notAuthorized": "You do not have permission to decide this claim.",
        "notPending": "This claim was already decided elsewhere. Refresh to see the latest status.",
        "financialDataMissing": "This decision could not be completed. Try again or refresh the card.",
        "dataUnavailable": "Approval details could not be loaded. Try again in a moment.",
        "noClaimRows": "No pending claims are eligible for this action.",
        "homeAmountUnavailable": "This claim is in a different currency and has no converted amount. Open the claim, enter the amount in your business currency, then approve it.",
        "homeAmountUnavailableNamed": "Cannot approve this report yet. The claim {claim} is in {claimCurrency} and your books are in {homeCurrency}. Add the {homeCurrency} amount to that claim, or enter a {claimCurrency} to {homeCurrency} rate for {date} on Accounting → Chart of Accounts, then try again.",
        "fxRateMissing": "Cannot approve this claim: it is in {claimCurrency} but your books are in {homeCurrency}, and there is no {claimCurrency} to {homeCurrency} exchange rate on file for {date}. Add that rate on Accounting → Chart of Accounts, then approve again.",
        "accrualSharesNotAllocatable": "Nothing was approved. These claims can't be posted together because their amounts in your business currency can't be shared out to the cent. Approve the claims one at a time, or contact support."
      },
      "approveClaim": "Approve claim",
      "rejectClaim": "Reject claim",
      "yesApprove": "Submit approval",
      "yesReject": "Submit rejection",
      "confirmApproveClaim": "Approve this claim?",
      "confirmApproveWithOverride": "Explain why this flagged claim should still be approved.",
      "confirmRejectClaim": "Reject this claim?",
      "overrideRequired": "Override reason required",
      "overrideReasonPlaceholder": "Briefly explain the business reason for approving this flagged claim.",
      "reviewerNotesPlaceholder": "Briefly explain the business reason for approving these flagged claims.",
      "disabledNotPending": "Only pending claims can be decided",
      "fallbackReportTitle": "Untitled report",
      "statusPending": "Pending",
      "statusNotPending": "Already decided",
      "fields": {
        "vendor": "Vendor",
        "date": "Expense date",
        "category": "Category"
      },
      "unavailable": {
        "submitter": "Unknown submitter",
        "description": "No description",
        "vendor": "Vendor unavailable",
        "date": "Date unavailable",
        "category": "Uncategorised",
        "amount": "Amount unavailable"
      },
      "badges": {
        "duplicate": "Duplicate check",
        "policy": "Policy check"
      },
      "duplicate": {
        "clear": "No duplicate found",
        "suspected": "Possible duplicate",
        "confirmed": "Confirmed duplicate",
        "dismissed": "No duplicate found",
        "unavailable": "Duplicate status unavailable"
      },
      "amountEdited": {
        "clear": "Matches receipt",
        "edited": "Differs from receipt",
        "unavailable": "Original amount unavailable"
      },
      "policy": {
        "passed": "Policy checks passed",
        "failed": "Policy failed",
        "failedWithCount": "{count, plural, one {# policy issue} other {# policy issues}}",
        "unavailable": "Policy status unavailable"
      },
      "summary": {
        "total": "{count, plural, one {# claim} other {# claims}}",
        "pending": "{count, plural, one {# pending} other {# pending}}",
        "duplicates": "{count, plural, one {# possible duplicate} other {# possible duplicates}}",
        "policyFailed": "{count, plural, one {# policy failure} other {# policy failures}}",
        "unavailable": "{count, plural, one {# unavailable duplicate check} other {# unavailable duplicate checks}}",
        "requiresOverride": "{count, plural, one {# flagged} other {# flagged}}",
        "amountEdited": "{count, plural, one {# with edited amount} other {# with edited amounts}}",
        "clear": "Clear"
      },
      "bulk": {
        "approveAll": "Approve all",
        "rejectAll": "Reject all",
        "approvePrompt": "Approve {count, plural, one {# pending claim} other {# pending claims}}?",
        "approvePromptWithOverride": "This reason will be saved on every flagged claim approved in this batch.",
        "rejectPrompt": "Reject {count, plural, one {# pending claim} other {# pending claims}}?",
        "confirmApprove": "Submit approval",
        "confirmReject": "Submit rejection",
        "processing": "Processing...",
        "allApproved": "{count, plural, one {# claim approved.} other {# claims approved.}}",
        "allRejected": "{count, plural, one {# claim rejected.} other {# claims rejected.}}",
        "partialResult": "{success} succeeded, {failed} failed.",
        "advancedToNextApprover": "{count, plural, one {# claim forwarded to the next approver.} other {# claims forwarded to the next approver.}}",
        "moreFailures": "+{count} more failed. See each claim below for its reason."
      },
      "validation": {
        "overrideReasonRequired": "Enter an override reason before approving."
      },
      "chain": {
        "levelXofY": "Level {level} of {depth}",
        "waitingFinal": "Waiting on final sign-off",
        "forwarded": "Forwarded to the next approver"
      },
      "overLimit": {
        "flag": "Over policy cap",
        "flagWithAmounts": "Over cap: {claimed} (cap {cap})",
        "prompt": "This claim is over its category cap. Approve at the cap, or override and approve the full amount with a reason.",
        "promptWithAmounts": "Claimed {claimed} exceeds the {cap} cap. Approve at the cap, or override and approve the full amount with a reason.",
        "approveAtCap": "Approve at cap",
        "approveFull": "Approve full amount",
        "fullReasonPrompt": "Explain why the full amount should be approved over the cap.",
        "fullReasonPlaceholder": "Briefly explain why this claim is approved above the policy cap.",
        "confirmFull": "Approve full amount"
      }
    },
    "expenseApprovalPush": {
      "title": "Expense approval needed",
      "subtitle": "Waiting for your review",
      "claimCount": "{count, plural, one {# claim} other {# claims}}",
      "review": "Review approval",
      "unknownSubmitter": "A team member",
      "untitledReport": "Untitled report"
    },
    "lateApprovals": {
      "title": "Late Approvals",
      "overdueBadge": "{count} overdue",
      "allCleared": "All cleared",
      "claimCount": "{count, plural, one {# claim} other {# claims}}",
      "dayCount": "{count, plural, one {# day} other {# days}}",
      "approveNow": "Approve Now",
      "confirmApprove": "Approve {amount} from {name}?",
      "yesApprove": "Yes, Approve",
      "cancel": "Cancel",
      "approving": "Approving...",
      "approvalFailed": "Approval failed",
      "tryAgain": "Try again",
      "historicalHint": "From a previous session. Ask \"what needs my approval?\" for current data.",
      "allApproved": "{count, plural, one {All # submission approved.} other {All # submissions approved.}}",
      "oldestWaitingLabel": "Oldest waiting:",
      "businessDays": "{count, plural, one {# business day} other {# business days}}",
      "levelXofY": "Level {level} of {depth}",
      "waitingFinal": "Waiting on final sign-off"
    }
  },
  "x_chat_2": {
    "bulk": {
      "selectAll": "Select All ({count})",
      "deselectAll": "Deselect All ({count})",
      "approveSelected": "Approve Selected ({count})",
      "confirmPrompt": "Approve {count, plural, one {# item} other {# items}}?",
      "confirm": "Confirm",
      "cancel": "Cancel",
      "processing": "Processing {count} items...",
      "allApproved": "All {count} items approved",
      "partialResult": "{success} approved, {failed} failed",
      "retryFailed": "Retry Failed",
      "errors": {
        "noBusinessContext": "No active business is selected. Refresh the page and try again.",
        "postFailed": "We couldn't post this invoice. Nothing was recorded for it. Try it again on its own to see the reason."
      }
    },
    "recon": {
      "cashLegReviewHold": "Review one effective cash leg before matching. This suggestion has not posted or reconciled anything.",
      "cashLegPreview": "Match the cash leg in {entryNumber}; no new journal will be created.",
      "statementStale": "The bank line changed. Open it and review the amount, date and account again.",
      "bankLinkUnresolved": "Choose the bank account and review its linked cash account.",
      "cashLegUnavailable": "This journal is not an effective posted cash movement. Review its posting or reversal.",
      "currencyReview": "The bank and cash-leg currencies cannot be compared safely. Review the currency.",
      "amountMismatch": "The posted cash-leg amount or direction differs from this bank line. Review both amounts.",
      "cashLegAlreadyMatched": "This posted cash leg is already matched to another bank line. Review that link first.",
      "browserRequired": "A signed-in reviewer must confirm this match in the browser.",
      "title": "Bank Reconciliation Match",
      "matchTypeExact": "Exact Match",
      "matchTypeSplit": "Split Match",
      "matchTypeFuzzy": "Fuzzy Match",
      "accepted": "Accepted",
      "rejected": "Rejected",
      "accept": "Accept",
      "reject": "Reject",
      "operationFailed": "Operation failed",
      "matchGone": "This match is no longer available. Someone may have already accepted or rejected it. Ask me to run reconciliation again to see what is still open."
    },
    "reimb": {
      "title": "Expense Reimbursement",
      "paidBadge": "Paid",
      "nothingPaidBadge": "Nothing paid",
      "nothingPaid": "Nothing was paid. {count, plural, one {# claim was} other {All # claims were}} skipped: already reimbursed, or no longer approved. No money moved.",
      "summary": "{claimCount, plural, one {# approved claim} other {# approved claims}} from {employeeCount, plural, one {# employee} other {# employees}}",
      "claimCountParen": "({count, plural, one {# claim} other {# claims}})",
      "unknownVendor": "Unknown vendor",
      "methodBankTransfer": "Bank Transfer",
      "methodCheque": "Cheque",
      "methodCash": "Cash",
      "paymentMethodLabel": "Payment Method",
      "paymentReferenceLabel": "Payment Reference (optional)",
      "paymentReferencePlaceholder": "e.g. TRF-20260319-001",
      "markAsPaid": "Mark as Paid",
      "confirmPrompt": "Mark {count, plural, one {# claim} other {# claims}} as paid via {method}?",
      "confirmYes": "Yes, Mark Paid",
      "cancel": "Cancel",
      "processing": "Processing reimbursement...",
      "tryAgain": "Try again",
      "operationFailed": "Operation failed",
      "successMessage": "{count, plural, one {# claim} other {# claims}} marked as paid via {method}.",
      "skippedSuffix": "({count} skipped)",
      "previewBadge": "To reimburse",
      "claimsCount": "{count, plural, one {# claim} other {# claims}}",
      "cappedAmountHint": "approved (capped) amount",
      "duplicateFlag": "Possible duplicate",
      "totalLabel": "Total",
      "duplicateSummary": "{count, plural, one {# claim flagged as a possible duplicate} other {# claims flagged as possible duplicates}}",
      "skippedNote": "{count, plural, one {# claim skipped (already reimbursed or no longer approved)} other {# claims skipped (already reimbursed or no longer approved)}}",
      "previewPrompt": "Please confirm reimbursing {count, plural, one {# approved claim} other {# approved claims}} at the approved (capped) amount.",
      "resultSummary": "Reimbursed {count, plural, one {# approved claim} other {# approved claims}} at the approved (capped) amount.",
      "confirmBelow": "Confirm or cancel with the card below. Nothing is paid until you confirm.",
      "payingFrom": "Paying from {account}.",
      "payingFromDefault": "No pay-from account was chosen, so the default bank account will be used.",
      "payingFromCash": "Paying in cash from Cash on Hand."
    },
    "cashflow": {
      "title": "Cash Flow Dashboard",
      "runway": "Cash runway",
      "daysValue": "{days} days",
      "runwayOverCap": "More than 5 years",
      "monthlyBurn": "Monthly Expenses",
      "estBalance": "Cash Balance",
      "netCashFlow": "Net Cash Flow",
      "expenseToIncomeRatio": "Expense-to-Income Ratio",
      "viewDetails": "View Details",
      "detailsTitle": "Cash Flow {period}",
      "detailsTitleFallback": "Dashboard",
      "runwayDays": "Cash Runway (days)",
      "monthlyBurnRate": "Monthly Burn Rate",
      "estimatedBalance": "Cash Balance",
      "totalIncome": "Total Income",
      "totalExpenses": "Total Expenses",
      "expenseToIncome": "Expense-to-Income",
      "notBurning": "Cash is not falling",
      "runwayUnknown": "Not enough cash history",
      "noCashAccounts": "No bank or cash accounts yet. Add one in Bank / Cash to see your cash runway.",
      "cashUnverified": "The cash balance is still being checked. Try again shortly.",
      "cashAsAt": "Cash as at {date}",
      "foreignExcluded": "Not included (other currency): {accounts}",
      "runwayNegative": "Cash is negative",
      "runwayEmpty": "No cash on hand",
      "countedAccounts": "Based on {count, plural, one {# registered bank or cash account} other {# registered bank and cash accounts}}{names}",
      "onlyRegistered": "Only registered bank and cash accounts are counted.",
      "profitViewTitle": "Profit view (not cash)",
      "lastStatement": "Bank statement lines up to {date}",
      "noStatement": "No bank statement imported",
      "profitViewTruncated": "Profit view not shown: more than {limit, number} entries in the last {days, number} days"
    },
    "receipt": {
      "title": "Receipt Ready",
      "createdBadge": "Created",
      "expiredBadge": "Expired",
      "deletedBadge": "Deleted",
      "claimCreated": "{count, plural, one {Expense claim created} other {# expense claims created}}",
      "claimAlreadyCreated": "Expense claim already created",
      "createdProcessing": "Created {count, plural, one {# draft expense claim} other {# draft expense claims}}. Processing receipt...",
      "createFailed": "Failed to create expense claim",
      "executionFailed": "Proposal execution failed. Please upload receipt again.",
      "viewInExpenseClaims": "View in Expense Claims →",
      "viewItInExpenseClaims": "You can view it in Expense Claims.",
      "deletedMessage": "This expense claim has been deleted. Upload the receipt again to create a new one.",
      "expiredMessage": "This proposal has expired. Please upload the receipt again to create a new claim.",
      "readyPrompt": "{count, plural, one {# receipt} other {# receipts}} ready to become {count, plural, one {expense claim} other {expense claims}}.",
      "createClaim": "Create Claim",
      "addMoreReceipts": "Add More Receipts",
      "historicalHint": "This is from a previous session. Upload a new receipt to create a claim.",
      "creating": "Creating expense claim...",
      "submittedBadge": "Submitted",
      "concludedMessage": "This expense report has already been submitted for approval. Start a New Chat to begin a fresh report.",
      "startNewChat": "Start New Chat",
      "result": {
        "title": "{count, plural, one {Expense Claim} other {Expense Claims}}",
        "processing": "Reading receipt…",
        "statusProcessing": "Processing",
        "statusReady": "Ready",
        "statusFiled": "Filed",
        "statusApproved": "Approved",
        "statusRejected": "Rejected",
        "routedTo": "Routed to {approver}",
        "unknownVendor": "Unknown vendor",
        "viewDetails": "View details",
        "openReport": "Open expense report",
        "createdSummary": "{count, plural, one {# expense claim created} other {# expense claims created}} in {title}."
      },
      "readingNotStarted": "{count} of your receipts could not start reading. They are saved as drafts, so open them from your claims to try again.",
      "duplicateHeading": "{count, plural, one {# receipt looks already claimed} other {# receipts look already claimed}}",
      "duplicateReceipt": "Receipt: {vendor}, {amount} on {date}",
      "duplicateMatchSame": "Already in {report} ({status})",
      "duplicateMatchSameNoStatus": "Already in {report}",
      "duplicateMatchPossible": "Possibly in {report} ({status}). {differences}",
      "duplicateMatchPossibleNoStatus": "Possibly in {report}. {differences}",
      "duplicateMatchDiffers": "Already in {report} ({status}): {vendor}, {amount} on {date}",
      "duplicateMatchDiffersNoStatus": "Already in {report}: {vendor}, {amount} on {date}",
      "duplicateMatchMore": "{count, plural, one {# more match} other {# more matches}}",
      "duplicateOpen": "Open submission",
      "duplicateNote": "Create Claim still creates these claims. Submitting may ask you for a reason.",
      "duplicateStatusDraft": "Draft",
      "duplicateStatusSubmitted": "Submitted",
      "duplicateStatusApproved": "Approved",
      "duplicateStatusReimbursed": "Reimbursed"
    },
    "actionProposal": {
      "title": "Confirm action",
      "confirmedBadge": "Confirmed",
      "cancelledBadge": "Cancelled",
      "expiredBadge": "Expired",
      "confirmedMessage": "{action} confirmed.",
      "cancelledMessage": "Action cancelled. Nothing was changed.",
      "expiredMessage": "This confirmation expired. Ask again to retry.",
      "executionFailed": "The action could not be completed.",
      "confirmFailed": "Could not confirm the action.",
      "cancelFailed": "Could not cancel the action.",
      "readyPrompt": "Ready to {action}? This needs your confirmation.",
      "confirmButton": "Confirm",
      "cancelButton": "Cancel",
      "historicalHint": "This confirmation is from an earlier message.",
      "processing": "Processing…",
      "actions": {
        "approveLeave": "approve this leave request",
        "rejectLeave": "reject this leave request",
        "confirmReconMatch": "accept this reconciliation match",
        "rejectReconMatch": "reject this reconciliation match",
        "runReconMatching": "run bank reconciliation",
        "storeMemory": "save this to memory",
        "forgetMemory": "forget this memory",
        "setBudget": "set this budget",
        "removeBudget": "remove this budget",
        "genericAction": "this action"
      },
      "suggestPrompt": "I couldn’t find a category named “{name}”. Did you mean one of these?",
      "noSuggestions": "I couldn’t find a category named “{name}” or anything close. Create it first, then try again.",
      "proposalGone": "This confirmation is no longer available. It may have expired or already been handled. Ask me again and I will propose it fresh."
    },
    "expenseWorkflow": {
      "confirmTitle": {
        "submit": "Confirm submission",
        "approve": "Confirm approval",
        "reject": "Confirm rejection",
        "reimburse": "Confirm reimbursement",
        "update": "Confirm changes",
        "default": "Confirm action"
      },
      "resultTitle": {
        "submit": "Report submitted",
        "approve": "Report approved",
        "reject": "Report returned",
        "reimburse": "Expense reimbursed",
        "update": "Changes saved",
        "default": "Action completed"
      },
      "failedTitle": "Action failed",
      "doneBadge": "Done",
      "confirmButton": "Confirm",
      "cancelButton": "Cancel",
      "confirmSentBadge": "Confirmed",
      "cancelledBadge": "Cancelled",
      "confirmSentMessage": "Confirmation sent. Finishing up in chat.",
      "cancelledMessage": "Cancelled. Nothing was changed.",
      "historicalHint": "This confirmation is from an earlier message.",
      "routing": {
        "routedTo": "Routed to {approver}",
        "policy": "Policy: {name}",
        "multiplePolicies": "Multiple approval policies",
        "multiStep": "Multi-step approval (up to {depth, plural, one {# level} other {# levels}})",
        "singleStep": "Single-step approval",
        "flagged": "{count, plural, one {# claim needs review} other {# claims need review}}"
      },
      "proposedChangesTitle": "Proposed changes",
      "fields": {
        "title": "Title",
        "description": "Description",
        "vendor_name": "Vendor",
        "amount": "Amount",
        "currency": "Currency",
        "transaction_date": "Date",
        "reference_number": "Reference",
        "expense_category": "Category",
        "business_purpose": "Business purpose",
        "yes": "Yes",
        "no": "No"
      }
    },
    "fallback": {
      "somethingWrong": "Something went wrong with this action."
    }
  },
  "x_chat_3": {
    "revenue": {
      "title": "Revenue Summary"
    },
    "invoice": {
      "title": "Invoice Posting",
      "historicalHint": "This is from a previous session. Ask \"show invoices to post\" for up-to-date actions."
    },
    "vendor": {
      "title": "Vendor Comparison"
    },
    "single": {
      "title": "Receipt Claim"
    },
    "header": {
      "txnCount": "{count} txn{count, plural, one {} other {s}}"
    },
    "columns": {
      "source": "Source",
      "amount": "Amount",
      "transactions": "Transactions",
      "percentOfTotal": "% of Total",
      "vendor": "Vendor",
      "avgPrice": "Avg Price",
      "onTimePercent": "On-Time %",
      "rating": "Rating",
      "totalSpend": "Total Spend",
      "spendPercent": "Spend %",
      "riskScore": "Risk Score",
      "trend": "Trend"
    },
    "metrics": {
      "avgPrice": "Avg Price",
      "onTime": "On-Time",
      "transactions": "Transactions",
      "totalSpend": "Total Spend",
      "spendPercent": "Spend %",
      "riskScore": "Risk Score",
      "trend": "Trend",
      "categories": "Categories"
    },
    "trend": {
      "increasing": "Increasing",
      "stable": "Stable",
      "decreasing": "Decreasing"
    },
    "period": {
      "thisMonth": "This month",
      "lastMonth": "Last month",
      "thisQuarter": "This quarter",
      "thisYear": "This year",
      "allTime": "All time",
      "custom": "Custom"
    },
    "status": {
      "posted": "Posted",
      "submitted": "Submitted",
      "cancelled": "Cancelled",
      "lowConfidence": "Low Confidence"
    },
    "batch": {
      "receiptsProcessed": "{count, plural, one {# Receipt Processed} other {# Receipts Processed}}",
      "receiptsFailed": "{count, plural, one {# receipt failed to process} other {# receipts failed to process}}"
    },
    "actions": {
      "exportCsv": "Export CSV",
      "exportCsvTitle": "Export as CSV",
      "viewDetails": "View Details",
      "postToAccounting": "Post to Accounting",
      "confirm": "Confirm",
      "cancel": "Cancel",
      "tryAgain": "Try again",
      "viewVendorHistory": "View Vendor History",
      "submit": "Submit",
      "submitAll": "Submit All",
      "edit": "Edit"
    },
    "errors": {
      "noBusinessContext": "No active business context. Please refresh and try again.",
      "failedToPost": "Failed to post invoice",
      "documentUnavailable": "We couldn't open this document. Please try again."
    },
    "totalRevenue": "Total Revenue",
    "detailsTitle": "Revenue Summary for {period}",
    "due": "Due {date}",
    "lowConfidenceWarning": "Low OCR confidence ({percent}%). Review before posting",
    "moreItems": "+{count} more items",
    "ocrConfidence": "OCR confidence: {percent}%",
    "confirmPost": "Post {amount} from {vendor} to accounting?",
    "posting": "Posting to accounting...",
    "processing": "Processing...",
    "riskFactors": "Risk factors",
    "narrowByPeriod": "Narrow by period",
    "pickTeamMember": "Pick a team member",
    "employeeSelected": "Employee: {name}",
    "narrowByCategory": "Narrow by category",
    "categorySelected": "Category: {category}",
    "loadingOptions": "Loading…",
    "noTeamMembers": "No direct reports found.",
    "noCategories": "No categories found.",
    "pickBankAccount": "Choose bank account",
    "bankAccountSelected": "Bank account: {account}",
    "noBankAccounts": "No bank accounts found.",
    "paymentDateLabel": "Payment date",
    "bankAccountFallback": "selected account",
    "filtered": "Filtered: {period}",
    "customDateRange": "Custom date range...",
    "to": "to",
    "go": "Go",
    "total": "Total",
    "notConfidentAbout": "Not confident about: {fields}",
    "duplicateWarning": "Possible duplicate: a similar claim already exists",
    "duplicate": {
      "badgeSuspected": "Possible duplicate",
      "badgeConfirmed": "Confirmed duplicate",
      "matchingTitle": "{count, plural, one {# matching expense already exists} other {# matching expenses already exist}}",
      "unknownVendor": "Unknown vendor",
      "justificationPrompt": "This looks like a duplicate. Add a justification to submit it anyway.",
      "justificationPlaceholder": "e.g. Separate meals on the same day with different attendees",
      "justificationRequired": "A justification is required before submitting a duplicate.",
      "submitAnyway": "Submit anyway",
      "confirm": "Confirm & submit",
      "cancel": "Cancel",
      "justified": "Justification recorded",
      "noMatchOnFile": "Possible duplicate, but no exact prior match on file"
    },
    "viewInExpenseClaims": "View in Expense Claims",
    "receipt": {
      "historicalHint": "This is from a previous session. Send a new receipt photo for up-to-date actions."
    },
    "bankAccountNeedsGlLink": "This account needs a chart of accounts account linked before you can pay from it.",
    "bankAccountsNeedGlLinkHint": "Greyed-out accounts need a chart of accounts account linked first. Link them on Accounting, then Chart of Accounts."
  },
  "x_chat_4": {
    "teamComparison": {
      "title": "Team Spending Comparison",
      "csv": {
        "employee": "Employee",
        "totalSpend": "Total Spend",
        "claimCount": "Claim Count",
        "outlier": "Outlier",
        "topCategories": "Top Categories",
        "yes": "Yes",
        "no": "No"
      },
      "exportCsvAria": "Export CSV",
      "exportCsvTitle": "Export as CSV",
      "teamAvgTooltip": "Team avg: {amount}",
      "teamAverageLegend": "Team average: {amount}",
      "teamTotalLabel": "Team total:",
      "averageLabel": "Average:",
      "outlierThresholdLabel": "Outlier threshold:"
    },
    "spendingChart": {
      "csv": {
        "category": "Category",
        "amount": "Amount",
        "percentage": "Percentage"
      },
      "exportCsvAria": "Export CSV",
      "exportCsvTitle": "Export as CSV",
      "total": "Total"
    },
    "leaveApproval": {
      "defaultRejectReason": "Rejected via chat assistant",
      "operationFailed": "Operation failed",
      "title": "Leave Request",
      "statusApproved": "Approved",
      "statusRejected": "Rejected",
      "employeeLabel": "Employee",
      "leaveTypeLabel": "Leave Type",
      "periodLabel": "Period",
      "periodRange": "{start} to {end}",
      "durationLabel": "Duration",
      "durationDays": "{count, plural, one {# day} other {# days}}",
      "approveButton": "Approve",
      "rejectButton": "Reject",
      "rejectReasonPlaceholder": "Reason for rejection...",
      "confirmRejectButton": "Confirm Reject",
      "cancelButton": "Cancel",
      "tryAgain": "Try again",
      "historicalHint": "This leave request may have already been actioned.",
      "insufficientBalance": "Not enough leave left. {remaining, plural, one {# day} other {# days}} available for {year}, and this request needs {requested, plural, one {# day} other {# days}}. Adjust the balance in Leave management, then approve."
    },
    "forecast": {
      "title": "Cash Flow Forecast",
      "monthsCount": "({count, plural, one {# month} other {# months}})",
      "riskHealthy": "Healthy",
      "riskLevel": {
        "medium": "Medium Risk",
        "high": "High Risk",
        "critical": "Critical Risk"
      },
      "runwayLabel": "Cash runway",
      "runwayUnknown": "Not enough cash history",
      "knownItemsOnly": "Projected from known receivables and payables only; there is not enough cash history for a run-rate.",
      "foreignItemsExcluded": "{count, plural, one {# foreign-currency item is} other {# foreign-currency items are}} not projected ({amounts}).",
      "startingCash": "Starting cash {amount} as at {date}",
      "foreignExcluded": "Not included (other currency): {accounts}",
      "runwayMonths": "{value} months",
      "knownArLabel": "Known AR",
      "knownApLabel": "Open AP bills with a due date",
      "incomeTooltip": "Income: {amount}",
      "expensesTooltip": "Expenses: {amount}",
      "incomeLegend": "Income",
      "expensesLegend": "Expenses",
      "balanceLabel": "Balance:",
      "riskAlertsCount": "{count, plural, one {# risk alert} other {# risk alerts}}",
      "runwayNegative": "Cash is negative",
      "runwayEmpty": "No cash on hand",
      "ledgerPayablesGap": "The ledger holds {balance} of payables; {unscheduled} of it is not deducted from the projected cash: it has no due date, is overdue, is due this month, or falls beyond the forecast.",
      "ledgerPayablesUnavailable": "Ledger payables could not be read, so the AP figure covers only open supplier bills with a due date.",
      "countedAccounts": "Based on {count, plural, one {# registered bank or cash account} other {# registered bank and cash accounts}}: {names}",
      "sources": "Figures: Cash Book balance, the cash run-rate of those accounts, and open customer and supplier bills with a due date.",
      "sourcesCashOnly": "Figures: Cash Book balance and the cash run-rate of those accounts only. Open customer and supplier bills are not included.",
      "sourcesCashOnlyRole": "Figures: Cash Book balance and the cash run-rate of those accounts only. Open invoices and bills are not included because your role cannot see them.",
      "lastStatement": "Bank statement lines up to {date}",
      "noStatement": "No bank statement imported"
    },
    "budgetAlert": {
      "status": {
        "on_track": "On Track",
        "above_average": "Above Average",
        "overspending": "Overspending"
      },
      "title": "Budget Alert",
      "csv": {
        "category": "Category",
        "currentSpend": "Current Spend",
        "averageSpend": "Average Spend",
        "percentOfAverage": "% of Average",
        "status": "Status"
      },
      "exportCsvAria": "Export CSV",
      "exportCsvTitle": "Export as CSV",
      "avgPrefix": "avg {amount}",
      "total": "Total",
      "totalAvgSuffix": "/ avg {amount}",
      "detailsTitle": "Budget Alert for {period}",
      "detailsColumns": {
        "category": "Category",
        "current": "Current",
        "average": "Average",
        "percentOfAvg": "% of Avg",
        "status": "Status"
      },
      "viewDetails": "View Details"
    }
  },
  "x_expense_0": {
    "stockIntake": {
      "switchLabel": "Track stock from this receipt",
      "supplierLabel": "Supplier",
      "chooseItems": "Choose items",
      "chip": "Stock: {stock} of {total} lines",
      "chipWithSupplier": "Stock: {stock} of {total} lines, {supplier}",
      "saveLinesFirst": "Save the claim once so its line items can be chosen.",
      "noLines": "This receipt has no line items to choose from.",
      "unavailablePlan": "Stock tracking is not available on your plan.",
      "unavailableMode": "Inventory is not managed in Groot for this business, so receipts cannot track stock.",
      "waitingForLines": "Line items are still being read. Stock can be chosen once they are ready.",
      "planSaved": "Stock items saved.",
      "saveFailed": "Could not save the stock choice. Please try again.",
      "chooseTitle": "Choose stock items",
      "categoryOnlyWaiting": "Line items are still being read. Categories can be chosen once they are ready.",
      "categoryOnlySaved": "Categories saved.",
      "categoryOnlyTitle": "Choose categories per line",
      "categoryOnlyHint": "Choose a category for each line, or keep the claim category.",
      "categoryOnlySummary": "Categories selected: {count}. Other lines keep the claim category.",
      "categoryOnlySave": "Save categories",
      "categoryOnlySaveFailed": "Could not save categories. Try again.",
      "lineCategory": "Category for this line",
      "chooseCategories": "Choose categories per line",
      "categoryChip": "{count} lines re-categorised",
      "expenseGroup": "Expense categories",
      "cogsGroup": "Cost of goods sold",
      "claimCategory": "Claim category ({name})",
      "claimCategoryUnnamed": "Claim category",
      "itemsPlanned": "of {total} lines will be received as stock",
      "itemsToReview": "{count} unmatched items will go to catalog review when you submit.",
      "savePlan": "Save {count} stock items",
      "saving": "Saving",
      "supplierAdd": "Add {name} as a new supplier",
      "supplierAdding": "Adding supplier",
      "errors": {
        "supplierRequired": "Confirm the supplier on this receipt before submitting a claim that tracks stock.",
        "linesStale": "The line items changed after stock items were chosen. Open Choose items again before submitting.",
        "doesNotFoot": "The stock lines on this receipt are worth more than the claim amount. Correct the quantities or unit costs."
      }
    },
    "analytics": {
      "noDataAvailable": "No analytics data available",
      "unavailableTitle": "Analytics could not load",
      "unavailableDescription": "We could not reach the analytics service. Your expense records are unaffected.",
      "retry": "Try again",
      "totalAmount": "Total Amount",
      "totalClaims": "Total Claims",
      "avgClaim": "Avg Claim",
      "pendingApproval": "Pending Approval",
      "expenseCategories": "Expense Categories",
      "categoryBreakdownPersonal": "Your expense breakdown by category",
      "categoryBreakdownDepartment": "Department expense breakdown by category",
      "categoryBreakdownCompany": "Company-wide expense breakdown by category",
      "noCategoryData": "No category data available",
      "noCategoryDataHint": "Submit some expense claims to see category breakdown",
      "categoryDetails": "Category Details",
      "claimsCount": "{count, plural, one {# claim} other {# claims}}",
      "monthlyTrends": "Monthly Trends",
      "monthlyTrendsDescription": "Expense trends over the last 3 months",
      "noTrendData": "No trend data available",
      "noTrendDataHint": "Submit expense claims over multiple months to see trends",
      "approvedAmount": "Approved: {amount}",
      "total": "Total"
    },
    "submissions": {
      "title": "Expense Submissions",
      "count": "{count, plural, one {# submission} other {# submissions}}",
      "filteredSuffix": " (filtered)",
      "newSubmission": "New Submission",
      "filterAll": "All",
      "statusDraft": "Draft",
      "statusPending": "Pending",
      "statusApproved": "Approved",
      "statusRejected": "Rejected",
      "statusReimbursed": "Reimbursed",
      "newestFirst": "Newest first",
      "oldestFirst": "Oldest first",
      "dateTo": "to",
      "clearFilters": "Clear filters",
      "emptyFiltered": "No submissions match your filters",
      "tryAdjustingFilters": "Try adjusting your filters or",
      "clearAllFilters": "clear all filters",
      "emptyNoSubmissions": "No expense submissions yet",
      "emptyNoSubmissionsHint": "Create a submission to batch upload receipts for approval",
      "claimCount": "{count, plural, one {# claim} other {# claims}}",
      "submit": "Submit",
      "cancel": "Cancel",
      "submitDialogTitle": "Submit for Approval",
      "submitDialogMessage": "Submit this expense submission for approval? All claims will be sent to your approver.",
      "failedToSubmit": "Failed to submit",
      "searchPlaceholder": "Search code or title",
      "searchLabel": "Search expense reports",
      "convertedTotal": "Total in {currency}",
      "unconvertedClaims": "{count} not converted",
      "submitDialogTitleNoApproval": "File Expense Report",
      "submitDialogMessageNoApproval": "File this expense report? Every claim in it posts straight away as an expense you are owed.",
      "emptyNoSubmissionsHintNoApproval": "Create a submission to batch upload receipts"
    },
    "camera": {
      "captureFailed": "Failed to capture photo. Please try again.",
      "notSupported": "Camera not supported on this device",
      "noCameraFound": "No camera found on this device",
      "initFailed": "Failed to initialize camera",
      "unableToAccess": "Unable to access camera. Please check permissions.",
      "switchFailed": "Failed to switch camera",
      "initializing": "Initializing camera...",
      "tryAgain": "Try Again",
      "cancel": "Cancel",
      "capturedReceiptAlt": "Captured receipt",
      "retake": "Retake",
      "processing": "Processing...",
      "usePhoto": "Use Photo",
      "captureReceipt": "Capture Receipt",
      "alignReceipt": "Align receipt within frame",
      "permissionDenied": "Camera access is turned off. Enable it for Groot in your device Settings, then try again."
    },
    "createExpense": {
      "defaultPageTitle": "Create Expense Claim",
      "defaultPageDescription": "Fill out the expense details below",
      "invalidFileType": "Please select a valid image (JPEG, PNG, WebP) or PDF file",
      "fileTooLarge": "File size must be less than 10MB",
      "uploadSuccessAi": "Receipt uploaded successfully! AI processing started. Task ID: {taskId}",
      "uploadSuccess": "Receipt uploaded successfully: {message}",
      "uploadFailed": "Upload failed",
      "uploadFailedWithReason": "Upload failed: {reason}",
      "unknownError": "Unknown error",
      "loadingTitle": "Loading Expense Form",
      "loadingDescription": "Please wait while we prepare the form...",
      "cannotLoadTitle": "Cannot Load Expense Form",
      "goBack": "Go Back",
      "back": "Back",
      "manualEntry": "Manual Entry",
      "manualEntryDescription": "Creating expense claim with manual data entry",
      "aiExtracted": "AI Extracted",
      "aiExtractedDescription": "Data extracted from receipt using AI • {method}",
      "savingDraft": "Saving Draft...",
      "saveAsDraft": "Save as Draft",
      "checking": "Checking...",
      "submitting": "Submitting...",
      "submitForApproval": "Submit for Approval"
    },
    "payment": {
      "methodBankTransfer": "Bank Transfer",
      "methodCheque": "Cheque",
      "methodCash": "Cash",
      "methodOnlineTransfer": "Online Transfer",
      "methodPayNow": "PayNow",
      "methodDuitNow": "DuitNow",
      "title": "Payment Processing",
      "description": "Approved expense claims ready for reimbursement",
      "allEmployees": "All Employees",
      "allCategories": "All Categories",
      "emptyTitle": "No approved claims pending payment",
      "emptyDescription": "All approved claims have been processed",
      "selectedCount": "{selected} of {total} selected",
      "selectAll": "Select All ({count, plural, one {# claim} other {# claims}})",
      "totalLabel": "Total: {total}",
      "markAsPaidButton": "Mark as Paid ({count})",
      "claimCount": "{count, plural, one {# claim} other {# claims}}",
      "individualClaims": "Individual Claims (no submission)",
      "processedResult": "Processed {count, plural, one {# claim} other {# claims}} totalling {total}{skipped}",
      "nothingPaid": "Nothing was paid: all {count, plural, one {# selected claim} other {# selected claims}} were skipped because they are already reimbursed or no longer approved. Refresh the list and select claims that are still awaiting payment.",
      "skippedSuffix": " ({count} skipped)",
      "errorPrefix": "Error: {message}",
      "paymentProcessingFailed": "Payment processing failed",
      "sentBackSuccess": "Claim sent back to employee for correction.",
      "sendBackFailed": "Send back failed",
      "confirmDialogTitle": "Confirm Payment",
      "confirmDialogMessage": "Process {count} claim(s) totaling {total}",
      "paymentMethodLabel": "Payment Method (optional)",
      "selectMethodPlaceholder": "Select method",
      "payFromAccountLabel": "Pay from account",
      "noPayFromAccountConfigured": "No bank account in your chart of accounts is available to pay from. Set one up on Accounting → Chart of Accounts, then confirm the payment again.",
      "cashPayFromAccount": "{code} · {name} (cash on hand)",
      "cashPayFromAccountLoading": "Checking your cash on hand account…",
      "cashAccountNotConfigured": "You have not set a cash on hand account, so a cash payment cannot be recorded. Set one up on Accounting → Chart of Accounts, then confirm the payment again.",
      "cashPaymentNamesBankAccount": "This payment is set to cash but also names a bank account to pay from. A cash payment comes out of your cash on hand account. Clear the bank account, or change the payment method.",
      "homeAmountUnavailableNamed": "Cannot record this payment yet. The claim {claim} is in {claimCurrency} and your books are in {homeCurrency}, so its amount cannot be converted. If your plan includes exchange rates, add a {claimCurrency} to {homeCurrency} rate for {date} on Accounting → Chart of Accounts. Otherwise use \"Send back for correction\" on that claim in this list, ask the employee to enter the {homeCurrency} amount and resubmit it, then confirm the payment once it is approved again. Or deselect it and pay the rest.",
      "noReceiptDateNamed": "Cannot record this payment yet. The claim {claim} has no receipt date, so there is no accounting period to record its expense in. An approved claim cannot be edited, so use \"Send back for correction\" on that claim in this list, ask the employee to add the date and resubmit it, then confirm the payment once it is approved again. Or deselect it and pay the rest.",
      "noCurrencyNamed": "Cannot record this payment yet. The claim {claim} has no currency, so its amount cannot be recorded. An approved claim cannot be edited, so use \"Send back for correction\" on that claim in this list, ask the employee to set the currency and resubmit it, then confirm the payment once it is approved again. Or deselect it and pay the rest.",
      "accrualShareDiffersNamed": "Cannot record this payment yet. For the claim {claim}, the amount to pay is not the amount its approval entry accrued, so nothing was paid. An approved claim cannot be edited, so use \"Send back for correction\" on that claim in this list, ask the employee to resubmit it, then confirm the payment once it is approved again. Or deselect it and pay the rest.",
      "expenseAccountNotConfiguredNamed": "Cannot record this payment yet. The claim {claim} has no expense account to post to, because this business has no active expense account. Add one, or restore an archived one, in Accounting → Chart of Accounts, then confirm the payment again. Or deselect it and pay the rest.",
      "expenseAccountBranchArchivedNamed": "Cannot record this payment yet. The category of the claim {claim} posts to account {headingCode}, which groups sub-accounts, and every sub-account under it is archived. Restore one of them in Accounting → Chart of Accounts, then confirm the payment again. Or use \"Send back for correction\" on that claim in this list, ask the employee to choose a different category and resubmit it, then confirm the payment once it is approved again. Or deselect it and pay the rest.",
      "claimNotPostableNamed": "Cannot record this payment yet. The claim {claim} cannot be posted, because the approval entry it clears cannot be read back, so nothing was paid. Deselect that claim and pay the rest, then contact support with this claim.",
      "paymentReferenceLabel": "Payment Reference (optional)",
      "paymentReferencePlaceholder": "e.g. TXN-2026-0301",
      "cancel": "Cancel",
      "confirmPayment": "Confirm Payment",
      "sendBackDialogTitle": "Are you sure you want to send this claim back?",
      "sendBackDialogMessage": "This claim will be returned to the employee for correction. After fixing, it will come back directly to Payment Processing (no manager re-approval needed).",
      "reasonLabel": "Reason (required)",
      "reasonPlaceholder": "e.g. Missing receipt, incorrect amount",
      "sendBackButton": "Send Back",
      "expenseFallback": "Expense",
      "splitBadge": "Split",
      "duplicateBadge": "Duplicate",
      "justificationLabel": "Justification: {reason}",
      "refLabel": "Ref: {reference}",
      "sendBackForCorrection": "Send back for correction",
      "cappedFrom": "capped from {claimed}",
      "batchCodeHeading": "Reimbursement batch",
      "batchCodeHintBank": "Record this reference against the bank payment so you can trace it back to these claims.",
      "batchCodeHintCash": "Record this reference against the cash paid out of your till so you can trace it back to these claims.",
      "batchCodeCopy": "Copy reimbursement batch code",
      "batchCodeCopyFailed": "Could not copy the code. Select it and copy manually.",
      "batchCodeDismiss": "Dismiss batch code",
      "openClaim": "Open the claim for {name}",
      "voucherMore": "+{count}",
      "voucherListLabel": "Vouchers",
      "voucherHeadingCash": "Petty cash voucher",
      "voucherHeadingBank": "Payment voucher",
      "voucherCodeCopy": "Copy voucher number",
      "homeTotalLabel": "Total to pay: {total}",
      "unconvertedClaims": "{count, plural, one {# claim is} other {# claims are}} not in this total: no {currency} conversion recorded",
      "noHomeConversion": "No {currency} conversion recorded",
      "categoryUnnamed": "Uncategorised"
    },
    "batchHistory": {
      "title": "Reimbursement history",
      "description": "Every payment run, searchable by its batch code.",
      "searchPlaceholder": "Search voucher or report code",
      "searchLabel": "Search reimbursement batches",
      "emptyTitle": "No payment runs yet",
      "emptyDescription": "When you mark approved claims as paid, each run appears here with its own code.",
      "emptySearchTitle": "No batches match your search",
      "emptySearchDescription": "Check the code, or clear the search to see every payment run.",
      "detailTitle": "Payment run",
      "detailUnavailable": "This payment run could not be loaded.",
      "detailDescription": "Everything this payment run settled: its reference, how it was paid, and the expenses it cleared.",
      "reconstructedBadge": "Reconstructed",
      "standaloneClaim": "Individual claim",
      "colTotal": "Total paid",
      "colPaidBy": "Paid by",
      "colPaymentDate": "Payment date",
      "colMethod": "Method",
      "colReference": "Reference",
      "colEntries": "Journal entries",
      "missingClaims": "{count, plural, one {# claim in this run has since been deleted.} other {# claims in this run have since been deleted.}}",
      "openClaim": "Open the claim for {name}",
      "searchHint": "Search a voucher number (PV…, PCV…) or a report code (ER…). A report code shows the payment that settled it.",
      "searchTruncated": "There may be more matches than shown. Search the full code for an exact answer.",
      "emptyReportSearchDescription": "No payment has settled that report yet, or the code belongs to another business. Check the code on the report page.",
      "matchedReport": "Report {code}",
      "reconstructedExplainLabel": "About reconstructed payment runs",
      "reconstructedExplainBody": "This run was rebuilt from historic claims that share a payment time and reference, because it happened before payment runs were recorded. It is evidence that the payment was made. It is not proof of where one payment ended and the next began.",
      "settledBy": "Settled by payment",
      "settledByRuns": "Settled by {count, plural, one {# payment} other {# payments}}"
    },
    "sqlExport": {
      "filterLabel": "Not exported only",
      "notExported": "Not exported",
      "exportedAt": "Exported {date}",
      "copy": "Copy for SQL",
      "copyAgain": "Copy again",
      "copySelected": "Copy selected for SQL",
      "clearSelection": "Clear selection",
      "selectRun": "Select payment run {code} for the SQL Account export",
      "selectedCount": "{count, plural, one {# payment run selected} other {# payment runs selected}}",
      "copiedTitle": "Copied {rows, plural, one {# row} other {# rows}} for {runs, plural, one {# payment run} other {# payment runs}}.",
      "pasteHint": "Paste at cell A6 of the SQL Account Cash Book sheet.",
      "skippedRows": "{count, plural, one {# receipt was left out of these rows.} other {# receipts were left out of these rows.}}",
      "mapCodesHint": "Missing SQL codes are added on Import & Export, in the Map Codes step.",
      "requeue": "Re-queue",
      "requeueConfirm": "Confirm re-queue",
      "requeueCancel": "Cancel",
      "requeueHint": "Puts this payment run back under \"Not exported\". Nothing in SQL Account changes.",
      "requeuedNotice": "{count, plural, one {# payment run is back under \"Not exported\".} other {# payment runs are back under \"Not exported\".}}",
      "errors": {
        "notPermitted": "Only the owner or a finance admin can export payment runs to SQL Account. Ask one of them to copy this run.",
        "jeExpenseLaneLive": "This business already exports expense claims through the {card} card, so a payment voucher would post the same expense twice. Turn that card off on Import & Export before exporting payment vouchers.",
        "nothingSelected": "Pick at least one payment run first.",
        "tooManyRuns": "That is more than {limit} payment runs at once. Copy them in smaller groups.",
        "runsUnavailable": "{count, plural, one {Groot could not load one of the selected payment runs} other {Groot could not load # of the selected payment runs}}, so nothing was copied. Refresh the list and try again.",
        "runsStale": "One of the selected payment runs no longer exists, so nothing was recorded. Refresh the list and try again.",
        "nothingExportable": "Nothing in this selection could be exported. The notes below say why, run by run.",
        "clipboard": "Groot could not write to your clipboard, so nothing was copied and these payment runs are still marked not exported. Allow clipboard access in your browser and try again.",
        "notRecorded": "The rows are on your clipboard, but Groot could not record the export, so this payment run still reads as not exported.",
        "copyFailed": "Groot could not build the rows for SQL Account. Please try again.",
        "requeueFailed": "Groot could not re-queue that payment run. Please try again."
      }
    }
  },
  "x_expense_1": {
    "myReports": "My Reports",
    "allEmployees": "All Employees",
    "allDirectReports": "All Direct Reports",
    "employeeIdFallback": "Employee ID: {id}",
    "errorSelectMonth": "Please select a month",
    "errorGenerateReport": "Failed to generate report",
    "errorGenerateFormattedReport": "Failed to generate formatted report",
    "errorNetworkRetry": "Network error. Please try again.",
    "generateMonthlyReport": "Generate Monthly Report",
    "generateMonthlyReportDescription": "Create detailed expense reports for compliance and reimbursement processing",
    "reportMonthLabel": "Report Month *",
    "selectMonthPlaceholder": "Select month",
    "periodLabel": "Period *",
    "selectPeriodPlaceholder": "Select period",
    "categoryFilterLabel": "Category",
    "categoryAllCategories": "All categories",
    "categorySelectedCount": "{count} selected",
    "categoryUncategorized": "Uncategorized",
    "categoryClearSelection": "Clear selection",
    "errorSelectDateRange": "Please pick a start and end date, with the start on or before the end",
    "employeeLabel": "Employee",
    "selectEmployeePlaceholder": "Select employee (optional)",
    "statusFilterLabel": "Status Filter",
    "filterByStatusPlaceholder": "Filter by status",
    "loadingButton": "Loading...",
    "generatingButton": "Generating...",
    "summaryPreview": "Summary Preview",
    "formattedPreview": "Formatted Preview",
    "exportCsv": "Export CSV",
    "monthlyExpenseReport": "Monthly Expense Report",
    "summaryTotalClaims": "Total Claims",
    "summaryTotalAmount": "Total Amount",
    "claimsCount": "{count, plural, one {# claim} other {# claims}}",
    "categoryBreakdown": "Category Breakdown",
    "reportEmptyNoClaimsTitle": "No claims in this period",
    "reportEmptyNoClaimsBody": "Try a wider date range, or a different employee or status.",
    "reportEmptyNoneInSelectedTitle": "No claims in the categories you picked",
    "reportEmptyNoneInSelectedBody": "Other claims in this period are categorised, just not under {count, plural, one {the category} other {the # categories}} you selected.",
    "reportEmptyNothingCategorizedTitle": "No claim in this period has a category",
    "reportEmptyNothingCategorizedBody": "{count, plural, one {# claim here carries no category} other {All # claims here carry no category}}, so no category filter can match. Set a category on each claim, then run the report again.",
    "reportEmptyShowAllCategories": "Show all categories",
    "reportGeneratedOn": "Report generated on: {datetime}",
    "reportScope": "Report scope: {scope}",
    "reportGeneratedBy": "Generated by: {role}",
    "reportDataAsOf": "Data as of: {date}",
    "recentReports": "Recent Reports",
    "recentReportsDescription": "Quick access to previously generated reports",
    "noRecentReports": "No recent reports",
    "noRecentReportsHint": "Generate your first monthly report to see it here",
    "statusAllStatuses": "All Statuses",
    "statusDraft": "Draft",
    "statusSubmittedPending": "Submitted (Pending)",
    "statusApproved": "Approved",
    "statusRejected": "Rejected",
    "statusReimbursed": "Reimbursed",
    "statusSubmitted": "Submitted",
    "errorFetchCategories": "Failed to fetch categories",
    "errorNetworkFetchCategories": "Network error while fetching categories",
    "categoryUpdatedSuccess": "Category updated successfully",
    "categoryCreatedSuccess": "Category created successfully",
    "errorSaveCategory": "Failed to save category",
    "errorNetworkSaveCategory": "Network error while saving category",
    "categoryDeletedSuccess": "Category deleted successfully",
    "errorDeleteCategory": "Failed to delete category",
    "errorNetworkDeleteCategory": "Network error while deleting category",
    "managersOnlyMessage": "Only managers and Finance can manage expense categories",
    "expenseCategories": "Expense Categories",
    "manageCategoriesDescription": "Create and manage custom expense categories for your organization",
    "addCategory": "Add Category",
    "searchCategoriesPlaceholder": "Search categories...",
    "loadingCategories": "Loading categories...",
    "noCategoriesMatchSearch": "No categories match your search",
    "noCategoriesFound": "No categories found",
    "inactive": "Inactive",
    "default": "Default",
    "receiptRequired": "Receipt required",
    "receiptNotRequired": "Receipt not required",
    "receiptThreshold": "above {amount}",
    "managerApprovalRequired": "Manager approval required",
    "managerApprovalNotRequired": "No manager approval required",
    "policyLimit": "Policy limit: {amount}",
    "monthlyBudget": "Monthly budget: {currency} {amount}",
    "noBudgetSet": "No budget set",
    "keywordsLabel": "Keywords: {keywords}",
    "edit": "Edit",
    "deleteCategoryTitle": "Delete Category",
    "deleteCategoryMessage": "Are you sure you want to delete \"{name}\"? This action cannot be undone.",
    "delete": "Delete",
    "cancel": "Cancel",
    "errorFetchReport": "Failed to fetch report",
    "errorDismissDuplicate": "Failed to dismiss duplicate",
    "errorNetworkDismissDuplicate": "Network error while dismissing duplicate",
    "errorConfirmDuplicate": "Failed to confirm duplicate",
    "errorNetworkConfirmDuplicate": "Network error while confirming duplicate",
    "errorBulkDismiss": "Failed to bulk dismiss duplicates",
    "pageTitle": "Duplicate Expense Detection",
    "pageDescription": "Review and manage potential duplicate expense claims",
    "processing": "Processing...",
    "markAsReviewed": "Mark {count} as Reviewed",
    "selectAllPending": "Select All Pending ({count})",
    "summaryTotalMatches": "Total Matches",
    "summaryPending": "Pending",
    "summaryConfirmed": "Confirmed",
    "summaryDismissed": "Dismissed",
    "summaryExact": "Exact",
    "summaryStrong": "Strong",
    "summaryFuzzy": "Fuzzy",
    "summaryCrossUser": "Cross User",
    "filters": "Filters",
    "statusLabel": "Status",
    "selectStatusPlaceholder": "Select status",
    "statusAll": "All",
    "statusPendingReview": "Pending Review",
    "statusConfirmedDuplicates": "Confirmed Duplicates",
    "statusDismissed": "Dismissed",
    "startDate": "Start Date",
    "endDate": "End Date",
    "actionsLabel": "Actions",
    "refresh": "Refresh",
    "duplicateMatches": "Duplicate Matches",
    "loading": "Loading...",
    "potentialDuplicatesFound": "{count, plural, one {# potential duplicate found} other {# potential duplicates found}}",
    "tierExactMatch": "Exact Match",
    "tierStrongMatch": "Strong Match",
    "tierFuzzyMatch": "Fuzzy Match",
    "statusConfirmed": "Confirmed",
    "noDuplicateMatchesFound": "No duplicate matches found",
    "noDuplicatesMatchFilters": "No duplicates match the current filters",
    "columnDate": "Date",
    "columnOriginalClaim": "Original Claim",
    "columnMatchedClaim": "Matched Claim",
    "columnAmount": "Amount",
    "columnMatchTier": "Match Tier",
    "columnConfidence": "Confidence",
    "columnStatus": "Status",
    "columnActions": "Actions",
    "unknownVendor": "Unknown Vendor",
    "unknown": "Unknown",
    "review": "Review",
    "originalLabel": "Original",
    "matchedLabel": "Matched",
    "confidenceLabel": "Confidence: {percent}%",
    "errorGenericRetryManual": "Something went wrong. Please try again or fill the form manually.",
    "errorTemporarySystem": "A temporary system error occurred. Please retry, since this usually resolves on the next attempt.",
    "errorMerchantSiteUnreachable": "Could not reach the merchant's website. The site may be temporarily down.",
    "errorMerchantFormTimeout": "The merchant form took too long to process. Please retry or fill the form manually.",
    "errorAiServiceTemporary": "Our AI service had a temporary issue. Please retry.",
    "errorNoMerchantForm": "No e-invoice form found for this merchant. You can fill it manually if you know the URL.",
    "errorNoBusinessDetails": "Company details are missing. Please update your business settings and retry.",
    "errorMerchantRejectedDetails": "The merchant rejected the details we submitted. This is usually the business tax number (TIN) or registration number not matching their records. Check them in Business Settings, then request again.",
    "errorMerchantRequiredFields": "The merchant form has required fields we couldn't fill automatically. Please fill the form manually.",
    "errorReceiptNotEligible": "The merchant says this receipt is no longer eligible for e-invoice. The submission window may have expired.",
    "errorReceiptNotFound": "The merchant's system could not find this receipt. It may have been removed or the reference is incorrect.",
    "errorAlreadySubmitted": "An e-invoice has already been submitted for this receipt.",
    "errorSubmissionWindowExpired": "The e-invoice submission window has expired for this receipt.",
    "errorReceiptInvalid": "The merchant marked this receipt as invalid.",
    "errorReceiptNotReady24Hours": "This merchant makes e-invoices available 24 hours after purchase. Please retry tomorrow.",
    "errorCouldNotSubmitAuto": "We couldn't submit the form automatically. You can retry or fill the form manually.",
    "errorRequestEinvoice": "Failed to request e-invoice",
    "errorUploadEinvoice": "Failed to upload e-invoice",
    "errorLoadEinvoicePdf": "Failed to load e-invoice PDF",
    "timeExpired": "Expired",
    "timeMinutesRemaining": "{minutes}m remaining",
    "timeHoursRemaining": "{hours}h remaining",
    "timeDaysHoursRemaining": "{days}d {hours}h remaining",
    "einvoiceTitle": "E-Invoice",
    "betaBadge": "Beta",
    "betaTooltip": "Automated e-invoice requests work with many Malaysian merchants, but each merchant has a different system. Some may require manual submission. We appreciate your understanding as we improve coverage.",
    "missingFieldTin": "Tax ID (TIN)",
    "missingFieldBrn": "Business Registration (BRN)",
    "missingFieldAddress": "Address",
    "missingFieldPhone": "Phone",
    "missingFieldEmail": "Email",
    "businessDetailsIncomplete": "Business details incomplete",
    "businessDetailsMissing": "Missing: {fields}. These are needed for automated e-invoice requests.",
    "updateBusinessSettings": "Update Business Settings",
    "merchantRequiresOtp": "This merchant requires verification (OTP)",
    "merchantNoAutomatedSupport": "This merchant doesn't support automated requests",
    "fillFormManuallyUseEmail": "Fill the form manually: use the email below so we auto-attach the e-invoice when it arrives.",
    "manualStepOpenForm": "Open the merchant form below",
    "manualStepFillDetails": "Fill in your company details",
    "manualStepUseEmail": "Use the email above for the e-invoice delivery",
    "manualStepAutoAttach": "We'll auto-attach it when it arrives",
    "openForm": "Open Form",
    "einvoiceRequestFailed": "E-invoice request failed",
    "fillFormManuallyUseEmailColon": "You can fill the form manually: use this email so we auto-attach the e-invoice:",
    "sourceLabel": "Source",
    "sourceMerchantIssued": "Merchant Issued",
    "sourceManualUpload": "Manual Upload",
    "sourceNotApplicable": "Not Applicable",
    "requestedLabel": "Requested",
    "receivedLabel": "Received",
    "lhdnUuidLabel": "LHDN UUID",
    "einvoiceCancelledBySupplier": "This e-invoice has been cancelled by the supplier on LHDN",
    "einvoiceRejectedByOrg": "This e-invoice has been rejected by your organization",
    "lhdnVerificationLabel": "LHDN Verification",
    "verifyOnMyInvois": "Verify on MyInvois",
    "merchantFormLabel": "Merchant Form",
    "openFormManually": "Open form manually",
    "einvoiceAttached": "E-Invoice Attached",
    "viewPdf": "View PDF",
    "noPortalFound": "No e-invoice portal found for this merchant",
    "noPortalNoSelfBillDescription": "Self-billing is not an option here: LHDN allows it only for a short list of cases, and a merchant that gave no e-invoice is not one of them. Ask the merchant for an e-invoice, or keep the receipt as proof of the expense.",
    "retryRequest": "Retry Request",
    "requestEinvoice": "Request E-Invoice",
    "einvoiceRequestPaused": "Automated request paused",
    "einvoiceRequestPausedDescription": "Groot paused this automated request for safety. You can retry now or open the merchant form manually.",
    "replaceEinvoice": "Replace E-Invoice",
    "uploadEinvoice": "Upload E-Invoice",
    "rejectEinvoice": "Reject E-Invoice",
    "merchantReceiptIneligible": "Receipt not eligible for e-invoice",
    "merchantIneligibleDescription": "The merchant says this receipt cannot be issued an e-invoice. This is typically due to the transaction type or the submission window has closed.",
    "merchantManualRequestUploadHere": "This merchant requires a manual e-invoice request. Fill the form below and upload the e-invoice here once you receive it.",
    "reasonAccountPinTitle": "Create or sign in to your own merchant account",
    "reasonAccountPinDescription": "This merchant requires an individual user account and PIN to submit an e-invoice request. Create or sign in to your account, submit the request on the merchant's portal, then upload the e-invoice here.",
    "reasonOtpTitle": "This merchant needs a one-time verification code",
    "reasonManualOnlyTitle": "This merchant can't be completed automatically",
    "reasonBotBlockedTitle": "This merchant's system is blocking automated requests",
    "reasonWantAutomatedPrompt": "Want us to handle merchants like this for you?",
    "cropToQrTip": "Tip",
    "cropToQrDescription": "If your receipt has a QR code, attach a photo cropped closely to just the QR code. We read every document you attach and link the merchant portal automatically when we find one.",
    "qrScanNoneFound": "We read the documents you attached. None of them carried an e-invoice QR code.",
    "qrScanNotReadYet": "We have not read your attached documents for a QR code yet.",
    "qrScanFailedEarlier": "We could not read your attached documents last time. Please try again.",
    "qrScanAttachedDocuments": "Scan attached documents",
    "qrScanRunning": "Reading...",
    "qrScanError": "We could not read the attached documents just now. Please try again.",
    "errorEinvoiceLhdnValidated": "This claim is linked to an LHDN validated e-invoice, so you cannot swap its document for an uploaded file. Reject that e-invoice first if it is wrong.",
    "errorEinvoiceClaimLocked": "This claim is already approved, so its e-invoice is locked. Ask finance to reverse the approval before you replace it.",
    "errorEinvoiceClaimResubmitted": "This claim was resubmitted, so its e-invoice can't be changed here. Open the new claim instead.",
    "errorEinvoiceAlreadyAttached": "This claim already has an e-invoice attached.",
    "errorEinvoiceFileType": "That file type is not supported. Please upload a PDF, PNG, JPG, WebP, or HEIC.",
    "errorEinvoiceFileTooLarge": "That file is too large. Please upload a file under 10MB.",
    "errorEinvoiceNoFile": "Please choose a file to upload.",
    "errorEinvoiceNotAuthorized": "You do not have permission to change the e-invoice on this claim.",
    "errorEinvoiceClaimNotFound": "We could not find this expense claim.",
    "replaceBlockedLhdnValidated": "Validated by LHDN. Reject it first to attach a different document.",
    "replaceBlockedClaimApproved": "Locked because this claim is already approved.",
    "replaceBlockedClaimResubmitted": "Locked because this claim was resubmitted. Open the new claim to change documents.",
    "countedByLabel": "Counted by",
    "periodPresetThisMonth": "This month",
    "periodPresetLastMonth": "Last month",
    "periodPresetLast30Days": "Last 30 days",
    "periodPresetLast3Months": "Last 3 months",
    "periodPresetThisYear": "This year",
    "periodSpecificMonth": "A specific month",
    "periodCustomRange": "Custom range",
    "monthLabel": "Month",
    "basisApprovedLabel": "Approval date",
    "basisTransactionLabel": "Transaction date",
    "basisSubmittedLabel": "Submission date",
    "periodCoversApproved": "{range} by approval date, for what you owe",
    "periodCoversTransaction": "{range} by transaction date, when it was spent",
    "periodCoversSubmitted": "{range} by submission date, what staff filed",
    "errorSelectPeriod": "Please select a period",
    "rangePrevMonth": "Move the range one month earlier",
    "rangeNextMonth": "Move the range one month later",
    "rangePrevMonthShort": "Prev month",
    "rangeNextMonthShort": "Next month",
    "rangeInvertedHint": "The start date is after the end date. Swap them, or use Prev/Next month to move the whole range.",
    "errorMerchantBlocksAutomation": "This merchant's website turned our automated request away. Open their form and submit it yourself. We'll attach the e-invoice here once it arrives.",
    "errorMerchantNoResponse": "The merchant accepted the request but hasn't sent the e-invoice yet. Chase them, or upload it here once you have it.",
    "errorBuyerProfileIncomplete": "Your business details are incomplete, so the merchant form can't be filled. Update your business settings, then retry.",
    "errorSubmissionMayHaveLanded": "The request may already have gone through. Check your inbox before requesting again, or upload the e-invoice here.",
    "errorMerchantNeedsManualRequest": "This merchant needs the e-invoice requested by hand. Open their form, submit it yourself, and we'll attach the e-invoice here once it arrives.",
    "matchReview": {
      "errors": {
        "resolveFailed": "We couldn't record your decision on this match. Please try again."
      }
    },
    "errorEinvoiceBusinessTinMissing": "Your business tax identification number (TIN) isn't set, so no e-invoice can be requested. Add it under Settings → Business → e-Invoice, then try again.",
    "errorEinvoiceBusinessAddressMissing": "Your business address isn't set, so no e-invoice can be requested. Add it under Settings → Business Profile, then try again.",
    "errorEinvoiceBrowserPaused": "E-invoice automation is paused for this account. Groot has stopped automated requests for now. Please try again later or contact support.",
    "errorEinvoiceAttemptLimitReached": "We have tried this e-invoice request the maximum number of times. Please request the e-invoice on the merchant's website and upload it here.",
    "errorEinvoiceRequestInFlight": "An e-invoice request for this claim is already in progress. Please wait a moment and check back. You do not need to submit it again.",
    "attemptsUsed": "Attempt {used} of {total}.",
    "attemptsAutoRetryStopped": "Groot has stopped retrying automatically; you can still retry yourself.",
    "attemptsExhausted": "All {total} attempts used. Request the e-invoice on the merchant's website and upload it here.",
    "submissionReportFilterLabel": "Submission Report",
    "submissionAllReports": "All reports",
    "submissionStandaloneLabel": "Not part of a report"
  },
  "x_expense_2": {
    "downloadDocument": "Download document",
    "loading": "Loading...",
    "failedToLoadPermissions": "Failed to load user permissions.",
    "managersFinanceOnly": "Category management is available for managers and finance users only.",
    "expenseCategories": "Expense Categories",
    "cogsCategories": "COGS Categories",
    "manageCategoriesDescription": "Manage expense categories for your organization",
    "addCategory": "Add Category",
    "searchCategoriesPlaceholder": "Search categories...",
    "loadingCategories": "Loading categories...",
    "noCategoriesMatchSearch": "No categories match your search",
    "noCategoriesFound": "No categories found",
    "inactive": "Inactive",
    "default": "Default",
    "standard": "Standard",
    "receiptRequired": "Receipt required",
    "receiptRequiredAbove": "Receipt required (>${amount})",
    "receiptNotRequired": "Receipt not required",
    "managerApprovalRequired": "Manager approval required",
    "managerApprovalNotRequired": "Manager approval not required",
    "policyLimitValue": "Policy limit: ${amount}",
    "keywordsLabel": "Keywords: {keywords}",
    "edit": "Edit",
    "deleteCategoryTitle": "Delete Category",
    "deleteCategoryConfirm": "Are you sure you want to delete the category \"{name}\"? This action cannot be undone and may affect existing expense claims.",
    "delete": "Delete",
    "cancel": "Cancel",
    "failedToFetchCategories": "Failed to fetch categories",
    "failedToSaveCategory": "Failed to save category",
    "categoryUpdatedSuccess": "Category updated successfully",
    "categoryCreatedSuccess": "Category created successfully",
    "networkErrorSaving": "Network error while saving category",
    "failedToDeleteCategory": "Failed to delete category",
    "categoryDeletedSuccess": "Category deleted successfully",
    "networkErrorDeleting": "Network error while deleting category",
    "whatYouCanDo": "What you can do:",
    "tryAgain": "Try Again",
    "waitMinutes": "(wait {minutes}m)",
    "dismiss": "Dismiss",
    "retry": "Retry",
    "processingEllipsis": "Processing...",
    "processingComplete": "Processing complete",
    "stepVendorAnalysisTitle": "Vendor Analysis",
    "stepVendorAnalysisDescription": "Identifying merchant and business information",
    "stepDateIdentificationTitle": "Date Identification",
    "stepDateIdentificationDescription": "Locating transaction date and time",
    "stepAmountParsingTitle": "Amount Parsing",
    "stepAmountParsingDescription": "Extracting monetary values and currency",
    "stepTaxCalculationTitle": "Tax Calculation",
    "stepTaxCalculationDescription": "Analyzing tax rates and amounts",
    "stepLineItemsExtractionTitle": "Line Items Extraction",
    "stepLineItemsExtractionDescription": "Parsing individual purchase items",
    "stepValidationChecksTitle": "Validation Checks",
    "stepValidationChecksDescription": "Verifying accuracy and consistency",
    "receiptExtractionFailed": "Receipt extraction failed",
    "dataExtractionFailed": "Data extraction failed",
    "failedToCheckClaimStatus": "Failed to check expense claim status",
    "claimStatusCheckFailed": "Expense claim status check failed",
    "processingStuck": "Processing appears to be stuck. Please try again or contact support if the issue persists.",
    "documentTypeNotSupported": "This document type is not supported for expense claims. Please upload a receipt or invoice.",
    "receiptProcessingFailedTimeout": "Receipt processing failed due to timeout or processing error",
    "unableToCheckStatus": "Unable to check processing status. Please try again.",
    "processingTakingLonger": "Processing is taking longer than expected. Please try again.",
    "processingFailed": "Processing failed",
    "processingCompleted": "Processing completed",
    "unknown": "Unknown",
    "notFound": "Not found",
    "reasoningVendor": "Identified vendor: {vendor}",
    "reasoningDate": "Found date: {date}",
    "reasoningAmount": "Extracted amount: {amount} {currency}",
    "reasoningTax": "Tax analysis: No tax information found",
    "reasoningLineItems": "Line items: 0 items extracted",
    "reasoningValidation": "Validation complete. Confidence: {confidence}%",
    "reasoningOverallConfidence": "Overall processing confidence: {confidence}%",
    "aiAnalyzing": "AI Analyzing",
    "aiExtraction": "AI Extraction",
    "processingProgress": "Processing Progress",
    "secondsRemaining": "{seconds}s remaining",
    "retryProcessing": "Retry Processing",
    "enterManually": "Enter Manually",
    "processingBadge": "Processing...",
    "completeBadge": "Complete",
    "aiExtractionComplete": "AI Extraction Complete",
    "confidenceScoreLabel": "Confidence Score:",
    "qualityLabel": "Quality:",
    "qualityValue": "{quality, select, high {High} medium {Medium} low {Low} other {{quality}}}",
    "reviewExtractedDataWarning": "Please review the extracted data carefully before submitting.",
    "continueToPrefilledForm": "Continue to Pre-filled Form",
    "skipProcessingEnterManually": "Skip Processing & Enter Manually",
    "editCategory": "Edit Category",
    "addNewCategory": "Add New Category",
    "configureCategoryDescription": "Configure expense category settings and auto-categorization rules",
    "validationCategoryNameRequired": "Category name is required",
    "validationReceiptThreshold": "Receipt threshold must be 0 or greater",
    "validationPolicyLimit": "Policy limit must be 0 or greater",
    "basicInformation": "Basic Information",
    "categoryNameLabel": "Category Name *",
    "categoryNamePlaceholder": "e.g., Travel & Accommodation",
    "descriptionLabel": "Description",
    "descriptionPlaceholder": "Brief description of this category",
    "glAccountCodeLabel": "GL Account Code",
    "glAccountCodePlaceholder": "e.g., 9120, 6010",
    "glAccountCodeHint": "Chart of Account code for accounting software export",
    "autoCategorizationRules": "Auto-Categorization Rules",
    "keywordsFieldLabel": "Keywords (comma-separated)",
    "keywordsFieldPlaceholder": "travel, hotel, flight, accommodation",
    "keywordsFieldHint": "Keywords found in receipt descriptions will auto-categorize to this category",
    "vendorPatternsLabel": "Vendor Patterns (comma-separated)",
    "vendorPatternsPlaceholder": "*airline*, *hotel*, booking.com",
    "vendorPatternsHint": "Use * as wildcards. Vendor names matching these patterns will auto-categorize",
    "policySettings": "Policy Settings",
    "taxTreatmentLabel": "Tax Treatment",
    "fullyDeductible": "Fully Deductible",
    "partiallyDeductible": "Partially Deductible",
    "nonDeductible": "Non-Deductible",
    "requiresReceiptAttachment": "Requires receipt attachment",
    "requiresManagerApproval": "Requires manager approval",
    "categoryStatus": "Category Status",
    "enabled": "Enabled",
    "disabled": "Disabled",
    "categoryAvailableHint": "Category is available for expense submissions",
    "categoryHiddenHint": "Category is hidden from expense forms",
    "receiptRequiredAboveAmountLabel": "Receipt Required Above Amount",
    "policyLimitLabel": "Policy Limit (SGD)",
    "policyLimitPlaceholder": "0.00 (0 = no limit)",
    "monthlyBudgetLimitLabel": "Monthly Budget Limit",
    "monthlyBudgetLimitPlaceholder": "0.00 (0 = no budget tracking)",
    "monthlyBudgetLimitHint": "Optional monthly spending limit for this category. Set to 0 or leave empty to disable budget tracking. Managers will be alerted when spending reaches 80% of this limit.",
    "saving": "Saving...",
    "updateCategory": "Update Category",
    "createCategory": "Create Category",
    "statusDraft": "Draft",
    "statusUploading": "Uploading",
    "statusClassifying": "Classifying",
    "statusAnalyzing": "Analyzing",
    "statusProcessing": "Processing",
    "statusSubmitted": "Submitted",
    "statusApproved": "Approved",
    "statusRejected": "Rejected",
    "statusReimbursed": "Reimbursed",
    "statusFailed": "Failed",
    "statusClassificationFailed": "Classification Failed",
    "claimDetailsTitle": "Claim Details",
    "expenseClaimDetails": "Expense claim details",
    "percentConfidence": "{percent}% confidence",
    "loadingPreview": "Loading preview...",
    "receiptAlt": "Receipt",
    "viewReceipt": "View receipt",
    "viewExpenseClaim": "View Expense Claim",
    "close": "Close",
    "previewUnavailable": "Preview unavailable",
    "noReceiptAttached": "No receipt attached",
    "vendorLabel": "Vendor",
    "amountLabel": "Amount",
    "dateLabel": "Date",
    "categoryLabel": "Category",
    "purposeLabel": "Purpose",
    "classificationFailedMessage": "Document could not be classified as a receipt. Please upload a valid receipt.",
    "processingFailedMessage": "Processing failed. Please try uploading again or enter details manually.",
    "downloadReceipt": "Download receipt",
    "downloadEinvoice": "Download e-invoice",
    "downloadErrorNoDocument": "This claim has no stored document to download.",
    "downloadErrorNotAllowed": "You do not have access to this document.",
    "downloadErrorSignedOut": "Please sign in again to download this document.",
    "downloadErrorGeneric": "We could not start the download. Please try again."
  },
  "x_expense_3": {
    "document": "Document",
    "aiConfidenceLabel": "AI confidence",
    "aiConfidencePercent": "{percent}%",
    "aiConfidenceReviewHint": "AI can be wrong. Check the details.",
    "aiConfidenceAria": "AI extraction confidence {percent} percent. AI can be wrong, so check the details before you submit.",
    "modalTitle": "Expense Submission",
    "modalSubtitleManual": "Manually fill out expense details and attach a receipt",
    "modalSubtitleAi": "Intelligent receipt processing with Chain-of-Thought AI",
    "badgeDraft": "Draft",
    "badgeProcessing": "{count} processing...",
    "badgeQuality": "{quality} quality",
    "stepUploadLabel": "Upload",
    "stepUploadDescription": "Receipt capture",
    "stepProcessLabel": "Process",
    "stepProcessDescription": "Data extraction",
    "stepReviewLabel": "Review",
    "stepReviewDescription": "Pre-filled form",
    "createPageTitle": "Create Expense Claim",
    "createPageDescription": "Review and submit your extracted expense details",
    "changeFile": "Change File",
    "poweredByAi": "Powered by AI Receipt Analysis",
    "errorInvalidFileType": "Please select a valid image (JPEG, PNG, WebP) or PDF file",
    "errorFileTooLarge": "File size must be less than 10MB",
    "errorProcessingFailed": "Processing failed",
    "errorSubmitFailed": "Failed to submit expense claim. Please try again.",
    "detailsTitle": "Expense Claim Details",
    "managerView": "Manager View",
    "loadingClaimDetails": "Loading claim details...",
    "tryAgain": "Try Again",
    "statusUnknownLabel": "Unknown",
    "statusUnknownDescription": "Status not available",
    "statusDraftLabel": "Draft",
    "statusDraftDescription": "Ready for editing - click Edit to modify or Submit to proceed",
    "statusUploadingLabel": "Uploading...",
    "statusUploadingDescription": "Receipt file is being uploaded",
    "statusAnalyzingLabel": "Analyzing 🧠",
    "statusAnalyzingDescription": "AI is analyzing the receipt",
    "statusSubmittedLabel": "Submitted",
    "statusSubmittedDescription": "Submitted for manager approval",
    "statusApprovedLabel": "Approved",
    "statusApprovedDescription": "Approved - awaiting reimbursement",
    "statusRejectedLabel": "Rejected",
    "statusRejectedDescription": "Claim was rejected",
    "statusReimbursedLabel": "Reimbursed",
    "statusReimbursedDescription": "Payment processed",
    "statusFailedLabel": "Failed",
    "statusFailedDescription": "Processing failed - please try manual entry",
    "statusInvalidDocumentLabel": "Invalid Document",
    "statusInvalidDocumentDescription": "This document does not appear to be a receipt or invoice. Please delete and upload a valid receipt.",
    "statusUnknownStatusDescription": "Unknown status",
    "statusUnknownUpper": "UNKNOWN",
    "errorApproveFailed": "Failed to approve claim. Please try again.",
    "errorRejectFailed": "Failed to reject claim. Please try again.",
    "einvoiceRejected": "E-Invoice Rejected",
    "notAvailable": "N/A",
    "attached": "Attached",
    "noReceipt": "No receipt",
    "currentlyWith": "Currently with:",
    "invalidDocumentDetected": "Invalid Document Detected",
    "invalidDocumentDetectedDescription": "This document does not appear to be a receipt or invoice. Please delete this entry and upload a valid receipt (photo of a purchase receipt, restaurant bill, or tax invoice).",
    "loadingPreview": "Loading preview...",
    "receipt": "Receipt",
    "failedToGenerateUrl": "Failed to generate secure URL",
    "contactSupportIfPersists": "Please contact support if this persists",
    "noReceiptAttached": "No receipt attached",
    "image": "Image",
    "processed": "Processed",
    "view": "View",
    "reprocess": "Reprocess",
    "moreOptions": "More options",
    "confirmedDuplicate": "Confirmed Duplicate",
    "potentialDuplicateDetected": "Potential Duplicate Detected",
    "duplicateDismissed": "Duplicate Dismissed",
    "markedAsSplitExpense": "Marked as split expense by employee",
    "mayBeDuplicate": "This claim may be a duplicate of another expense",
    "reviewDuplicates": "Review Duplicates",
    "employeesJustification": "Employee's Justification",
    "acknowledgedOn": "Acknowledged on {date}",
    "managerActions": "Manager Actions",
    "employee": "Employee",
    "approvalNotesOptional": "Approval Notes (Optional)",
    "approvalNotesPlaceholder": "Add notes about this approval decision...",
    "reject": "Reject",
    "approve": "Approve",
    "claimRejected": "Claim Rejected",
    "claimRejectedDescription": "This expense claim was rejected. You can correct any issues and resubmit for approval.",
    "basicInformation": "Basic Information",
    "category": "Category",
    "referenceNumber": "Reference Number",
    "referenceNotProvided": "Not provided - verify receipt authenticity",
    "description": "Description",
    "businessPurpose": "Business Purpose",
    "additionalNotes": "Additional Notes",
    "lineItemsWithCount": "Line Items ({count})",
    "colDescription": "Description",
    "colQty": "Qty",
    "colUnitPrice": "Unit Price",
    "colTotal": "Total",
    "item": "Item",
    "qtyPrefix": "Qty:",
    "totalAmount": "Total Amount",
    "noItemizedBreakdown": "No itemized breakdown available",
    "singleAmountEntry": "This expense was entered as a single amount",
    "documentProcessingStatus": "Document Processing Status",
    "processingProgress": "Processing Progress",
    "approvalHistory": "Approval History",
    "submittedForApproval": "Submitted for approval",
    "approvedBy": "Approved by {name}",
    "manager": "Manager",
    "copyReceiptId": "Copy Receipt ID",
    "noClaimDetails": "No claim details available",
    "receiptPreview": "Receipt Preview",
    "lineItemsLoading": "Line Items (...)",
    "extractingLineItems": "Extracting line items...",
    "addItem": "Add Item",
    "colCurrency": "Currency",
    "colActions": "Actions",
    "itemDescriptionPlaceholder": "Item description",
    "removeItem": "Remove item",
    "serviceCharge": "Service Charge",
    "tax": "Tax",
    "subtotal": "Sub-total",
    "noLineItemsYet": "No line items added yet",
    "addFirstItem": "Add First Item",
    "processing": "Processing...",
    "aiExtract": "AI Extract",
    "extractDataUsingAi": "Extract data using AI",
    "viewReceipt": "View receipt",
    "close": "Close",
    "done": "Done",
    "editItem": "Edit item",
    "tapToEdit": "Tap to edit",
    "uploadReceiptRequired": "Upload Receipt (Required)",
    "dragAndDrop": "Drag and drop or click to select",
    "chooseFile": "Choose File",
    "expenseSummary": "Expense Summary",
    "vendor": "Vendor",
    "notSpecified": "Not specified",
    "amount": "Amount",
    "date": "Date",
    "conversionPreview": "Conversion Preview",
    "manualTag": "(Manual)",
    "rateLabelOpen": "(Rate:",
    "rateDisplay": "(Rate: {rate})",
    "editExchangeRate": "Edit exchange rate",
    "revertToAutoRate": "Revert to auto rate",
    "ratePairDisplay": "1 {from} = {rate} {to}",
    "preferredRateTag": "(Preferred)",
    "rateUnavailableNoRate": "No exchange rate is available for this currency yet. Use Edit exchange rate to enter the rate you were quoted.",
    "rateUnavailableProvider": "We could not reach the exchange rate service. Use Edit exchange rate to enter the rate you were quoted.",
    "rateUnavailableRateLimited": "The exchange rate service is busy right now. Use Edit exchange rate to enter the rate you were quoted, or try again shortly.",
    "loadingExpenseDetails": "Loading Expense Details",
    "loadingExpenseInfo": "Please wait while we load the expense information...",
    "expenseDetails": "Expense Details",
    "vendorNameLabel": "Vendor Name *",
    "vendorNamePlaceholder": "Vendor or merchant name",
    "transactionDateLabel": "Transaction Date *",
    "categoryLabel": "Category *",
    "selectCategory": "Select category",
    "loadingCategories": "Loading categories...",
    "errorLoadingCategories": "Error loading categories",
    "noCategoriesAvailable": "No categories available",
    "referenceNumberPlaceholder": "Receipt or reference number",
    "recommendedForApproval": "Recommended for faster approval",
    "amountLabel": "Amount *",
    "currency": "Currency",
    "homeCurrency": "Home Currency",
    "descriptionLabel": "Description *",
    "descriptionPlaceholder": "Brief description of expense",
    "businessPurposeLabel": "Business Purpose *",
    "businessPurposePlaceholder": "Explain the business reason for this expense",
    "additionalNotesPlaceholder": "Any additional information",
    "movedToApInvoices": "Moved to AP Invoices",
    "movedToApInvoicesDescription": "Document reclassified and moved to Invoices",
    "reclassifyFailed": "Reclassify failed",
    "reclassifyFailedFallback": "Failed to reclassify",
    "successSubmitted": "Expense claim submitted for approval!",
    "successSavedDraft": "Expense claim saved as draft successfully!",
    "editTitle": "Edit Expense Claim",
    "editSubtitle": "Modify your expense claim details",
    "delete": "Delete",
    "saving": "Saving...",
    "saveDraft": "Save Draft",
    "checking": "Checking...",
    "submitting": "Submitting...",
    "submit": "Submit",
    "loadingExpenseDetailsShort": "Loading expense details...",
    "potentialDuplicateTitle": "⚠️ Potential Duplicate Detected!",
    "duplicateMatchSummary": "This expense matches {count, plural, one {# existing claim} other {# existing claims}} ({tier}). ",
    "tierExact": "Exact match",
    "tierStrong": "Same vendor/date/amount",
    "tierSimilar": "Similar expense",
    "viewMatches": "View matches →",
    "duplicateCheckUnavailable": "We could not check this receipt for duplicates just now. Open the claim and check before you submit.",
    "autoClassifiedPrefix": "Auto-classified as",
    "autoClassifiedSuffix": "from email forwarding",
    "moveToApInvoices": "Move to AP Invoices",
    "deleteDialogTitle": "Delete Expense Claim",
    "deleteDialogMessage": "Are you sure you want to delete this draft expense claim? This action cannot be undone.",
    "cancel": "Cancel",
    "billRounding": "Bill Rounding",
    "governmentFuelSubsidy": "Government fuel subsidy",
    "removeCharge": "Remove adjustment",
    "chargeLabelPlaceholder": "Adjustment label",
    "reclassifyErrors": {
      "claimNotFound": "We couldn't find this document. It may have been moved or deleted. Close this window and refresh the list.",
      "generic": "We couldn't move this to purchase invoices. The document was left where it is. Please try again."
    },
    "errorLoadClaimFailed": "We couldn't load this claim's details. Refresh the page and try again.",
    "errorDeleteFailed": "We couldn't delete this claim. Nothing was changed. Please try again.",
    "errorReprocessFailed": "We couldn't re-run the AI extraction on this receipt. Please try again.",
    "errorNoReceiptToReprocess": "There's no receipt on this claim to re-process. Upload one first.",
    "errorSaveFailedGeneric": "We couldn't save this claim. Nothing was changed. Please try again.",
    "errorClaimNotFound": "This claim is no longer available. It may have been deleted. Close this window and refresh.",
    "errorClaimFinalStatus": "This claim has already been approved or reimbursed, so it can no longer be edited.",
    "errorClaimInvalidStatus": "This claim's status has changed. Refresh to see where it stands now.",
    "errorNoReceiptExemptionDisabled": "Your business has not turned on no-receipt claims. Attach a receipt, or ask an owner or finance admin to turn it on in approval settings.",
    "errorNoReceiptExemptionOverThreshold": "This claim is over your business's no-receipt limit. Attach a receipt, or reduce the claimed amount.",
    "errorNoReceiptExemptionAmountUnknown": "This claim has no amount in your business currency yet, so it cannot be checked against the no-receipt limit. Enter the amount and its conversion, or attach a receipt.",
    "fieldSuggestion": {
      "aiSuggestionFor": "AI Suggestion for {field}",
      "highConfidence": "High Confidence",
      "mediumConfidence": "Medium Confidence",
      "lowConfidence": "Low Confidence",
      "confidencePercent": "{percent}%",
      "current": "Current:",
      "empty": "Empty",
      "aiSuggests": "AI Suggests:",
      "accept": "Accept",
      "applying": "Applying...",
      "keepCurrent": "Keep Current",
      "aiAnalyzing": "AI Analyzing...",
      "aiProcessingFailed": "AI Processing Failed",
      "aiProcessingComplete": "AI Processing Complete",
      "analyzingDocument": "Analyzing document and extracting data...",
      "extractionFailed": "AI extraction failed. You can continue editing with existing data or try re-extracting again.",
      "foundImprovements": "Found {count} suggested improvements",
      "avgConfidence": "Avg confidence: {percent}%",
      "acceptAll": "Accept All ({count})",
      "applyingAll": "Applying All...",
      "keepAllCurrent": "Keep All Current",
      "tryAiExtractAgain": "Try AI Extract Again",
      "continueWithCurrentData": "Continue with Current Data"
    },
    "pagesNotRead": "Only {read} of {total} pages were read. Amounts printed on the pages we skipped are not included, so check the total yourself.",
    "aiConfidenceUnreliable": "Not reliable",
    "aiConfidenceNoAmountHint": "No amount was read from this document, so this score says nothing about the figures. Check every page and enter the total yourself.",
    "fxSectionTitle": "Currency conversion",
    "fxRateLabel": "Exchange rate used",
    "fxConvertedLabel": "Converted amount",
    "fxCapturedLabel": "Rate captured",
    "fxCapturedUnknown": "Capture time not recorded for this claim",
    "successSubmittedNoApproval": "Expense claim filed and posted!",
    "filedAndPosted": "Filed and posted",
    "claimHistory": "Claim History",
    "filedBy": "Filed by {name}",
    "noReceiptToggleLabel": "This expense has no receipt",
    "noReceiptToggleHint": "For expenses like parking or tolls where no receipt is issued. Allowed up to {amount}.",
    "noReceiptReasonLabel": "Why is there no receipt?",
    "noReceiptReasonPlaceholder": "e.g. Parking fee, no receipt issued",
    "approvedAutomatically": "Approved automatically ({rules})",
    "approvedAutomaticallyNoRule": "Approved automatically",
    "autoApprovalRule": "{category} up to {amount}",
    "workflowProgressLabel": "Claim progress",
    "saveChanges": "Save changes",
    "successSavedChanges": "Changes saved.",
    "descriptionSuggestedHint": "Suggested from the receipt. Check it says what the expense was, and change it if not."
  },
  "x_expense_4": {
    "aiAnalyzing": "AI Analyzing... This may take a few moments.",
    "potentialDuplicateDetected": "Potential duplicate detected!",
    "receiptSimilarToExisting": "This receipt appears {percent}% similar to an existing claim.",
    "viewExistingClaim": "View existing claim",
    "receiptProcessedWithConfidence": "Receipt processed with {percent}% confidence. Please verify the details below.",
    "receiptProcessedSuccessfully": "Receipt processed successfully! Please review the extracted details.",
    "receiptPreviewAlt": "Receipt preview",
    "confidence": "Confidence: {percent}%",
    "policyComplianceRequired": "Policy Compliance Required",
    "amountExceedsCategoryLimit": "• Amount exceeds category limit of ${limit}",
    "receiptRequiredOverAmount": "• Receipt required for amounts over ${threshold}",
    "expenseWillRequireApproval": "This expense will require manager approval.",
    "tabBasicDetails": "Basic Details",
    "tabLineItems": "Line Items ({count})",
    "tabTaxPolicy": "Tax & Policy",
    "tabAdditionalInfo": "Additional Info",
    "expenseCategoryLabel": "Expense Category *",
    "loadingCategories": "Loading categories...",
    "selectCategory": "Select category",
    "noCategoriesAvailable": "No categories available",
    "totalAmountLabel": "Total Amount *",
    "autoCalculatedFromLineItems": "(Auto-calculated from line items)",
    "syncWithLineItems": "Sync with line items (${total})",
    "vendorNameLabel": "Vendor Name *",
    "vendorNamePlaceholder": "Restaurant, store, or service provider name",
    "descriptionLabel": "Description *",
    "descriptionPlaceholder": "Brief description of the expense",
    "businessPurposeLabel": "Business Purpose *",
    "businessPurposePlaceholder": "Explain the business reason for this expense",
    "transactionDateLabel": "Transaction Date *",
    "currencyLabel": "Currency",
    "selectCurrency": "Select currency",
    "receiptNumberLabel": "Receipt Number",
    "receiptNumberPlaceholder": "Receipt #",
    "itemizedDetails": "Itemized Details",
    "breakDownExpense": "Break down your expense into individual items",
    "addItem": "Add Item",
    "noLineItemsAdded": "No line items added",
    "addItemizedDetailsHint": "Add itemized details for better expense tracking",
    "itemDescriptionLabel": "Item Description *",
    "itemNamePlaceholder": "Item name",
    "qtyLabel": "Qty *",
    "unitPriceLabel": "Unit Price *",
    "taxPercentLabel": "Tax %",
    "totalLabel": "Total",
    "lineItemsTotal": "Line Items Total:",
    "taxInformation": "Tax Information",
    "taxAmountLabel": "Tax Amount",
    "taxRateLabel": "Tax Rate (%)",
    "policyCompliance": "Policy Compliance",
    "categoryPolicyTitle": "{category} Policy",
    "policyLimitLabel": "Policy Limit:",
    "noLimit": "No limit",
    "receiptRequiredOverLabel": "Receipt Required Over:",
    "amountExceedsPolicyLimit": "Amount exceeds policy limit. Manager approval required.",
    "receiptRequiredUpload": "Receipt required for this amount. Please upload receipt.",
    "requiresManagerApproval": "Requires manager approval",
    "referenceNumberLabel": "Reference Number",
    "referenceNumberPlaceholder": "PO number, invoice number, etc.",
    "recommendedForFasterApproval": "Recommended for faster approval",
    "clientEntertainmentLabel": "Client Entertainment",
    "expenseIncludedClientEntertainment": "This expense included client entertainment",
    "attendeesLabel": "Attendees *",
    "attendeeNamePlaceholder": "Name of attendee",
    "additionalNotesLabel": "Additional Notes",
    "additionalNotesPlaceholder": "Any additional information or special circumstances",
    "back": "Back",
    "reviewAndSubmit": "Review & Submit",
    "exportManagersOnly": "Export functionality is available for managers and finance users only.",
    "exportFailed": "Export failed",
    "networkErrorDuringExport": "Network error occurred during export",
    "dataCopiedToClipboard": "Data copied to clipboard! You can now paste it directly into Google Sheets.",
    "exportExpenseReport": "Export Expense Report",
    "exportDescriptionCompany": "Generate comprehensive expense reports for company-wide analysis",
    "exportDescriptionTeam": "Generate comprehensive expense reports for team analysis",
    "exportFormat": "Export Format",
    "downloadCsv": "Download CSV",
    "googleSheetsFormat": "Google Sheets Format",
    "dateRange": "Date Range",
    "startDate": "Start Date",
    "endDate": "End Date",
    "statusFilter": "Status Filter",
    "status_pending": "Pending",
    "status_approved": "Approved",
    "status_rejected": "Rejected",
    "status_reimbursed": "Reimbursed",
    "noFilterSelected": "No filter selected - all statuses will be included",
    "additionalOptions": "Additional Options",
    "includeLineItems": "Include detailed line items",
    "generatingExport": "Generating Export...",
    "generateExport": "Generate Export",
    "exportGeneratedSuccessfully": "Export Generated Successfully",
    "totalRecords": "Total Records",
    "formatLabel": "Format",
    "generatedLabel": "Generated",
    "previewData": "Preview Data",
    "copyForGoogleSheets": "Copy for Google Sheets",
    "moreRows": "... and {count} more rows",
    "summaryTotal": "Total: {count}",
    "summaryAmount": "Amount: ${amount}",
    "summaryPending": "Pending: {count}",
    "summaryApproved": "Approved: {count}",
    "roleLabelEmployee": "Potential Duplicate Detected",
    "roleLabelManager": "Duplicate Review",
    "roleLabelFinance": "Duplicate Audit Trail",
    "potentialDuplicatesFound": "{count, plural, one {# potential duplicate found} other {# potential duplicates found}}",
    "currentExpense": "Current Expense",
    "unknownVendor": "Unknown Vendor",
    "refLabel": "Ref",
    "matchingExpenses": "Matching Expenses ({count})",
    "exactMatch": "Exact Match",
    "strongMatch": "Strong Match",
    "viewDetails": "View Details",
    "unknown": "Unknown",
    "transactionLabel": "Transaction",
    "submittedLabel": "Submitted",
    "matchedOnSame": "Same {fields}",
    "matchFieldReferenceNumber": "receipt number",
    "matchFieldTotalAmount": "amount",
    "matchFieldTransactionDate": "date",
    "matchFieldVendorName": "merchant",
    "matchFieldCurrency": "currency",
    "matchFieldLineItems": "line items",
    "theirJustification": "Their Justification:",
    "footerEmployee": "Please review these potential duplicates. If this is a legitimate expense, provide a justification when submitting.",
    "footerManager": "Review the duplicate matches above. Employee justifications are shown if provided. Approve only if you're confident these are separate transactions.",
    "footerFinance": "Audit trail for reference. This claim was approved by a manager despite duplicate warnings.",
    "close": "Close",
    "selfBilledEInvoice": "Self-Billed E-Invoice",
    "cancellationWindowRemaining": "Cancellation window: {hours}h {minutes}m remaining",
    "reasonForCancellationPlaceholder": "Reason for cancellation...",
    "confirmCancel": "Confirm Cancel",
    "cancelEInvoice": "Cancel E-Invoice",
    "cancellationWindowExpired": "72-hour cancellation window has expired.",
    "selfBillSubmissionFailed": "Self-bill submission failed",
    "selfBilledEInvoiceSubmitted": "Self-billed e-invoice submitted to LHDN",
    "failedToSubmitSelfBilled": "Failed to submit self-billed e-invoice",
    "cancellationFailed": "Cancellation failed",
    "selfBilledEInvoiceCancelled": "Self-billed e-invoice cancelled",
    "failedToCancelEInvoice": "Failed to cancel e-invoice",
    "noQrCodeDetected": "No e-invoice QR code detected on this receipt. A self-billed e-invoice may be required.",
    "selfBillingMayBeRequired": "Self-billing may be required for this expense claim.",
    "previousSubmissionRejected": "Previous submission was rejected. You can resubmit.",
    "resubmitSelfBilled": "Resubmit Self-Billed E-Invoice",
    "generateSelfBilled": "Generate Self-Billed E-Invoice",
    "tierExactLabel": "Exact Duplicate",
    "tierExactShortLabel": "Duplicate",
    "tierExactDescription": "Same receipt/reference number detected",
    "tierStrongLabel": "Likely Duplicate",
    "tierStrongShortLabel": "Likely Dup.",
    "tierStrongDescription": "Same vendor, date, and amount",
    "tierFuzzyLabel": "Possible Duplicate",
    "tierFuzzyShortLabel": "Possible Dup.",
    "tierFuzzyDescription": "Similar transaction detected",
    "crossUserDuplicate": "Cross-user duplicate (different submitter)",
    "clickToReview": "Click to review",
    "verifyAmountsLabel": "Please verify amounts",
    "verifyAmountsDescription": "The extracted amounts don't add up. The line items and charges don't match the total. Double-check the total before approving."
  },
  "x_expense_5": {
    "tierExactMatch": "Exact Match",
    "tierStrongMatch": "Strong Match",
    "tierPossibleMatch": "Possible Match",
    "tierMatch": "Match",
    "modalTitle": "Potential Duplicate Detected",
    "modalSubtitleSingle": "This expense may already exist",
    "modalSubtitleMultiple": "{count} potential duplicates found",
    "closeAria": "Close",
    "crossUserAlertLabel": "Potential Shared Expense:",
    "crossUserAlertBody": "One or more matches are from other team members. If this is a split expense where multiple people are claiming their portion, please indicate this below.",
    "currentExpenseLabel": "Current Expense (Being Edited)",
    "currentBadge": "★ Current",
    "fieldReference": "Reference:",
    "fieldVendor": "Vendor:",
    "fieldDate": "Date:",
    "fieldAmount": "Amount:",
    "fieldStatus": "Status:",
    "fieldSubmittedBy": "Submitted by:",
    "matchingExpensesLabel": "Matching Expenses (Potential Duplicates)",
    "otherUserBadge": "Other User",
    "confidenceLabel": "{percent}% confidence",
    "viewLink": "View",
    "copyIdTitle": "Copy expense ID",
    "splitExpenseLabel": "This is a split expense. I am claiming my portion.",
    "splitExpenseDescription": "Check this if multiple team members are each claiming their share of a shared expense.",
    "acknowledgeLabel": "I acknowledge this may overlap with another team member's claim",
    "acknowledgeDescription": "You must acknowledge this before proceeding with submission.",
    "justificationLabel": "Justification Reason",
    "justificationPlaceholder": "Please explain why this is not a duplicate or provide additional context...",
    "justificationHelp": "This explanation will be recorded for audit purposes.",
    "cancel": "Cancel",
    "proceedAnyway": "Proceed Anyway",
    "pdfGenerateError": "Failed to generate PDF. Please try again.",
    "print": "Print",
    "generatingPdf": "Generating PDF...",
    "saveAsPdf": "Save as PDF",
    "duplicateBannerTitle": "{count} Potential {count, plural, one {Duplicate} other {Duplicates}} Detected",
    "duplicateBannerBody": "The system has identified expense claims with identical reference numbers or matching vendor, date, and amount. Duplicate rows are highlighted in red below. Please review before processing reimbursement.",
    "labelName": "NAME",
    "labelDesignation": "DESIGNATION",
    "labelApprovedBy": "APPROVED BY",
    "colNo": "No.",
    "colDate": "Date",
    "colParticulars": "Particulars",
    "colAmount": "Amount ({currency})",
    "colTotal": "Total ({currency})",
    "refPrefix": "Ref: {ref}",
    "statusSplitExpense": "SPLIT EXPENSE",
    "statusConfirmedDuplicate": "CONFIRMED DUPLICATE",
    "statusPotentialDuplicate": "POTENTIAL DUPLICATE",
    "justificationInline": "Justification: {reason}",
    "total": "TOTAL",
    "forClaimantUse": "FOR CLAIMANT USE",
    "forAccountsUse": "FOR ACCOUNTS USE",
    "claimedBy": "Claimed by",
    "signatureDate": "Date",
    "receivedBy": "Received by",
    "forAdminUse": "FOR ADMIN USE",
    "verifiedBy": "Verified by",
    "approvedBy": "Approved by",
    "reportGeneratedOn": "Report generated on: {date}",
    "reportScope": "Report scope: {scope}",
    "dataAsOf": "Data as of: {date}",
    "badgeApproved": "Approved: {count, plural, one {# claim} other {# claims}}",
    "badgeSubmitted": "Submitted: {count, plural, one {# claim} other {# claims}}",
    "badgeRejected": "Rejected: {count, plural, one {# claim} other {# claims}}",
    "badgeDuplicate": "{count} Potential {count, plural, one {Duplicate} other {Duplicates}}",
    "errorSelectApprover": "Please select an approver",
    "errorRouteFailed": "Failed to route claim",
    "routeToButton": "Route to...",
    "routeShort": "Route",
    "dialogTitle": "Route Claim",
    "dialogDescription": "Select a manager or admin to reassign this expense claim for approval.",
    "routeToLabel": "Route to",
    "selectApproverPlaceholder": "Select an approver",
    "loading": "Loading...",
    "noApproversAvailable": "No other approvers available",
    "reasonLabel": "Reason (Optional)",
    "reasonPlaceholder": "Add a note explaining why you're routing this claim...",
    "routing": "Routing...",
    "routeClaimButton": "Route Claim",
    "receiptSelected": "Receipt Selected",
    "receiptReady": "Your receipt is ready for processing",
    "receiptPreviewAlt": "Receipt preview",
    "chooseDifferentFile": "Choose Different File",
    "processingReceipt": "Processing receipt with AI extraction...",
    "uploadReceipt": "Upload Receipt",
    "uploadReceiptSubtitle": "Capture or upload your receipt for automatic data extraction",
    "errorValidation": "Please select a valid image (JPEG, PNG, WebP) or PDF file",
    "errorSize": "File size must be less than 10MB",
    "optimizingImage": "Optimizing image for faster upload...",
    "camera": "Camera",
    "upload": "Upload",
    "enterManually": "Enter Manually",
    "errorResubmitFailed": "Failed to resubmit expense claim",
    "errorUnexpected": "An unexpected error occurred",
    "resubmit": "Resubmit",
    "resubmitRejectedTitle": "Resubmit rejected claim",
    "correctAndResubmit": "Correct & Resubmit",
    "dialogResubmitTitle": "Resubmit Rejected Claim",
    "dialogResubmitDescription": "Create a new draft expense claim based on this rejected claim. You can edit the new draft before submitting.",
    "rejectionReasonLabel": "Rejection Reason",
    "newDraftCreatedLabel": "New Draft Created",
    "newDraftCreatedBody": "A new draft expense claim has been created. You can now edit it and resubmit for approval.",
    "whatHappensTitle": "What happens when you resubmit:",
    "whatHappensStep1": "A new draft claim will be created with all the original data",
    "whatHappensStep2": "The receipt attachment will be copied to the new claim",
    "whatHappensStep3": "You can edit the new draft to make corrections",
    "whatHappensStep4": "Submit the corrected claim for approval",
    "done": "Done",
    "creating": "Creating...",
    "createDraft": "Create Draft",
    "selfDraftTitle": "You already have a draft of this receipt",
    "selfDraftSubtitleSingle": "A matching draft is waiting in your expenses",
    "selfDraftSubtitleMultiple": "{count} matching drafts are waiting in your expenses",
    "selfDraftBody": "This looks like a receipt you have already started. Submitting will create a separate claim. If this is the same expense, open your existing draft instead.",
    "selfDraftKeepEditing": "Keep editing",
    "selfDraftSubmitAnyway": "Submit anyway",
    "reportDateBasisSubmitted": "Selected by submission date: {from} to {to}",
    "reportDateBasisApproved": "Selected by approval date: {from} to {to}",
    "reportDateBasisTransaction": "Selected by transaction date: {from} to {to}",
    "reportCodePrefix": "Report: {code}",
    "batchCodePrefix": "Batch: {code}",
    "errorClaimNotFound": "We couldn't find this claim. It may have been deleted. Refresh the list and try again.",
    "errorInvalidStatus": "Only submitted claims can be routed. Refresh to see this claim's current status.",
    "errorRouteNotAuthorized": "Only the assigned approver, a finance admin, or the owner can route this claim.",
    "errorApproverNotFound": "That approver is no longer available. Pick someone else from the list.",
    "errorInvalidApprover": "That person can't approve claims here. Pick a manager, finance admin, or the owner.",
    "submissionStandaloneHeading": "NOT PART OF A REPORT",
    "submissionClaimsCount": "{count, plural, one {# claim} other {# claims}}",
    "submissionSubtotalLabel": "REPORT SUBTOTAL"
  },
  "x_invoices_0": {
    "cogs": {
      "title": {
        "edit": "Edit COGS Category",
        "add": "Add New COGS Category"
      },
      "subtitle": "Configure Cost of Goods Sold category for invoices and supplier transactions",
      "sections": {
        "basicInfo": "Basic Information",
        "costClassification": "Cost Classification",
        "autoCategorization": "Auto-Categorization Rules",
        "settings": "Category Settings"
      },
      "fields": {
        "categoryName": {
          "label": "Category Name *",
          "placeholder": "e.g., Materials & Supplies"
        },
        "description": {
          "label": "Description",
          "placeholder": "Brief description of this COGS category"
        },
        "glCode": {
          "label": "GL Account Code",
          "placeholder": "e.g., 5100",
          "help": "Chart of Account code for accounting software export"
        },
        "costType": {
          "label": "Cost Type *",
          "direct": "Direct Cost",
          "indirect": "Indirect Cost",
          "help": "Direct costs are directly attributable to specific products/services"
        },
        "keywords": {
          "label": "Keywords (comma-separated)",
          "placeholder": "materials, supplies, inventory, components",
          "help": "Keywords found in invoice descriptions will auto-categorize to this category"
        },
        "vendorPatterns": {
          "label": "Vendor Patterns (comma-separated)",
          "placeholder": "supplier, materials, wholesale, trading",
          "help": "Vendor names containing these patterns will auto-categorize to this category"
        },
        "sortOrder": {
          "label": "Sort Order",
          "help": "Lower numbers appear first in category lists"
        },
        "status": {
          "label": "Category Status",
          "enabled": "Enabled",
          "disabled": "Disabled",
          "enabledHelp": "Category is available for invoice categorization",
          "disabledHelp": "Category is hidden from categorization options"
        }
      },
      "validation": {
        "categoryNameRequired": "Category name is required",
        "sortOrderMin": "Sort order must be 0 or greater"
      },
      "actions": {
        "cancel": "Cancel",
        "saving": "Saving...",
        "update": "Update Category",
        "create": "Create Category"
      }
    },
    "field": {
      "boolean": {
        "yes": "Yes",
        "no": "No"
      },
      "itemCount": "{count} items",
      "viewDetails": "View details",
      "viewObjectData": "View object data",
      "notExtracted": "Not extracted",
      "aiConfidence": "AI Confidence",
      "tooltip": {
        "clickToHighlight": "Click to highlight in document",
        "bboxSupported": "Supports bounding box highlighting",
        "dataExtracted": "Data extracted",
        "noDataFound": "No data found"
      }
    },
    "ic": {
      "gender": {
        "male": "Male",
        "female": "Female",
        "notSpecified": "Not specified"
      },
      "fields": {
        "fullName": "Full Name",
        "icNumber": "IC Number",
        "dateOfBirth": "Date of Birth",
        "gender": "Gender",
        "registeredAddress": "Registered Address"
      },
      "sections": {
        "personalInfo": "Personal Information",
        "addressInfo": "Address Information"
      },
      "warning": "AI Extraction - Please verify accuracy"
    },
    "renderer": {
      "processingIssue": "Processing Issue",
      "documentAnalysis": "{type} Document Analysis",
      "fieldCount": "({completed}/{total} fields)",
      "showRawData": "Show Raw Extracted Data"
    },
    "apCreditNote": {
      "title": "Capture supplier credit note",
      "maxCreditable": "Reduce amount payable to supplier. Max creditable: {max}",
      "lineItemsHint": "Pre-filled from the original invoice. Change only what is being credited.",
      "total": "Credit Note Total",
      "fields": {
        "reason": {
          "label": "Reason *",
          "placeholder": "e.g., Goods returned to supplier, pricing error..."
        },
        "lineItems": {
          "label": "Line Items",
          "descriptionPlaceholder": "Description",
          "qtyPlaceholder": "Qty",
          "pricePlaceholder": "Price",
          "total": "Line total"
        },
        "notes": {
          "label": "Notes (optional)",
          "placeholder": "Additional notes..."
        }
      },
      "actions": {
        "addLineItem": "Add Line Item",
        "removeLineItem": "Remove line item",
        "creating": "Capturing...",
        "create": "Capture credit note",
        "cancel": "Cancel"
      },
      "allocation": {
        "scopeLabel": "What does this credit cover?",
        "source_lines": {
          "title": "Specific invoice items",
          "description": "Choose the returned or adjusted items below. Their original categories stay unchanged."
        },
        "overall": {
          "title": "Overall invoice adjustment",
          "description": "Use for an invoice-wide discount, rebate, or other general credit."
        },
        "sourceCategoryLocked": "Categories are inherited from the posted invoice so this credit reverses the same accounts.",
        "originalCategoryFallback": "Original invoice category",
        "overallDescription": "Overall invoice credit",
        "descriptionLabel": "Description",
        "amountLabel": "Credit amount",
        "categoryLabel": "How should this credit be categorised?",
        "proportional": {
          "title": "Allocate across original invoice categories",
          "description": "Recommended. Uses the same category proportions as the original invoice."
        },
        "specific": {
          "title": "Use one category",
          "description": "Use only when the entire credit belongs to a single category.",
          "selectLabel": "COGS category for this credit",
          "selectPlaceholder": "Choose a COGS category"
        }
      },
      "cogs": {
        "defaultLabel": "Default COGS category",
        "noDefault": "Use the standard expense account",
        "splitByLine": "Set categories by line",
        "useOneCategory": "Use default for all lines",
        "splitHint": "Turn this on only if some line items use a different category.",
        "splitEnabledHint": "Lines without a category use the default.",
        "collapseConfirm": "Use the default category for every line? This clears the categories set on individual lines.",
        "lineLabel": "COGS category",
        "useDefault": "Use default category",
        "chooseCategory": "Choose a category"
      },
      "errors": {
        "reasonRequired": "Credit note reason is required",
        "lineItemRequired": "At least one line item is required",
        "totalMustBePositive": "Credit note total must be greater than 0",
        "exceedsCreditable": "Credit note total ({total}) exceeds remaining creditable amount ({max})",
        "notCreditable": "This invoice is not completed, paid or posted yet, so a credit note cannot be raised against it. Post the invoice first, then try again.",
        "currencyMismatch": "A credit note must use the same currency as the original invoice. Change the line currency to match, then try again.",
        "exceedsRemainingCredit": "This credit note, plus the credit notes already raised on this invoice, would come to more than the invoice total. Lower the amount, or void an existing credit note first.",
        "categoryRequired": "Choose the COGS category for this overall credit.",
        "createFailed": "This supplier credit note could not be captured. Please try again.",
        "returnExceedsReceived": "More units than were received, less earlier returns, cannot go back. Lower the quantity.",
        "returnInsufficientStock": "Those units are not at this location any more. Choose another location or lower the quantity.",
        "returnCostUnreadable": "Groot cannot read how these goods were received, so it will not guess. Save the credit note without returning stock, then adjust the stock.",
        "returnInvoiceRequired": "Returning goods needs the supplier invoice they were received on.",
        "returnNotReceived": "That supplier line was never received into stock, so it cannot go back from stock."
      },
      "stockReturn": {
        "toggle": "Return goods to supplier",
        "help": "Takes the units out of stock at the cost they were received at, and reverses that receipt in the books.",
        "locationLabel": "Return from location",
        "locationPlaceholder": "Choose a location",
        "bucketLabel": "Units come from",
        "bucketSellable": "Sellable stock",
        "bucketDamaged": "Damaged stock",
        "columns": {
          "item": "Item",
          "received": "Received",
          "returned": "Already returned",
          "returnable": "Can return",
          "quantity": "Units going back"
        },
        "unitCost": "Received at {cost} each",
        "errors": {
          "locationRequired": "Choose the location the goods are going back from.",
          "quantityRequired": "Enter how many units are going back, or turn off Return goods to supplier.",
          "quantityExceeds": "{item}: only {max} can still go back."
        }
      }
    }
  },
  "x_invoices_2": {
    "modal": {
      "reopen": {
        "cta": "Reopen to edit",
        "reopening": "Reopening…",
        "confirmTitle": "Reopen this bill for editing?",
        "confirmMessage": "This reverses the bill's posting so it can be edited. A reversing journal entry is recorded and the original stays in your books for audit. You can re-post it after editing.",
        "confirmMessagePaid": "This bill has payments recorded against it. Reopening reverses those payments and the bill's posting, and any matched bank transactions will need reconciling again. A reversing journal entry is recorded for each.",
        "confirmCta": "Reopen bill",
        "success": "Bill reopened for editing",
        "successPaidDescription": "{payments} payment(s) reversed · {bankTransactions} bank transaction(s) unmatched",
        "errorTitle": "Couldn't reopen this bill"
      },
      "title": "Document Analysis",
      "close": "Close",
      "hideDocumentPreview": "Hide Document Preview",
      "viewDocumentPreview": "View Document Preview",
      "documentPreview": "Document Preview",
      "pagesCount": "({count} pages)",
      "loadingPages": "Loading pages...",
      "pageOf": "Page {current} of {total}",
      "loadingDocument": "Loading document...",
      "noPreviewAvailable": "No preview available",
      "processingInformation": "Processing Information",
      "invoiceId": "Invoice ID",
      "copyInvoiceId": "Copy Invoice ID",
      "invoiceIdCopied": "Invoice ID copied",
      "invoiceIdCopyFailed": "Couldn't copy invoice ID",
      "processingFailedFallback": "Processing failed",
      "status": "Status:",
      "aiConfidence": "AI Confidence:",
      "notAvailable": "N/A",
      "processingIssue": "Processing Issue",
      "journalEntry": "Journal Entry",
      "posted": "Posted",
      "reversed": "Reversed",
      "location": {
        "saved": "Invoice Location saved",
        "saveFailed": "Could not save the invoice Location",
        "requiredToPost": "Choose a Location before posting."
      },
      "inventoryReceived": "Inventory Received",
      "done": "Done",
      "inventoryReceivedDescription": "Items from this invoice have been received into inventory.",
      "inventoryManagedInSql": "Stock managed in SQL Account",
      "inventoryManagedInSqlDescription": "Stock is managed in SQL Account for this business. Inventory is raised when the itemized Purchase Invoice is imported into SQL. Groot does not also raise it.",
      "receiveToInventory": "Receive to Inventory",
      "payment": {
        "title": "Payment",
        "status": {
          "unpaid": "Unpaid",
          "partial": "Partially paid",
          "paid": "Paid"
        },
        "recordPayment": "Record payment",
        "postToAP": "Post to AP",
        "reviewGstToPost": "Review GST to post",
        "postingToAP": "Posting...",
        "amountReview": {
          "title": "Invoice amounts don't match",
          "checked": "Total checked",
          "postingPaused": "Posting paused",
          "fromLines": "Lines and charges",
          "invoiceTotal": "Invoice total",
          "difference": "Difference",
          "lineTotalsMissing": "Line totals cannot be checked.",
          "editDescription": "Fix the invoice amounts before posting categories by line.",
          "confirmDescription": "Check the supplier invoice total before posting it to one COGS category.",
          "checkedDescription": "The supplier invoice total was checked and can be posted to one COGS category.",
          "editAmounts": "Edit amounts",
          "confirmTotal": "I checked the invoice total",
          "confirmedToast": "Invoice total confirmed",
          "confirmFailed": "Couldn't confirm the invoice total",
          "confirmFailedDescription": "Refresh the invoice and try again."
        },
        "postFirstDescription": "Post this invoice to AP before recording an outgoing payment.",
        "confirmFirstDescription": "Confirm this invoice before recording an outgoing payment.",
        "zeroTotalNoLedger": "This zero-total invoice is saved for your records and inventory receipt. It does not create a ledger entry or supplier payment.",
        "alreadyPaidDescription": "This invoice is already fully paid.",
        "amountMissingDescription": "The invoice total is missing or zero. Check the extracted amount before recording payment.",
        "fullApRequiredDescription": "Full AP is required to record Purchase Invoice payments.",
        "total": "Total",
        "paid": "Paid",
        "outstanding": "Outstanding",
        "history": "Payment history",
        "noHistory": "No payments have been recorded yet.",
        "journalEntryShort": "Payment JE",
        "methods": {
          "bankTransfer": "Bank Transfer",
          "cash": "Cash",
          "cheque": "Cheque",
          "card": "Card",
          "other": "Other"
        },
        "postToLedger": "Post to ledger"
      },
      "documentSummary": "Document Summary",
      "hovering": "Hovering: {category}",
      "documentType": "Document Type",
      "vendor": "Vendor",
      "amount": "Amount",
      "date": "Date",
      "vendorInformation": "Vendor Information",
      "notExtracted": "Not extracted",
      "address": "Address",
      "contact": "Contact",
      "taxIdRegistration": "Tax ID / Registration",
      "customerInformation": "Customer Information",
      "customerName": "Customer Name",
      "customerAddress": "Customer Address",
      "customerContact": "Customer Contact",
      "documentInformation": "Document Information",
      "documentNumber": "Document Number",
      "billReference": "Reference (PO or DO)",
      "billReferenceNone": "Not entered",
      "dueDate": "Due Date",
      "paymentInformation": "Payment Information",
      "paymentTerms": "Payment Terms",
      "paymentMethod": "Payment Method",
      "bankDetails": "Bank Details",
      "taxFinancialBreakdown": "Tax & Financial Breakdown",
      "subtotal": "Subtotal",
      "taxAmount": "Tax Amount",
      "discount": "Discount",
      "documentSpecificInformation": "Document-Specific Information",
      "invoiceDetails": "Invoice Details",
      "invoiceNumber": "Invoice Number:",
      "customer": "Customer:",
      "paymentTermsLabel": "Payment Terms:",
      "dueDateLabel": "Due Date:",
      "receiptDetails": "Receipt Details",
      "receiptNumber": "Receipt Number:",
      "paymentMethodLabel": "Payment Method:",
      "cashierId": "Cashier ID:",
      "transportDetails": "Transport Details",
      "tripId": "Trip ID:",
      "pickup": "Pickup:",
      "dropoff": "Dropoff:",
      "createCreditNote": "Supplier credit note",
      "creditNoteNeedsPosting": "Post this bill to your accounts first, then you can record a credit note against it. An unposted bill has no payable to credit.",
      "createDebitNote": "Supplier debit note",
      "financialEntities": "Financial Entities ({count})",
      "lineItems": "Line Items",
      "extractingLineItems": "Extracting line items...",
      "pendingExtraction": "(Pending extraction)",
      "complete": "✓ Complete",
      "colDescription": "Description",
      "colItemCode": "Item Code",
      "colQty": "Qty",
      "colUnit": "Unit",
      "colUnitPrice": "Unit Price",
      "colDiscount": "Discount",
      "colNetCost": "Net Cost",
      "colTotal": "Total",
      "extractingLineItemsFromDocument": "Extracting line items from document...",
      "lineItemsExtractionPending": "Line items extraction pending...",
      "willUpdateAutomatically": "This will update automatically when complete",
      "completeExtractedText": "Complete Extracted Text",
      "cleanOcrOutput": "Clean OCR Output",
      "cleanStructuredDataExtracted": "Clean structured data extracted successfully",
      "hideRawJson": "Hide Raw JSON Data",
      "showRawJson": "Show Raw JSON Data",
      "readingInvoice": "Reading invoice…",
      "readingLineItems": "Reading line items…",
      "pagesNotRead": "Only {read} of {total} pages were read. Amounts printed on the pages we skipped are not included, so check the total yourself."
    },
    "debitNote": {
      "title": "Capture supplier debit note",
      "description": "Record additional charges from supplier (e.g., freight surcharge, price adjustment).",
      "reasonLabel": "Reason *",
      "reasonPlaceholder": "e.g., Freight surcharge, price adjustment...",
      "lineItemsLabel": "Line Items",
      "descriptionPlaceholder": "Description",
      "qtyPlaceholder": "Qty",
      "pricePlaceholder": "Price",
      "lineTotal": "Line total",
      "addLineItem": "Add Line Item",
      "removeLineItem": "Remove line item",
      "notesLabel": "Notes (optional)",
      "notesPlaceholder": "Additional notes...",
      "total": "Debit Note Total",
      "creating": "Capturing...",
      "create": "Capture debit note",
      "cancel": "Cancel",
      "allocation": {
        "scopeLabel": "What does this charge cover?",
        "source_lines": {
          "title": "Specific invoice items",
          "description": "Choose the adjusted items below. Their original categories stay unchanged."
        },
        "overall": {
          "title": "Overall invoice adjustment",
          "description": "Use for freight, a surcharge, or another invoice-wide charge."
        },
        "sourceCategoryLocked": "Categories are inherited from the posted invoice so this charge follows the same accounts.",
        "originalCategoryFallback": "Original invoice category",
        "overallDescription": "Overall invoice charge",
        "descriptionLabel": "Description",
        "amountLabel": "Charge amount",
        "categoryLabel": "How should this charge be categorised?",
        "proportional": {
          "title": "Allocate across original invoice categories",
          "description": "Recommended. Uses the same category proportions as the original invoice."
        },
        "specific": {
          "title": "Use one category",
          "description": "Use only when the entire charge belongs to a single category.",
          "selectLabel": "COGS category for this charge",
          "selectPlaceholder": "Choose a COGS category"
        }
      },
      "cogs": {
        "defaultLabel": "Default COGS category",
        "noDefault": "Use the standard expense account",
        "splitByLine": "Set categories by line",
        "useOneCategory": "Use default for all lines",
        "splitHint": "Turn this on only if some line items use a different category.",
        "splitEnabledHint": "Lines without a category use the default.",
        "collapseConfirm": "Use the default category for every line? This clears the categories set on individual lines.",
        "lineLabel": "COGS category",
        "useDefault": "Use default category",
        "chooseCategory": "Choose a category"
      },
      "errors": {
        "reasonRequired": "Debit note reason is required",
        "lineItemRequired": "At least one line item is required",
        "totalGreaterThanZero": "Debit note total must be greater than 0",
        "notDebitable": "This invoice is not completed, paid or posted yet, so a debit note cannot be raised against it. Post the invoice first, then try again.",
        "currencyMismatch": "A debit note must use the same currency as the original invoice. Change the line currency to match, then try again.",
        "categoryRequired": "Choose the COGS category for this overall charge.",
        "createFailed": "This supplier debit note could not be captured. Please try again."
      }
    },
    "lineItemsTable": {
      "empty": "No line items available",
      "totalItems": "Total items:"
    },
    "payslip": {
      "notAvailable": "N/A",
      "employeeName": "Employee Name",
      "payPeriod": "Pay Period",
      "netWages": "Net Wages",
      "employerName": "Employer Name",
      "earningsItems": "Earnings Items",
      "deductionItems": "Deduction Items",
      "lineItemsExtracted": "{count} line items extracted",
      "basicInformation": "Basic Information",
      "icNumber": "IC Number",
      "employeeCode": "Employee Code",
      "financialSummary": "Financial Summary",
      "grossWages": "Gross Wages",
      "totalDeductions": "Total Deductions",
      "earningsBreakdown": "Earnings Breakdown",
      "deductionsBreakdown": "Deductions Breakdown",
      "description": "Description",
      "amount": "Amount",
      "aiExtractionWarning": "AI Extraction - Please verify accuracy"
    },
    "applicationForm": {
      "notProvided": "Not provided",
      "notSpecified": "Not specified",
      "year": "Year",
      "years": "Years",
      "yearLower": "year",
      "yearsLower": "years",
      "financingDetails": "Financing Details",
      "typeOfFinancing": "Type of Financing",
      "amountRequested": "Amount Requested",
      "applicationType": "Application Type",
      "tenure": "Tenure",
      "purposeOfFinancing": "Purpose of Financing",
      "personalInformation": "Personal Information",
      "fullName": "Full Name",
      "mykadNumber": "MyKad Number",
      "dateOfBirth": "Date of Birth",
      "maritalStatus": "Marital Status",
      "phoneNumber": "Phone Number",
      "emailAddress": "Email Address",
      "residentialAddress": "Residential Address",
      "employmentDetails": "Employment Details",
      "employerName": "Employer Name",
      "monthlyIncome": "Monthly Income",
      "jobTitle": "Job Title",
      "employmentType": "Employment Type",
      "yearsOfService": "Years of Service",
      "department": "Department",
      "officePhone": "Office Phone",
      "employerAddress": "Employer Address",
      "aiExtractionWarning": "AI Extraction - Please verify accuracy"
    },
    "editor": {
      "editButton": "Edit extracted fields",
      "title": "Edit extracted fields",
      "subtitle": "Correct any AI-extracted value below, then save as a draft before posting to AP.",
      "vendorSection": "Vendor",
      "vendorName": "Vendor name",
      "vendorAddress": "Vendor address",
      "vendorContact": "Vendor contact",
      "vendorTaxId": "Vendor tax ID",
      "documentSection": "Invoice details",
      "invoiceNumber": "Invoice number",
      "billReference": "Reference (PO or DO)",
      "billReferenceHint": "Goes to Ext. No in SQL Account.",
      "billReferenceNoRoom": "This reference will not fit in Ext. No, because the long supplier invoice number takes that space first.",
      "supplierNumberTooLong": "This supplier invoice number is longer than the 40 characters SQL Account keeps. SQL Account would cut it short, so we will not send this bill automatically. Check that the number was read correctly.",
      "invoiceDate": "Invoice date",
      "dueDate": "Due date",
      "currency": "Currency",
      "paymentTerms": "Payment terms",
      "paymentMethod": "Payment method",
      "lineItemsSection": "Line items",
      "colDescription": "Description",
      "colItemCode": "Item code",
      "colQty": "Qty",
      "colUnit": "Unit",
      "colUnitPrice": "Unit price",
      "colDiscount": "Discount",
      "colDiscountAmount": "Discount amount",
      "colDiscountPercent": "Discount percent",
      "colNetCost": "Net cost",
      "colLineTotal": "Line total",
      "discountAmountPlaceholder": "Amount",
      "discountPercentPlaceholder": "%",
      "lineItemAria": "Line item {row} {field}",
      "addLineItem": "Add line item",
      "removeLineItem": "Remove line item {row}",
      "noLineItems": "No line items. Add one if the invoice has item rows.",
      "totalsSection": "Totals",
      "subtotal": "Subtotal",
      "taxAmount": "Tax amount",
      "discount": "Discount",
      "totalAmount": "Total amount",
      "computedTotal": "Computed from line items: {amount}",
      "saveDraft": "Save draft",
      "saving": "Saving...",
      "cancel": "Cancel",
      "saveSuccessTitle": "Draft saved",
      "saveSuccessDescription": "Extracted fields updated. Review and post to AP when ready.",
      "saveErrorTitle": "Could not save changes",
      "saveErrorFallback": "Saving the edited fields failed. Please try again.",
      "invalidNumberTitle": "Invalid amount",
      "invalidNumberDescription": "Check the highlighted numeric fields. They must be numbers.",
      "datePlaceholder": "YYYY-MM-DD",
      "cogsCategory": "COGS category",
      "cogsCategoryNone": "(None)",
      "postedToAccount": "Posted to",
      "cogsDefaultHint": "Each line uses the default category unless you choose a different one.",
      "splitCogsByLine": "Set categories by line",
      "editCogsByLine": "Edit categories by line",
      "useOneCogsCategory": "Use default for all lines",
      "splitCogsHint": "Turn this on only if some line items use a different category.",
      "splitCogsEnabledHint": "Lines without a category use the default.",
      "applyDefaultToAll": "Reset all lines to default",
      "splitCogsCollapseConfirm": "Use the default category for every line? This clears the categories set on individual lines.",
      "colCogsCategory": "COGS category",
      "useDefaultCogsCategory": "Use default category",
      "defaultCogsCategory": "Default COGS category",
      "chooseCogsCategory": "Choose a category",
      "cogsAllocationTitle": "COGS categories",
      "cogsAllocationRequired": "Choose a default COGS category or one for every line.",
      "lineItemsExtractingHint": "Line items are still being extracted. Edits you save now are kept. The automatic extraction will not overwrite them.",
      "readingLineItems": "Reading line items…",
      "supplierChoose": "Choose supplier",
      "supplierChange": "Change",
      "supplierLinkedAs": "Linked to {name}",
      "supplierSuggestion": "Appears to be {name}. Confirm?",
      "supplierAmbiguous": "Found more than one matching supplier. Pick the right one.",
      "supplierSearchPlaceholder": "Search suppliers",
      "supplierSearchAria": "Search suppliers",
      "supplierSearchHint": "Type a supplier name to search.",
      "supplierSearchEmpty": "No supplier matches your search.",
      "cogsSaved": "Posting account saved",
      "cogsSaveFailed": "Could not save the posting account",
      "categorySourceUnavailable": "We could not load your categories, so nothing was suggested. Pick one, or this bill posts to your default cost of goods sold account.",
      "categorySourceNoneConfigured": "No cost of goods sold categories are switched on, so nothing was suggested. Switch some on under Chart of Accounts.",
      "categorySourceNotLearned": "Groot could not learn this supplier's category yet: it needs three posted bills in the same category. Choose one, or this bill will post to your default cost of sales account."
    },
    "feedback": {
      "prompt": "Was the extraction correct?",
      "good": "Extraction looks correct",
      "bad": "Extraction has errors",
      "thanks": "Thanks! This helps Groot improve.",
      "error": "Couldn't save your feedback. Please try again."
    },
    "itemMatch": {
      "matchToCatalog": "Match to catalog",
      "showCatalogMatch": "Show catalog match",
      "resolving": "Matching…",
      "matched": "Matched",
      "needsMatch": "No catalog match yet",
      "itemCodePlaceholder": "Item code",
      "candidatesTitle": "Suggested catalog item",
      "catalogItemFallback": "Catalog item",
      "confidenceSuffix": "· {confidence}%",
      "editExtractedFields": "Edit extracted fields",
      "confirmedTitle": "Item match confirmed",
      "confirmedDescription": "“{item}” is now linked for this supplier, so future invoices match automatically and the SQL export learns it.",
      "confirmedDescriptionPendingSql": "“{item}” is now linked for this supplier, so future invoices match automatically. It will sync to the SQL export once it’s added there.",
      "confirmErrorTitle": "Could not confirm the item match",
      "confirmErrorFallback": "Confirming the item match failed. Please try again."
    },
    "duplicateBill": {
      "chip": "Possible duplicate",
      "chipTitle": "Another bill from this supplier carries the same invoice number.",
      "bannerTitle": "Possible duplicate bill",
      "bannerBody": "{count, plural, one {Another bill from this supplier already carries invoice number {number}.} other {# other bills from this supplier already carry invoice number {number}.}}",
      "bannerSameTotal": "One of them has the same total, so this may be the same bill uploaded twice.",
      "bannerPosted": "At least one of them is already posted.",
      "confirmTitle": "Post a possible duplicate bill?",
      "confirmBody": "{count, plural, one {This bill has the same supplier and invoice number as another bill.} other {# of the selected bills have the same supplier and invoice number as another bill.}} Posting both would record the same purchase twice.",
      "confirmAcknowledge": "I have checked, and this is not a duplicate",
      "confirmPost": "Post anyway",
      "confirmBack": "Go back"
    },
    "mergedDocument": {
      "chip": "At least {count} invoices",
      "chipAcknowledged": "Checked: one invoice",
      "chipTitle": "This file seems to hold more than one supplier invoice. Open it to see the invoice numbers.",
      "bannerTitle": "This file may hold more than one invoice",
      "bannerBody": "Groot read at least {count} separate invoices in this file. The figures on this bill may cover only one of them.",
      "listLabel": "Other invoices seen",
      "listMore": "and {count} more",
      "minimum": "This count is a minimum. A long file can have pages Groot did not read.",
      "action": "Upload each invoice as its own file so each one posts correctly. If this really is one invoice, confirm that below.",
      "postingPaused": "Posting paused",
      "acknowledge": "This is one invoice",
      "acknowledgedTitle": "You confirmed this file is one invoice",
      "acknowledgedBody": "The other invoice numbers Groot saw in this file are not posted separately.",
      "acknowledgedToast": "Confirmed. This bill can be posted now.",
      "acknowledgeFailed": "Could not confirm",
      "acknowledgeFailedDescription": "Refresh the invoice and try again. If it keeps failing, contact support.",
      "refused": {
        "DOCUMENT_VOIDED": "This bill was voided, so it can no longer be changed.",
        "INVOICE_ALREADY_POSTED": "This bill is already posted.",
        "MERGED_DOCUMENT_NOTHING_TO_ACKNOWLEDGE": "This file no longer shows more than one invoice. Refresh the page."
      },
      "postedAction": "This bill is already posted. Check the invoice numbers above against your books, and upload any invoice you have not recorded as its own file."
    }
  },
  "x_invoices_3": {
    "empty": {
      "noDocuments": "No documents uploaded yet.",
      "uploadHint": "Upload your first document above to get started.",
      "noCreditPurchases": "No credit purchases yet.",
      "noCreditPurchasesHint": "Supplier bills you settle later appear here once you upload or enter one.",
      "noDirectPurchases": "No direct purchases yet.",
      "noDirectPurchasesHint": "A purchase paid at the point of purchase appears here. It never creates a payable."
    },
    "vendorBanner": {
      "filteredBy": "Filtered by vendor:",
      "count": "({visible} of {total} {total, plural, one {invoice} other {invoices}})",
      "clear": "Clear",
      "clearAria": "Clear vendor filter"
    },
    "vendorEmpty": {
      "noMatch": "No invoices match vendor \"{vendor}\".",
      "clearHint": "Clear the filter to see all {total} {total, plural, one {invoice} other {invoices}}."
    },
    "bulkBar": {
      "selectedCount": "{selected} of {total} invoices selected",
      "selectAllPostable": "Select All Postable",
      "clear": "Clear",
      "posting": "Posting...",
      "postToAP": "Post to AP ({count})",
      "postDirect": "Post to ledger ({count})"
    },
    "badge": {
      "creditNote": "CN",
      "debitNote": "DN",
      "posted": "Posted",
      "postedTitle": "Click to view journal entry",
      "voided": "Voided",
      "notPosted": "Not Posted",
      "noLedgerEntryZeroTotal": "No ledger entry (zero total)",
      "cashPurchase": "Cash purchase",
      "cashPurchaseTitle": "Paid on the spot, so no payable was created.",
      "heldForReview": "Pending Review",
      "cashPurchaseEvidenceTitle": "Click to see why this was recorded as already paid"
    },
    "paymentStatus": {
      "unpaid": "Unpaid",
      "partial": "Partially paid",
      "paid": "Paid"
    },
    "processingStatus": {
      "uploading": "Uploading",
      "pending": "Pending",
      "analyzing": "Analyzing",
      "analyzingStage": "Analyzing ({stage})",
      "stage": {
        "extracting": "extracting",
        "analyzing": "analyzing",
        "finalizing": "finalizing"
      },
      "processing": "Processing",
      "classifying": "Classifying Document",
      "completed": "Completed",
      "classificationFailed": "Classification Failed",
      "paid": "Paid",
      "overdue": "Overdue",
      "disputed": "Disputed",
      "cancelled": "Cancelled",
      "failed": "Failed",
      "unknown": "Unknown"
    },
    "lhdn": {
      "rejected": "Rejected",
      "hoursLeftToReject": "{hours}h left to reject",
      "verified": "LHDN ✓",
      "pending": "LHDN...",
      "validated": "LHDN validated",
      "cancelled": "LHDN cancelled"
    },
    "compactTitle": {
      "invoiceNumber": "Invoice: {number}"
    },
    "row": {
      "selectInvoiceAria": "Select invoice",
      "originalInvoice": "original invoice",
      "creditNoteCreatedFrom": "Supplier credit note · against {invoiceNumber} · {date}",
      "debitNoteCreatedFrom": "Supplier debit note · against {invoiceNumber} · {date}",
      "viewDetails": "View details",
      "analyze": "Analyze",
      "reprocess": "Reprocess",
      "processing": "Processing...",
      "retry": "Retry",
      "recordPayment": "Record payment",
      "recordPaymentPostFirst": "Post this invoice to AP before recording payment.",
      "recordPaymentAlreadyPaid": "This invoice is already fully paid.",
      "recordPaymentFullApRequired": "Full AP is required to record Purchase Invoice payments.",
      "delete": "Delete",
      "confirmAndPost": "Confirm & post",
      "dueOn": "Due {date}",
      "voidedReadOnly": "Voided. This bill can no longer be changed.",
      "confirmAndSendSql": "Confirm and send to SQL Account",
      "confirmAndSendSqlHint": "Groot posts this invoice and sends it to SQL Account automatically.",
      "sqlReviewHint": "Check what Groot read from this invoice. When you confirm, it is posted and sent to SQL Account automatically."
    },
    "classificationFailed": "Classification failed",
    "deleteDialog": {
      "title": "Delete Document",
      "message": "Are you sure you want to delete this document? This action cannot be undone.",
      "confirm": "Delete",
      "cancel": "Cancel"
    },
    "toast": {
      "deleteSuccess": {
        "title": "Document deleted",
        "description": "The document has been successfully deleted"
      },
      "deleteError": {
        "title": "Delete failed",
        "fallback": "Unable to delete the document"
      },
      "postSuccess": {
        "title": "Posted to AP",
        "vendorNote": ". {count, plural, one {Vendor} other {Vendors}} {vendors} now active.",
        "partial": "Posted {succeeded} of {total} invoices. {failed} failed{vendorNote}",
        "full": "Successfully posted {count, plural, one {# invoice} other {# invoices}} to AP{vendorNote}",
        "titleDirect": "Posted to the ledger",
        "fullDirect": "Successfully posted {count, plural, one {# direct purchase} other {# direct purchases}} to the ledger{vendorNote}"
      },
      "confirmSuccess": {
        "title": "Posted",
        "stockAdvisory": "{amount} of this bill went to Cost of Sales and none of it was received into stock. If any of it is goods you keep in stock, receive them from the bill so stock on hand and cost of goods stay right.",
        "stockAdvisorySplit": "{amount} of this bill went to Cost of Sales and none of it was received into stock. A bill split across several categories cannot be received from the bill, so if any of it is stock you keep, add it under Stock with its cost."
      },
      "confirmFailed": {
        "title": "Confirm and post failed"
      },
      "processError": {
        "title": "Could not start reprocessing"
      }
    },
    "postError": {
      "currentPeriod": "current period",
      "unknown": "Unknown error",
      "unableToPost": "Unable to post invoices to AP",
      "periodClosed": {
        "title": "Accounting period closed",
        "description": "The accounting period {period} is closed. Go to Accounting → Periods to reopen it, then try again."
      },
      "coaMissing": {
        "title": "Chart of accounts missing",
        "description": "Your business needs Expense (5100) and AP (2100) accounts. Go to Accounting > Chart of Accounts to set them up."
      },
      "notReady": {
        "title": "Invoice not ready",
        "description": "The invoice is still processing or missing extracted data. Wait for OCR to complete, then try again."
      },
      "invalidAmount": {
        "title": "Invalid invoice amount",
        "description": "The invoice total amount is missing or zero. Check the extracted data and correct the amount."
      },
      "alreadyPosted": {
        "title": "Already posted",
        "description": "This invoice has already been posted to AP. Check the Accounting > Journal Entries page."
      },
      "generic": {
        "title": "Post to AP failed"
      },
      "heldForReview": {
        "title": "Pending review",
        "description": "This invoice is waiting for review, so it cannot be posted from here. Open the invoice, then use Confirm & post."
      },
      "amountConfirmationRequired": {
        "title": "Check invoice total",
        "description": "Open the invoice and confirm the supplier total before posting."
      },
      "lineAmountsUnreconciled": {
        "title": "Invoice amounts don't match",
        "description": "Open the invoice and correct the amounts before posting categories by line."
      },
      "locationRequired": {
        "title": "Choose a Location",
        "description": "Select the invoice Location, then post it again."
      },
      "beforeConversionDate": {
        "title": "Date before go-live",
        "description": "This date is before your opening-balance go-live date. Use a date on or after go-live, or review the opening balance in Accounting → Opening balance."
      },
      "fxRateUnresolved": {
        "title": "Exchange rate needed",
        "description": "This bill is in a foreign currency and there is no exchange rate for its date, so it was not posted. Enter a rate on the bill, or add one under Accounting → Chart of Accounts → Currencies & rates, then post it again."
      },
      "fxBillDateRequired": {
        "title": "Bill date needed",
        "description": "Add the bill date to see its exchange rate."
      },
      "mergedDocumentAcknowledgementRequired": {
        "title": "This file holds more than one invoice",
        "description": "Upload each invoice as its own file. If this really is one invoice, open it, confirm that, and post it again."
      }
    },
    "cogs": {
      "title": "Cost of Goods Sold Categories",
      "description": "Manage COGS categories for invoice and supplier transactions",
      "addCategory": "Add Category",
      "searchPlaceholder": "Search COGS categories...",
      "loading": "Loading COGS categories...",
      "noPermission": "COGS category management is available for managers and finance users only.",
      "empty": {
        "noMatch": "No COGS categories match your search",
        "none": "No COGS categories found"
      },
      "costType": {
        "direct": "Direct",
        "indirect": "Indirect"
      },
      "card": {
        "inactive": "Inactive",
        "costType": "Cost Type: {type}",
        "keywords": "Keywords: {keywords}",
        "vendorPatterns": "Vendor Patterns: {patterns}",
        "edit": "Edit"
      },
      "success": {
        "created": "COGS category created successfully",
        "updated": "COGS category updated successfully",
        "deleted": "COGS category deleted successfully"
      },
      "error": {
        "fetch": "Failed to fetch COGS categories",
        "fetchNetwork": "Network error while fetching COGS categories",
        "save": "Failed to save COGS category",
        "saveNetwork": "Network error while saving COGS category",
        "delete": "Failed to delete COGS category",
        "deleteNetwork": "Network error while deleting COGS category"
      },
      "deleteDialog": {
        "title": "Delete COGS Category",
        "message": "Are you sure you want to delete the COGS category \"{name}\"? This action cannot be undone and may affect existing invoices.",
        "confirm": "Delete",
        "cancel": "Cancel"
      }
    },
    "ocr": {
      "extractedText": "Extracted Text",
      "confidenceLabel": "Confidence:",
      "confidenceValue": "{percent}% ({label})",
      "confidence": {
        "high": "High",
        "medium": "Medium",
        "low": "Low"
      },
      "toggle": {
        "structured": "Structured",
        "rawText": "Raw Text"
      },
      "editTitle": "Edit text",
      "copyTitle": "Copy text",
      "documentInformation": "Document Information",
      "documentType": "Document Type",
      "invoiceReceiptNumber": "Invoice/Receipt Number",
      "date": "Date",
      "vendorInformation": "Vendor Information",
      "lineItems": "Line Items",
      "table": {
        "description": "Description",
        "qty": "Qty",
        "unitPrice": "Unit Price",
        "total": "Total",
        "confidence": "Confidence"
      },
      "summary": "Summary",
      "subtotal": "Subtotal:",
      "tax": "Tax:",
      "total": "Total:",
      "notes": "Notes",
      "rawOcrText": "Raw OCR Text",
      "editPlaceholder": "Edit the extracted text...",
      "saveChanges": "Save Changes",
      "cancel": "Cancel",
      "parseWarning": "⚠️ Unable to parse document structure. Showing raw text instead.",
      "wordsExtracted": "{count} words extracted",
      "processingMethod": "Processing method: OCR"
    },
    "manualInvoice": {
      "enterManually": "Enter invoice manually",
      "title": "Enter invoice manually",
      "cashTitle": "Record a cash purchase",
      "description": "Create a supplier invoice without uploading a document. It posts to your ledger as soon as you save it.",
      "cashDescription": "The supplier has already been paid, so no payable is created. It posts to your ledger as soon as you save it.",
      "vendorName": "Vendor name",
      "vendorPlaceholder": "e.g. TEO HIN SDN BHD",
      "invoiceNumber": "Invoice number",
      "invoiceDate": "Invoice date",
      "currency": "Currency",
      "lineItems": "Line items",
      "itemCode": "Item code",
      "itemCodePlaceholder": "Supplier or catalog code",
      "itemOptions": "Supplier and catalog items",
      "itemSearching": "Searching items…",
      "itemNoneMatching": "No matching items",
      "itemNoneForVendor": "No items recorded for this supplier",
      "itemTypeToSearch": "Type an item code to search the catalog",
      "itemFreeTextHelp": "You can keep this item code as free text.",
      "itemNoCode": "No item code",
      "itemMappedTo": "Mapped to {name}",
      "itemMapped": "Mapped to catalog",
      "itemSupplierHistory": "Supplier history",
      "itemCatalog": "Catalog item",
      "itemLoadMore": "Load more supplier items",
      "itemLoadError": "We couldn't load supplier items. Try again to continue.",
      "itemRetry": "Try again",
      "itemDescription": "Description",
      "qty": "Qty",
      "unitPrice": "Unit price",
      "addLine": "Add line",
      "removeLine": "Remove line",
      "cogs": {
        "defaultLabel": "Default COGS category",
        "noDefault": "Use the standard expense account",
        "splitByLine": "Set categories by line",
        "useOneCategory": "Use default for all lines",
        "splitHint": "Turn this on only if some line items use a different category.",
        "splitEnabledHint": "Lines without a category use the default.",
        "collapseConfirm": "Use the default category for every line? This clears the categories set on individual lines.",
        "lineLabel": "COGS category",
        "useDefault": "Use default category",
        "chooseCategory": "Choose a category"
      },
      "taxAmount": "Tax amount (optional)",
      "notes": "Notes (optional)",
      "notesPlaceholder": "Internal note",
      "subtotal": "Subtotal",
      "tax": "Tax",
      "total": "Total",
      "cancel": "Cancel",
      "create": "Create invoice",
      "creating": "Creating…",
      "successTitle": "Invoice created",
      "successDescription": "{docNo} added to Purchase Invoices.",
      "zeroTotalDescription": "{docNo} was saved without a ledger entry because its total is zero.",
      "genericError": "Could not create the invoice. Please try again.",
      "receiveGoods": "Receive goods after creating this invoice",
      "receiveGoodsHelp": "Continue straight to catalog matching and stock receipt after the invoice is created.",
      "receiveDeferred": "Receive goods becomes available after this invoice is posted. Finish its review from Purchase Invoices first.",
      "required": {
        "summary": "Fill in the fields marked below before you create this invoice.",
        "vendorName": "Enter the vendor name",
        "vendorPhone": "Enter the supplier phone number",
        "vendorPhoneInvalid": "Enter a valid supplier phone number for Malaysia",
        "vendorEmailInvalid": "Enter a valid supplier email address",
        "vendorAddress": "Enter the supplier street address",
        "vendorCity": "Enter the supplier city",
        "vendorPostalCode": "Enter the supplier postcode",
        "vendorCountry": "Choose the supplier country",
        "vendorState": "Choose the supplier state",
        "invoiceNumber": "Enter the invoice number",
        "invoiceDate": "Choose the invoice date",
        "lineItem": "Give line {row} a description, a quantity above zero and a unit price",
        "lineDescription": "Enter a description for line {row}",
        "lineQuantity": "Enter a quantity above zero for line {row}",
        "lineUnitPrice": "Enter a unit price of zero or more for line {row}",
        "taxAmountNonNegative": "Enter a tax amount of zero or more",
        "cogsCategory": "Choose a default COGS category or one for every line"
      },
      "postedTitle": "Invoice created and posted",
      "postedApDescription": "{docNo} is now a payable, posted to account {account}.",
      "postedCashDescription": "{docNo} posted as a cash purchase, paid from account {account}.",
      "deferredGstReview": "{docNo} was saved as a draft. Review its input GST from Purchase Invoices, then it can post.",
      "deferredFeatureNotEnabled": "{docNo} was saved as a draft. Posting purchase invoices to the ledger isn't included in your current plan. Upgrade in Settings to turn it on.",
      "settlement": {
        "label": "How was this paid?",
        "ap": "On credit (you still owe the supplier)",
        "apHelp": "Posts to Accounts Payable, so it appears in the aging report and on the pay run.",
        "cash": "Cash purchase (paid on the spot)",
        "cashHelp": "No payable is created. The cost is posted against the bank or cash account below.",
        "lockedHint": "Set by the purchases tab you are on. Switch tabs to record the other kind."
      },
      "stockAdvisory": "{amount} of this bill went to Cost of Sales and none of it was received into stock. If any of it is goods you keep in stock, receive them from the bill so stock on hand and cost of goods stay right.",
      "stockAdvisorySplit": "{amount} of this bill went to Cost of Sales and none of it was received into stock. A bill split across several categories cannot be received from the bill, so if any of it is stock you keep, add it under Stock with its cost."
    },
    "vendorSelector": {
      "searchPlaceholder": "Search suppliers or type a new name...",
      "searching": "Searching...",
      "noneMatching": "No supplier matches \"{query}\"",
      "noneYet": "No suppliers yet",
      "createNamed": "Use \"{name}\" as a new supplier",
      "createNew": "Create new supplier",
      "newTag": "(new)",
      "clear": "Change supplier",
      "profileTitle": "New supplier details",
      "vendorNameLabel": "Supplier / business name",
      "vendorNamePlaceholder": "Supplier name",
      "emailLabel": "Email (optional)",
      "phoneLabel": "Phone",
      "taxIdLabel": "Tax ID (optional)",
      "addressLabel": "Business address",
      "streetPlaceholder": "Street address",
      "cityPlaceholder": "City",
      "postalCodePlaceholder": "Postcode",
      "statePlaceholder": "State",
      "stateProvincePlaceholder": "State / province",
      "countryLabel": "Country"
    },
    "confirmError": {
      "notAwaitingReview": "This invoice is no longer waiting for review. Refresh the page and try again.",
      "amountsDoNotFoot": "This invoice's net amount and tax do not match its total, so it cannot be posted. Check the extracted data and correct the amounts.",
      "supplierInactive": "This affiliate's supplier is inactive, so the bill was not posted. Reactivate the supplier, then try again.",
      "connectorBillReadOnly": "This bill comes from a connected system, so its figures cannot be edited here. Confirm it as it is, or leave it held."
    },
    "settlement": {
      "title": "Groot recorded this as already paid",
      "intro": "Nobody typed this in. Groot read the payment off the document itself, so this purchase was recorded as paid on the spot and nothing is owed to the supplier.",
      "reasonsLabel": "What the document showed",
      "unnamed": "Plus {count, plural, one {# more payment detail} other {# more payment details}} Groot recorded but cannot name here.",
      "evidence": {
        "cashSalesMarker": "The document is printed as a cash sale.",
        "paymentMethodCash": "The payment line says cash.",
        "paymentMethodCard": "A card was charged at the till.",
        "paymentMethodWithReference": "A transfer or e-wallet payment, with the reference number the payment generated.",
        "amountTendered": "The document shows how much was handed over.",
        "zeroBalanceDue": "The balance due is printed as zero.",
        "paidStatusFlag": "The document is stamped paid.",
        "paymentMethodUnconfirmed": "A way to pay is named, but nothing shows the money moved.",
        "changeLinePresent": "There is a change line, the way a till receipt has.",
        "paymentTermsCash": "The payment terms say cash or cash on delivery.",
        "creditSaleMarker": "The document is printed as a credit sale.",
        "paymentTermsPresent": "The document has payment terms, so it is meant to be paid later.",
        "dueDatePresent": "The document has a due date.",
        "nonzeroBalanceDue": "There is still a balance due on the document.",
        "unpaidStatusFlag": "The document is stamped unpaid.",
        "partialPayment": "Only part of the total was paid, so the rest is still owed.",
        "conflictingEvidence": "The document says both paid and still owing.",
        "unreadableInput": "The document could not be read.",
        "noEvidence": "Nothing on the document showed a payment."
      }
    },
    "affiliate": {
      "hold": {
        "generic": "Groot could not post this bill yet.",
        "AFFILIATE_COMMISSION_ACCOUNT_NOT_CONFIGURED": "no Affiliate commission account is chosen.",
        "AFFILIATE_COMMISSION_ACCOUNT_NOT_COST_OF_SALES": "the Affiliate commission account must be a cost of sales account.",
        "CHART_OF_ACCOUNTS_NOT_CONFIGURED": "the accounts payable account could not be found.",
        "AFFILIATE_AP_NOT_ENABLED": "supplier bills are not enabled on this plan.",
        "AFFILIATE_OWNER_REQUIRED": "the owner who connected AffiliateWP is no longer an owner. Disconnect and connect it again as a current owner.",
        "AFFILIATE_SUPPLIER_INACTIVE": "this supplier is inactive. Reactivate it to bill.",
        "AFFILIATE_CURRENCY_MISMATCH": "the commission is not in your home currency.",
        "AFFILIATE_REFERRAL_AMOUNT_INVALID": "the commission has no amount to bill.",
        "AFFILIATE_REFERRAL_UNREADABLE": "AffiliateWP sent this referral in a shape Groot could not read.",
        "AFFILIATE_DETAILS_UNAVAILABLE": "the affiliate details could not be read from AffiliateWP.",
        "AFFILIATE_CONNECTION_REUSED": "this referral belongs to a previous store on this connection.",
        "PERIOD_CLOSED": "the accounting period is closed.",
        "POSTING_BEFORE_CONVERSION_DATE": "the date is before your conversion date."
      },
      "notBilled": {
        "waiting": "Waiting for approval",
        "notInGroot": "Order not in Groot",
        "held": "Held: {reason}",
        "failed": "Could not bill yet. It is tried again on the next check.",
        "rejectedAfterPosting": "Rejected in AffiliateWP after posting",
        "fix": "Open Payment & posting",
        "title": "Referrals not billed yet",
        "row": "Order #{order} · referral {id} · {amount}",
        "rejectedAfterPostingHint": "Groot does not reverse the bill. Review it under the supplier."
      },
      "markPaid": "Paid in Groot. Mark referral {id} paid in AffiliateWP.",
      "view": {
        "label": "Credit purchases view",
        "all": "All",
        "affiliates": "Affiliate commissions"
      },
      "source": "Commission for order #{order} · referral {referral}",
      "sourceNoOrder": "Commission for referral {referral}",
      "sourceUnknown": "Affiliate commission",
      "empty": "No affiliate commission bills yet",
      "emptyHint": "A bill appears here when AffiliateWP approves a referral.",
      "capped": "Showing the latest affiliate bills only."
    },
    "fx": {
      "label": "Exchange rate on the bill date",
      "needsDate": "Add the bill date to see its exchange rate.",
      "loading": "Looking up the exchange rate...",
      "unresolved": "There is no exchange rate for {currency} on {date}. Enter one here, or add it under Accounting → Chart of Accounts → Currencies & rates.",
      "unresolvedLink": "Open Currencies & rates",
      "rateInputPrefix": "1 {currency} =",
      "rateInputLabel": "Exchange rate: {home} per 1 {currency}",
      "useRate": "Use this rate",
      "yourRate": "Your rate · {date}",
      "needsRate": "Needs an exchange rate",
      "requiredError": "Enter an exchange rate to post this bill, or add one under Accounting → Chart of Accounts → Currencies & rates.",
      "postedAt": {
        "label": "Posted at",
        "pair": "{currency} 1 = {home} {rate}",
        "source": {
          "bnmUndated": "Bank Negara selling rate",
          "manual": "your own rate",
          "manualDated": "your own rate, {date}",
          "userOverride": "rate entered on the bill",
          "parentBill": "rate of the bill it adjusts",
          "bnmUndatedBuying": "Bank Negara buying rate",
          "userOverrideInvoice": "rate entered on the invoice",
          "parentInvoice": "rate of the invoice it adjusts"
        }
      },
      "needsDateBadge": "Needs a bill date",
      "needsAddonBadge": "Needs the multi-currency add-on",
      "clearRateFailed": {
        "title": "Could not go back to the automatic rate",
        "description": "The rate typed on this bill is still in place. Please try again."
      },
      "invoiceLabel": "Exchange rate on the invoice date",
      "invoiceNeedsDate": "Add the invoice date to see its exchange rate.",
      "invoiceRequiredError": "Enter an exchange rate to issue this invoice, or add one under Accounting → Chart of Accounts → Currencies & rates.",
      "saveCurrencyFirst": "Save the new currency to enter a rate for it.",
      "storedRateInvalid": "This rate is not valid. Enter a rate above zero."
    },
    "bulkReview": {
      "banner": "{count, plural, one {{shown} supplier invoice is waiting for your check.} other {{shown} supplier invoices are waiting for your check.}}",
      "review": "Review {shown}",
      "title": "Waiting for your check",
      "help": "Check what Groot read, then confirm the ones that are right. Invoices that need a fix first have no tick box.",
      "selectReady": "Select all ready ({count})",
      "selected": "{count} selected · {totals}",
      "confirmSql": "Confirm and send {count} to SQL Account",
      "confirmAutoCount": "Confirm and send {count} to AutoCount",
      "confirmPost": "Confirm and post {count}",
      "confirmTitle": "{count, plural, one {Confirm # supplier invoice?} other {Confirm # supplier invoices?}}",
      "confirmBody": "Total {totals}. These invoices will be posted to your books. A posted invoice is fixed one at a time.",
      "sendSql": "They will also be queued for SQL Account.",
      "sendAutoCount": "They will also be queued for AutoCount.",
      "posted": "{count, plural, one {Posted # invoice.} other {Posted # invoices.}}",
      "queuedSql": "{count, plural, one {Posted # invoice and queued it for SQL Account.} other {Posted # invoices and queued them for SQL Account.}}",
      "queuedAutoCount": "{count, plural, one {Posted # invoice and queued it for AutoCount.} other {Posted # invoices and queued them for AutoCount.}}",
      "partial": "Posted {done} of {total}. {left, plural, one {# needs} other {# need}} your attention.",
      "alreadyConfirmed": "{count} already confirmed.",
      "stockAdvisory": "{count, plural, one {# invoice went to Cost of Sales and nothing was received into stock.} other {# invoices went to Cost of Sales and nothing was received into stock.}}",
      "stale": "This invoice changed after you looked at it. Check it again.",
      "supplierMissing": "Add the supplier name first.",
      "supplierAmbiguous": "Pick the supplier first.",
      "evidenceOnly": "This document is GST evidence only. Open the invoice to check it.",
      "location": "Choose a Location first.",
      "gst": "Decide the GST first.",
      "gstRole": "An owner or finance admin must post this one.",
      "amounts": "Totals do not add up. Check the amount first.",
      "rate": "Needs an exchange rate.",
      "date": "Needs the bill date.",
      "fxAddon": "Needs the Multi-currency add-on. Check Currencies and rates.",
      "openInvoice": "Open invoice",
      "newSupplier": "New supplier",
      "credit": "Credit",
      "direct": "Paid already",
      "duplicate": "Possible duplicate",
      "unusualAmount": "Much larger than this supplier's usual (about {amount}).",
      "lhdnDiffers": "Differs from the LHDN e-invoice",
      "lhdnAgrees": "Matches the LHDN e-invoice",
      "tax": "Tax {amount}",
      "confidence": "Read confidence {percent}%",
      "due": "Due {date}",
      "fx": "{homeAmount} at {rate}",
      "truncated": "Showing up to 50 invoices from the review queue. More are waiting; review this page first.",
      "empty": "No invoices are waiting for your check here.",
      "loading": "Loading invoices waiting for your check…",
      "progress": "Confirming {done} of {total}…",
      "chatConfirm": "Confirm and post {count} waiting for review",
      "back": "Go back",
      "close": "Close",
      "readFailed": "Could not load invoices waiting for review. Close this panel and try again.",
      "correctionSql": "Once SQL Account has an invoice, use a credit note to correct it.",
      "correctionAutoCount": "Once AutoCount has an invoice, use a credit note to correct it.",
      "mergedDocument": "This file holds more than one invoice. Open it and confirm it is one invoice, or upload each invoice as its own file.",
      "mergedDocumentCount": "Groot read at least {count} invoices in this file. Open it and confirm it is one invoice, or upload each invoice as its own file."
    }
  },
  "x_feedback_0": {
    "sendFeedback": "Send Feedback",
    "typeLabel": "What kind of feedback?",
    "messageLabel": "Your feedback",
    "screenshotLabel": "Screenshot (optional)",
    "screenshotHint": "Attach a screenshot to help us understand the issue better",
    "submitAnonymously": "Submit anonymously",
    "cancel": "Cancel",
    "sending": "Sending...",
    "minCharsHint": "Please write at least {min} characters ({remaining} more needed)",
    "errorMinContent": "Please fill in the template with at least {min} characters of content",
    "errorMaxContent": "Message must be under {max} characters",
    "errorScreenshotTooLarge": "Screenshot is too large (max 2MB)",
    "errorSubmitFailed": "Failed to submit feedback"
  },
  "x_reports_0": {
    "howItWorks": {
      "title": "How Aging Reports Work",
      "intro": "Aging reports show how much your customers owe you (AR) or how much you owe vendors (AP), broken down by how long each amount has been outstanding.",
      "stepsHeading": "Steps",
      "step1Title": "Generate a report",
      "step1Desc": "Click \"Generate Report\", pick AR or AP, and select the reference date.",
      "step2Title": "Review debtor statements",
      "step2Desc": "Each month, individual statements are generated per customer. Review them before sending.",
      "step3Title": "Send statements to debtors",
      "step3Desc": "Select which debtors to notify and click \"Send\". They receive a professional PDF statement by email.",
      "step4Title": "Enable auto-send (optional)",
      "step4Desc": "After a few months, enable auto-send for trusted debtors to skip manual review.",
      "bucketsHeading": "Aging Buckets",
      "bucketCurrent": "Current",
      "bucket1to30": "1-30 Days",
      "bucket31to60": "31-60 Days",
      "bucket61to90": "61-90 Days",
      "bucket90plus": "90+ Days",
      "automationHeading": "Monthly Automation",
      "automationDesc": "On the 1st of each month, reports are automatically generated. Before sending statements, the system checks for unreconciled bank payments that might affect accuracy.",
      "goodToKnowHeading": "Good to Know",
      "goodToKnow1": "Reports use only outstanding balances (partially paid invoices show remaining amount)",
      "goodToKnow2": "Reports are stored for 12 months and can be re-downloaded anytime",
      "goodToKnow3": "AI insights highlight trends and concentration risks on consolidated reports",
      "goodToKnow4": "Settings can be configured in Business Settings → Reports"
    },
    "dialog": {
      "title": "Generate Aging Report",
      "description": "Select the report type and reference date",
      "reportTypeLabel": "Report Type",
      "arAging": "AR Aging (Receivables)",
      "apAging": "AP Aging (Payables)",
      "asOfDateLabel": "As of Date",
      "cancel": "Cancel",
      "generating": "Generating...",
      "generate": "Generate Report",
      "generationFailed": "Generation failed",
      "generateSuccess": "Report generated successfully",
      "generateError": "Failed to generate report"
    },
    "auditHowItWorks": {
      "title": "How the Audit Trail Works",
      "intro": "The audit trail is a read-only, chronological record of financial actions taken in your business, useful for compliance, reviews, and answering “who changed this?”.",
      "loggedHeading": "What gets logged",
      "loggedIntro": "Every key financial action is recorded automatically:",
      "logged1": "Expense claims: submitted, approved, rejected, and marked as paid",
      "logged2": "Invoices (AP): created, posted, payments recorded, and voided",
      "logged3": "Journal entries: created and posted",
      "logged4": "Vendors: added and updated",
      "logged5": "Sales invoices (AR): created, sent, and voided",
      "readOnlyHeading": "Read-only by design",
      "readOnlyDesc": "Entries cannot be edited or deleted from this screen. Each entry captures who performed the action, when, and the before/after details.",
      "visibilityHeading": "Who can see it",
      "visibilityDesc": "The audit trail is visible to business owners and Finance only. Other team members do not see this tab’s contents.",
      "retentionHeading": "Retention",
      "retentionDesc": "How long Groot keeps an audit event depends on what the event records. These are Groot’s current retention settings and may change.",
      "retentionAccounting": "Events that explain an accounting record, such as expense claims, invoices, journal entries, vouchers and accounting periods: kept for {years, plural, one {# year} other {# years}}.",
      "retentionOther": "Every other event, such as vendor changes and attendance: kept for {years, plural, one {# year} other {# years}}.",
      "retentionClosing": "After that, events are removed automatically. This is Groot’s own copy of the trail and does not replace the records you keep yourself."
    }
  },
  "x_vendorintel_0": {
    "alertType": {
      "perInvoice": "Price Increase",
      "trailingAverage": "Trailing Average Spike",
      "newItem": "New Charge Detected",
      "frequencyChange": "Billing Pattern Changed"
    },
    "severity": {
      "highImpact": "High Impact",
      "standard": "Standard"
    },
    "itemLabel": "Item: {item}",
    "previous": "Previous: {value}",
    "current": "Current: {value}",
    "newCharge": "New charge: {value}",
    "detected": "Detected {date}",
    "viewHistory": "View History",
    "dismiss": "Dismiss",
    "recommendedActions": "Recommended Actions",
    "priority": {
      "high": "high",
      "medium": "medium",
      "low": "low"
    },
    "markComplete": "Mark Complete",
    "feedbackPlaceholder": "Why is this not an issue? (optional)",
    "dialog": {
      "title": "Confirm Item Match",
      "description": "The system found a potential match for this item but isn't confident enough to auto-link. Please confirm if these are the same item.",
      "confidence": "Confidence:",
      "confidenceValue": "{score}%",
      "newItem": "New Item",
      "existingItem": "Existing Item",
      "confirmHint": "If confirmed, future invoices with this description will automatically link to the existing price history.",
      "differentItems": "Different Items",
      "sameItem": "Same Item"
    },
    "riskConcentration": {
      "label": "Concentration Risk",
      "tooltip": "Share of this business's posted supplier spend that goes to this supplier. Rated once 3 suppliers have posted bills: High above 50%, Medium above 25%.",
      "notRated": "Not rated until 3 suppliers have posted bills",
      "share": "{percent}% of posted spend",
      "band": {
        "low": "Low",
        "medium": "Medium",
        "high": "High"
      }
    }
  },
  "x_referral_0": {
    "settingUpCode": "Setting up your referral code...",
    "resellerProgram": "Reseller Program",
    "referralProgram": "Referral Program",
    "headerSubtitle": "Earn rewards by {mode, select, reseller {reselling} other {referring}} businesses to Groot Finance",
    "launchPromo": "Launch Promo",
    "promoFee": "2x {mode, select, reseller {reseller} other {referral}} fee, from RM {promoMin} (Starter Annual) to RM {promoMax} (Pro Annual) per deal",
    "promoLimit": "Limited to the first {limit} annual subscriptions. {remaining} left, first come, first served.",
    "viewFullDetails": "View full {programLabel} details",
    "earnTooltip": "Earn $ with referrals",
    "shareTitle": "Groot Finance Referral",
    "yourResellerCode": "Your Reseller Code",
    "yourReferralCode": "Your Referral Code",
    "copied": "Copied!",
    "copyCode": "Copy Code",
    "copyLink": "Copy Link",
    "share": "Share",
    "discountPrefix": "Applicable to annual plans only. Referred businesses get",
    "discountAmount": "RM {discount} off",
    "discountSuffix": ".",
    "stats": {
      "totalReferrals": "Total Referrals",
      "inTrial": "In Trial",
      "paying": "Paying",
      "estEarnings": "Est. Earnings"
    },
    "list": {
      "titleReferral": "Referred Businesses",
      "titleReseller": "Reseller Clients",
      "emptyReferral": "No referrals yet. Share your code to start earning!",
      "emptyReseller": "No clients yet. Share your code to start earning!",
      "earnHint": "Earn RM {min} (Starter) or RM {max} (Pro) for every annual subscription.",
      "pending": "Pending",
      "promoBadge": "2x",
      "promoSlotTitle": "Launch promo: 2x commission (slot {slot} of {limit})"
    },
    "status": {
      "signed_up": "Signed Up",
      "trial": "In Trial",
      "paid": "Paying",
      "upgraded": "Upgraded",
      "downgraded": "Downgraded",
      "churned": "Churned",
      "cancelled": "Cancelled",
      "expired": "Expired"
    },
    "standardRate": "Standard Rate",
    "standardFee": "RM {min} (Starter Annual) to RM {max} (Pro Annual) per deal",
    "promoClaimed": "All {limit} launch promo slots have been claimed."
  },
  "x_exports_0": {
    "fieldMapper": {
      "title": "Field Mapping",
      "description": "Select fields to include and customize their column names.",
      "addField": "Add Field",
      "emptyTitle": "No fields mapped yet.",
      "emptyHint": "Click \"Add Field\" to start building your export.",
      "selectField": "Select field",
      "columnName": "Column name",
      "moveUp": "Move up",
      "moveDown": "Move down",
      "removeField": "Remove field",
      "dateFormat": "Date Format",
      "decimalPlaces": "Decimal Places",
      "thousandsSeparator": "Thousands Separator",
      "separatorNone": "None (1234.56)",
      "separatorComma": "Comma (1,234.56)",
      "mappedCount": "{count} {count, plural, one {field} other {fields}} mapped",
      "availableCount": "{count} {count, plural, one {field} other {fields}} available"
    },
    "formatConfig": {
      "title": "Format Defaults",
      "description": "Configure default date and number formats for this export.",
      "dateFormat": "Date Format",
      "decimalPlaces": "Decimal Places",
      "decimalWhole": "Whole numbers (1234)",
      "decimalTwo": "2 decimals (1234.56)",
      "decimalFour": "4 decimals (1234.5678)",
      "numberFormatting": "Number Formatting",
      "noSeparator": "No separator (1234.56)",
      "commaSeparator": "Comma separator (1,234.56)"
    },
    "schedule": {
      "title": "Schedule Export",
      "subtitle": "Automatically run this export on a recurring basis.",
      "close": "Close",
      "exportTemplate": "Export Template",
      "selectTemplate": "Select a template",
      "prebuilt": "(Prebuilt)",
      "frequency": "Frequency",
      "daily": "Daily",
      "weekly": "Weekly",
      "monthly": "Monthly",
      "dayOfWeek": "Day of Week",
      "dayOfMonth": "Day of Month",
      "time": "Time",
      "timeNote": "All times are in UTC. Adjust for your local timezone.",
      "cancel": "Cancel",
      "creating": "Creating...",
      "createSchedule": "Create Schedule",
      "days": {
        "sunday": "Sunday",
        "monday": "Monday",
        "tuesday": "Tuesday",
        "wednesday": "Wednesday",
        "thursday": "Thursday",
        "friday": "Friday",
        "saturday": "Saturday"
      }
    },
    "filters": {
      "title": "Filters",
      "clear": "Clear",
      "dateRange": "Date Range",
      "selectPeriod": "Select period",
      "startDate": "Start Date",
      "endDate": "End Date",
      "status": "Status",
      "selectStatus": "Select status",
      "invoiceType": "Invoice Type",
      "allInvoicesPlaceholder": "All invoices",
      "allInvoices": "All Invoices",
      "invoiceAp": "AP (Purchases)",
      "invoiceAr": "AR (Sales)",
      "sourceType": "Source Type",
      "allSourcesPlaceholder": "All sources",
      "allSources": "All Sources",
      "sourceExpenseClaims": "Expense Claims",
      "sourceInvoices": "Invoices",
      "notExportedChip": "New only",
      "notExportedActive": "New only (not yet exported)",
      "notExportedHint": "Showing invoices not yet exported to SQL Accounting",
      "notExportedHintRuns": "Showing payment runs not yet exported to SQL Accounting",
      "datePresets": {
        "last7Days": "Last 7 days",
        "last30Days": "Last 30 days",
        "last90Days": "Last 90 days",
        "lastYear": "Last year",
        "customRange": "Custom range",
        "allTime": "All time"
      },
      "statusOptions": {
        "all": "All",
        "draft": "Draft",
        "submittedPending": "Submitted / Pending",
        "approved": "Approved",
        "rejected": "Rejected",
        "reimbursed": "Reimbursed",
        "cancelled": "Cancelled",
        "pending": "Pending",
        "paid": "Paid",
        "overdue": "Overdue",
        "disputed": "Disputed",
        "completed": "Completed",
        "sent": "Sent",
        "active": "Active",
        "inactive": "Inactive",
        "archived": "Archived",
        "finalized": "Finalized",
        "locked": "Locked"
      }
    },
    "codeMapping": {
      "loading": "Loading mappable values...",
      "title": "Map Codes for {system}",
      "description": "Enter the corresponding {system} codes for each item below. Saved codes will auto-fill on your next export.",
      "autoFill": "Auto-fill Groot codes",
      "defaultFallback": "Default (fallback):",
      "defaultPlaceholder": "e.g., 6099",
      "usedForUnmapped": "Used for unmapped items",
      "masterCodePlaceholder": "Master Acct code",
      "noValuesFound": "No values found in selected records for this mapping type. Set a default code above if needed.",
      "noTaxValuesFound": "No taxed lines found in the selected invoices. Add a tax code or rate mapping if you need one.",
      "skipMapping": "Skip mapping",
      "skipNoDefaults": "Skip (no defaults set)",
      "saving": "Saving...",
      "saveAndContinue": "Save & Continue",
      "typeLabels": {
        "accountCode": "Account Codes",
        "creditorCode": "Creditor/Supplier Codes",
        "debtorCode": "Debtor/Customer Codes",
        "bankCode": "Bank/Cash A/C Codes",
        "agentCode": "Agent Codes",
        "taxCode": "Tax Codes"
      },
      "typeDescriptions": {
        "accountCode": "Map Groot Finance categories to {system} Account Codes (e.g., 6001, 9017)",
        "creditorCode": "Map vendor names to {system} Creditor Codes (e.g., 4000-A0001)",
        "debtorCode": "Map customer names to {system} Debtor Codes (e.g., 3000-C0001)",
        "bankCode": "Map to {system} Bank/Cash A/C Codes (e.g., 3010-100)",
        "agentCode": "Map your sales agents to {system} Agent Codes (e.g., ASHLEY)",
        "taxCode": "Map Groot tax codes or rates to {system} Tax Codes (e.g., SR). Map each one explicitly."
      },
      "paymentMethodHint": "Start typing to pick from the {count} payment methods found in your SQL Account backup.",
      "addRow": "+ Add mapping",
      "pasteList": "Paste list",
      "pasteHint": "one per line: name, code (tab, | or last comma separates the code)",
      "pastePlaceholder": "TEO HIN SDN BHD,400-TEOHIN\nKLAS PLASTIC INDUSTRIES SDN BHD,400-K0001",
      "pasteApply": "Add pasted rows",
      "removeRow": "Remove row",
      "sourcePlaceholder": "Name / value in Groot",
      "excludeFromExport": "Exclude from export",
      "excluded": "Excluded",
      "includedInExport": "Include in export",
      "removeMapping": {
        "button": "Remove saved mapping",
        "confirmBody": "Remove the saved code {code} for {source}?",
        "confirmHint": "This row will use the default fallback code until you map it again. Nothing in your accounting software changes.",
        "confirmImportedHint": "This code came from your accounting software import, so you will need the real code again to map this row.",
        "confirmAction": "Remove mapping",
        "cancel": "Keep it",
        "removing": "Removing...",
        "errorNotAuthorized": "You do not have permission to remove a saved mapping. Ask the business owner or a finance admin to remove it on the Map Codes step.",
        "errorGeneric": "Could not remove this mapping. Nothing was changed, so you can try again."
      },
      "agentHint": "Start typing to pick from the {count} agents found in your SQL Account backup.",
      "bankCodePlaceholder": "Bank/Cash A/C code",
      "bankCodeDefaultPlaceholder": "e.g., 310-001",
      "agentCodePlaceholder": "Agent code",
      "agentCodeDefaultPlaceholder": "e.g., ASHLEY",
      "taxCodePlaceholder": "Tax code"
    }
  },
  "x_exports_1": {
    "common": {
      "cancel": "Cancel",
      "close": "Close"
    },
    "preview": {
      "loading": "Loading preview...",
      "noRecords": "No records match your current filters.",
      "noRecordsHint": "Try adjusting the date range or status filter.",
      "noRecordsNotExportedHint": "Records already exported are left out. Turn off New only in the filters to include them again.",
      "title": "Export Preview",
      "showing": "Showing {previewCount} of {totalCount} records",
      "generating": "Generating...",
      "exportRecords": "Export {count} Records",
      "masterDetailTitle": "MASTER/DETAIL Format",
      "masterDetailDescPrefix": "Each record produces a",
      "masterLabel": "MASTER",
      "masterDetailDescMiddle": "row (header) followed by one or more",
      "detailLabel": "DETAIL",
      "masterDetailDescSuffix": "rows (line items). Delimiter: semicolon (;)",
      "limitedNote": "Preview limited to {previewCount} records. Full export will include all {totalCount} records.",
      "fileLimitNote": "Preview limited to {previewCount} records. This file will carry the first {fileCount} of the {totalCount} records, the most one file can hold. Narrow the date range or filters and export again to get the rest.",
      "templateLabel": "Template:",
      "columnCount": "{count} columns",
      "yes": "Yes",
      "no": "No",
      "rowType": "Row Type",
      "col": "Col {num}",
      "moreDetailRows": "... {count} more detail rows",
      "notPostedClaims": "{count} of the {total} listed claims will be left out of this file: only approved or reimbursed claims are booked.",
      "notPaidClaims": "{count} of the {total} listed claims will be left out of this file: only reimbursed claims are booked, because an approved claim that is not paid yet has no payment.",
      "noAmount": {
        "noHomeFigure": "{count} of the {total} listed claims will be left out of this file because no home currency amount is on record for them: {names}{more, plural, =0 {} other { and # more}}. Open each claim and check its exchange rate under Accounting → Chart of Accounts / Exchange rates, or enter it in your accounting system by hand.",
        "approvalPostingShared": "{count} of the {total} listed claims will be left out of this file because each was approved in one posting with other claims, so its own amount is not recorded: {names}{more, plural, =0 {} other { and # more}}. Open each claim to see its approved amount, then enter it in your accounting system by hand.",
        "paymentNotProvable": "{count} of the {total} listed claims will be left out of this file because the amount paid for each cannot be confirmed from its own payment record: {names}{more, plural, =0 {} other { and # more}}. Open the claim to see when and how it was paid, then enter the payment in your accounting system by hand using the amount on your bank statement.",
        "noAmount": "{count} of the {total} listed claims will be left out of this file because they have no amount on record: {names}{more, plural, =0 {} other { and # more}}. Open the claim and check its amount.",
        "noBilledAmount": "{count} of the {total} listed claims will be left out of this file because Groot has no record of a bill export for them, so it cannot say what amount to reverse: {names}{more, plural, =0 {} other { and # more}}. If you imported a bill for one of them, raise the debit note in Master Accounting by hand for the amount on that bill."
      }
    },
    "templateList": {
      "emptyDefault": "No templates available",
      "prebuiltHeading": "Pre-built Templates",
      "customHeading": "Custom Templates",
      "fieldCount": "{count} fields",
      "cloneTemplate": "Clone template",
      "deleteTemplate": "Delete template"
    },
    "builder": {
      "validationError": "Validation error",
      "nameRequired": "Template name is required.",
      "moduleRequired": "Please select an export module.",
      "fieldMappingRequired": "At least one field mapping is required.",
      "duplicateColumnNames": "Two columns have the same name. Give each column its own name, then save again.",
      "updatedTitle": "Template updated",
      "updatedDescription": "Your template has been saved.",
      "createdTitle": "Template created",
      "createdDescription": "Your custom template is ready to use.",
      "updateFailed": "Failed to update template",
      "createFailed": "Failed to create template",
      "tryAgain": "Please try again.",
      "editTitle": "Edit Template",
      "createTitle": "Create Custom Template",
      "editSubtitle": "Update your export template configuration",
      "createSubtitle": "Build a custom export template with your own field mappings",
      "detailsCardTitle": "Template Details",
      "nameLabel": "Template Name *",
      "namePlaceholder": "e.g., Monthly Payroll Export",
      "moduleLabel": "Module *",
      "descriptionLabel": "Description (optional)",
      "descriptionPlaceholder": "Brief description of this template's purpose",
      "fieldMappingsCardTitle": "Field Mappings",
      "fieldMappingsCardDescription": "Select which fields to include and customize column names",
      "loadingFields": "Loading available fields...",
      "lineItemNote": "Line item fields selected. The export will produce one row per line item, with header-level fields repeated on each row.",
      "formatCardTitle": "Format Configuration",
      "formatCardDescription": "Set default formatting options for dates and numbers",
      "saving": "Saving...",
      "saveChanges": "Save Changes",
      "createTemplateButton": "Create Template"
    },
    "scheduleList": {
      "loading": "Loading schedules...",
      "emptyDefault": "No schedules configured",
      "daily": "Daily at {time}",
      "weekly": "Every {day} at {time}",
      "monthly": "Monthly on the {date} at {time}",
      "dayFallback": "Day",
      "overdue": "Overdue",
      "lessThanHour": "Less than an hour",
      "inHours": "In {count, plural, one {# hour} other {# hours}}",
      "inDays": "In {count, plural, one {# day} other {# days}}",
      "nextRun": "Next run: {value}",
      "enabled": "Enabled",
      "disabled": "Disabled",
      "deleteSchedule": "Delete schedule"
    },
    "moduleLabels": {
      "expense": "Expense Claims",
      "invoice": "Invoices",
      "leave": "Leave Records",
      "accounting": "Accounting Records",
      "masterData": "Master Data"
    },
    "daysOfWeek": {
      "sun": "Sun",
      "mon": "Mon",
      "tue": "Tue",
      "wed": "Wed",
      "thu": "Thu",
      "fri": "Fri",
      "sat": "Sat"
    },
    "deleteDialog": {
      "title": "Delete Template",
      "subtitle": "This action cannot be undone",
      "confirmPrefix": "Are you sure you want to delete the template",
      "warning": "All saved configuration and field mappings will be permanently removed.",
      "deleting": "Deleting...",
      "deleteButton": "Delete Template"
    }
  },
  "x_accounting_0": {
    "glClassification": {
      "title": "GL Classification",
      "reference": "Ref: {reference}",
      "debitAmount": "Debit: {amount}",
      "creditAmount": "Credit: {amount}",
      "aiSuggestion": "AI Suggestion",
      "confidence": "{percent}% confidence",
      "tierRules": "Rules",
      "tierAi": "AI",
      "tierUnknown": "Unknown",
      "unknownAccount": "Unknown account",
      "postedToGl": "Posted to GL as a journal entry",
      "overrideClassification": "Override Classification",
      "debitAccount": "Debit Account",
      "creditAccount": "Credit Account",
      "selectAccount": "Select account",
      "posting": "Creating draft...",
      "overrideAndPost": "Override and create draft",
      "cancel": "Cancel",
      "confirmAndPost": "Create draft journal",
      "override": "Override",
      "reject": "Reject",
      "errorPostToGl": "Failed to create draft journal",
      "errorReject": "Failed to reject classification",
      "errorOverride": "Failed to override classification",
      "errorSameAccount": "Debit and credit accounts must be different for a valid journal entry.",
      "grabPayoutTitle": "Grab payout",
      "grabPayoutDescription": "Grab reported this exact payout amount for this transfer date. Confirm to match this bank credit and immediately post it against Sales Settlement Clearing.",
      "settlementId": "Settlement ID",
      "transferDate": "Transfer date",
      "netTotal": "Net total",
      "store": "Store",
      "destinationBank": "Destination bank",
      "payoutStatus": "Status: {status}",
      "matchAndPostPayout": "Match and post",
      "matchingAndPostingPayout": "Matching and posting...",
      "errorMatchAndPostPayout": "Failed to match and post the Grab payout"
    },
    "reconSummary": {
      "title": "Reconciliation Summary",
      "export": "Export",
      "exportTitle": "Export reconciliation summary as CSV",
      "statementClosingBalance": "Statement closing balance",
      "calculatedBalance": "Calculated balance",
      "openingBalance": "Opening balance",
      "netMovement": "Net movement",
      "difference": "Difference",
      "balancesAgree": "Statement balance agrees with our calculation",
      "balancesDisagreeTitle": "Balances do not agree",
      "balancesDisagreeBody": "The statement closing balance is {difference} away from opening balance plus movements. A row may be missing, duplicated or mis-signed in the import.",
      "noStatementBalance": "This statement has no running balance column, so there is nothing to compare against.",
      "csvStatementClosingBalance": "Statement closing balance",
      "csvCalculatedBalance": "Calculated balance",
      "csvOpeningBalance": "Opening balance",
      "csvNetMovement": "Net movement",
      "csvDifference": "Difference",
      "totalReconciled": "Total Reconciled",
      "postedToGl": "Posted to GL",
      "remainingUnmatched": "Remaining Unmatched",
      "statusReconciled": "reconciled",
      "statusClassified": "classified",
      "statusPosted": "posted",
      "statusCategorized": "categorized",
      "statusUnmatched": "unmatched",
      "statusSuggested": "suggested",
      "allReconciled": "All transactions reconciled or posted",
      "awaitingAction": "{count, plural, one {# line still needs action: it is suggested, classified or labelled but not yet reconciled or posted} other {# lines still need action: they are suggested, classified or labelled but not yet reconciled or posted}}",
      "outstandingTotalling": "{count, plural, one {# outstanding item totalling} other {# outstanding items totalling}}",
      "outstandingItems": "Outstanding Items ({count})",
      "andMore": "... and {count} more",
      "csvDate": "Date",
      "csvDescription": "Description",
      "csvAmount": "Amount",
      "csvDirection": "Direction",
      "csvTitle": "RECONCILIATION SUMMARY",
      "csvBank": "Bank: {bankName} (****{last4})",
      "csvCurrency": "Currency: {currency}",
      "csvMetric": "Metric",
      "csvValue": "Value",
      "totalTransactions": "Total Transactions",
      "totalCredits": "Total Credits",
      "totalDebits": "Total Debits",
      "reconciled": "Reconciled",
      "classifiedAi": "Classified (AI)",
      "categorized": "Categorized",
      "unmatched": "Unmatched",
      "suggested": "Suggested",
      "unmatchedAmount": "Unmatched Amount",
      "progress": "Progress",
      "csvOutstandingItems": "OUTSTANDING ITEMS",
      "openingFromBooks": "From your books, before {date}",
      "unsureLines": "{n, plural, one {# line needs your decision (Groot was not sure)} other {# lines need your decision (Groot was not sure)}}",
      "unavailableLines": "{n, plural, one {# line could not be given a suggestion} other {# lines could not be given a suggestion}}"
    },
    "matchCandidates": {
      "statementStale": "The bank line changed. Open it and review the amount, date and account again.",
      "bankLinkUnresolved": "Choose the bank account and review its linked cash account.",
      "cashLegUnavailable": "This journal is not an effective posted cash movement. Review its posting or reversal.",
      "currencyReview": "The bank and cash-leg currencies cannot be compared safely. Review the currency.",
      "amountMismatch": "The posted cash-leg amount or direction differs from this bank line. Review both amounts.",
      "cashLegAlreadyMatched": "This posted cash leg is already matched to another bank line. Review that link first.",
      "cashLegReviewHold": "Only reviewed, effective cash legs can be matched here. Resolve incomplete Cash Book history or ambiguous journal legs before confirming.",
      "cashLegMatchRefused": "The cash leg changed or was already matched. Refresh and review the statement line again.",
      "title": "Smart Match Suggestions",
      "description": "Our system analyzed your accounting records and found these potential matches",
      "reference": "Ref: {reference}",
      "searchPlaceholder": "Search by description, vendor, reference...",
      "splitMode": "Split Mode",
      "splitModeTitle": "Split matching: match one bank transaction to multiple journal entries",
      "splitHint": "Select entries that together equal the bank transaction amount",
      "selectedLabel": "Selected:",
      "clear": "Clear",
      "confirmSplit": "Confirm Split ({count})",
      "noMatchesFound": "No matches found",
      "noMatchesHint": "Try adjusting the date range or manually categorize this transaction",
      "noSearchResults": "No results match your search",
      "match": "Match",
      "matchTitle": "Match this entry",
      "noDescription": "No description",
      "helpText": "Confidence scores are calculated based on amount, date proximity, reference numbers, and description similarity. Higher scores indicate stronger matches.",
      "strongMatch": "Strong Match",
      "likelyMatch": "Likely Match",
      "possibleMatch": "Possible Match"
    },
    "dashboard": {
      "cardReconciled": "Reconciled",
      "cardSuggested": "Suggested",
      "cardClassified": "Classified",
      "cardPosted": "Posted",
      "cardUnmatched": "Unmatched",
      "cardCategorized": "Categorized",
      "reconciliationProgress": "Reconciliation progress",
      "correctionBoundary": "Imported bank transactions remain unchanged. Unmatch a reconciled transaction before correcting its source payment; the payment workflow records the linked official reversal and then allows the replacement cash movement to be reconciled.",
      "totalCredits": "Total Credits",
      "totalDebits": "Total Debits",
      "openingBalance": "Opening Balance",
      "difference": "Difference",
      "csvStatementClosingBalance": "Statement closing balance",
      "csvCalculatedBalance": "Calculated balance",
      "csvNetMovement": "Net movement",
      "totalTransactions": "Total Transactions",
      "dateFrom": "From",
      "dateTo": "to",
      "dateToPlaceholder": "To",
      "clear": "Clear",
      "transactionCount": "{count, plural, one {# transaction} other {# transactions}}",
      "exportCsv": "Export CSV",
      "exportTitle": "Export reconciliation as CSV",
      "colDescription": "Description",
      "colDebit": "Debit",
      "colCredit": "Credit",
      "colBalance": "Balance",
      "colStatus": "Status",
      "emptyFiltered": "No {status} transactions",
      "emptyNoTransactions": "No transactions imported yet. Click \"Import Statement\" to begin.",
      "csvDate": "Date",
      "csvDescription": "Description",
      "csvReference": "Reference",
      "csvDebit": "Debit",
      "csvCredit": "Credit",
      "csvBalance": "Balance",
      "csvStatus": "Status",
      "csvCategory": "Category",
      "csvSummaryTitle": "RECONCILIATION SUMMARY",
      "statusName": {
        "unmatched": "unmatched",
        "suggested": "suggested",
        "reconciled": "reconciled",
        "categorized": "categorized",
        "classified": "classified",
        "posted": "posted"
      }
    },
    "batchActions": {
      "reviewRequired": "Review each bank line. Match an existing posted cash leg, or complete source and tax review before creating a new movement. Batch confirmation is on hold.",
      "label": "Batch Actions:",
      "confirmAll": "Confirm All High-Confidence ({count})",
      "postAll": "Post All to GL ({count})",
      "confirmResult": "Confirmed {confirmed} transactions, created {journalEntries} journal entries.",
      "confirmError": "Batch confirm encountered an error.",
      "postResult": "Posted {posted} transactions to GL.{errors, plural, =0 {} other { # errors.}}",
      "postError": "Batch post encountered an error."
    },
    "classifyErrors": {
      "transactionNotFound": "We couldn't find that transaction. Refresh the page and try again.",
      "noClassification": "This transaction hasn't been categorised yet, so there's nothing to confirm.",
      "payrollAlreadyExpensed": "These wages are already recorded as an expense by a pay run, so posting this would count them twice. Match this row to that pay run instead. If the pay run was accrued rather than paid, categorise it to the payroll payable account."
    },
    "payoutMatchErrors": {
      "bankAccountNotConfigured": "No bank account is configured for this business yet. Set one up in Payment & posting settings, then match this payout.",
      "alreadyMatched": "This bank transaction is already matched to something else.",
      "alreadyPosted": "This bank transaction has already been posted and cannot be matched again.",
      "amountMismatch": "The payout amount and the bank transaction amount do not match.",
      "wrongBusiness": "That bank transaction belongs to a different business.",
      "payoutAlreadyMatched": "This payout is already matched to a bank transaction.",
      "currencyMismatch": "The payout and the bank transaction are in different currencies.",
      "payoutNotFound": "That payout no longer exists. Refresh the page and try again."
    },
    "fxTrueUp": {
      "title": "Near match",
      "description": "You recorded this foreign payment with an estimated {homeCurrency} amount, and the bank took a slightly different amount.",
      "recordedVsStatement": "Recorded {recorded}, bank statement {statement}",
      "differenceLoss": "{amount} more than recorded (loss)",
      "differenceGain": "{amount} less than recorded (gain)",
      "matchedOnReference": "Matched on the payment reference",
      "matchedOnSupplier": "Matched on the supplier name",
      "action": "True up to {statement}",
      "acting": "Posting...",
      "helpLoss": "Posts the {amount} difference as a realised exchange loss and matches this line.",
      "helpGain": "Posts the {amount} difference as a realised exchange gain and matches this line.",
      "trueUpBadge": "Trued up",
      "appliedLoss": "{amount} more than recorded, posted as a realised exchange loss.",
      "appliedGain": "{amount} less than recorded, posted as a realised exchange gain.",
      "incomplete": "The search for near matches did not finish, so some payments may not be shown.",
      "errors": {
        "stale": "The difference changed since you reviewed it. The figures are updated, so please check them and try again.",
        "alreadyApplied": "This payment has already been trued up to a bank line.",
        "notEligible": "Only a foreign supplier payment recorded with an estimated amount can be trued up.",
        "noDifference": "The statement amount now equals the recorded payment, so you can match it directly.",
        "outOfWindow": "The statement amount is too far from the recorded payment to be the same payment.",
        "humanRequired": "A bank true-up has to be confirmed by a person in the app.",
        "noOpenPeriod": "There is no open accounting period to post this in. Open a period and try again.",
        "beforeConversion": "This date is before your opening balances start, so it cannot be posted.",
        "notThisBank": "This payment was not made from this bank account, so it cannot be trued up here.",
        "bankUnsupported": "A true-up needs a bank account in your home currency that is linked to your chart of accounts.",
        "reviewFirst": "This payment has been trued up and reversed too many times. Review it before trying again.",
        "generic": "The true-up could not be posted. Nothing was changed. Please try again.",
        "postingAccountNotConfigured": "Choose the realised exchange gain and loss accounts under Accounting > Payment & posting, then try again.",
        "paymentNotInWindow": "This payment is too far in time from the bank line to be the same payment. Choose a payment dated close to the statement line.",
        "notCorroborated": "Nothing links this payment to the bank line: its reference or the supplier's name should appear in the statement line. Check that it is the right payment."
      },
      "payFromLine": {
        "action": "Pay a bill from this line",
        "hint": "Choose a foreign-currency supplier bill. The bank amount sets the {homeCurrency} amount of the payment."
      }
    }
  },
  "x_accounting_1": {
    "bankAccountsTitle": "Bank Accounts",
    "noGlLink": "No GL link",
    "glPrefix": "GL: {name}",
    "transactionCount": "{count, plural, one {# transaction} other {# transactions}}",
    "lastImport": "Last import: {date}",
    "editBankAccount": "Edit Bank Account",
    "addBankAccount": "Add Bank Account",
    "bankNameLabel": "Bank Name",
    "bankNamePlaceholder": "e.g., Maybank, CIMB",
    "accountNumberLabel": "Account Number",
    "accountNumberPlaceholder": "e.g., 1234567890",
    "currencyLabel": "Currency",
    "nicknameLabel": "Nickname (optional)",
    "nicknamePlaceholder": "e.g., Operating Account",
    "glAccountLabel": "GL Account (Cash at Bank)",
    "selectGlAccountOption": "Select GL Account",
    "glAccountHelp": "Link to the Cash at Bank account in your chart of accounts for automatic GL posting.",
    "glAccountNoLongerPostable": "Linked to an account that can no longer take postings. Pick another one.",
    "glAccountNoneAvailable": "No bank accounts in your chart of accounts are available to link. An owner or finance admin can add one under Accounting.",
    "addFromChartHeading": "Add a bank account from your chart",
    "addFromChartHelp": "These are the bank accounts already in your chart of accounts. Pick one and Groot sets it up for reconciliation using the name and code that are already there. Nothing to retype.",
    "addFromChartAction": "Use this",
    "addFromChartAria": "Use {code} {name} as a bank account to reconcile",
    "addFromChartNoneLeft": "Every bank account in your chart is already available here. To add another bank, add a sub-account under your bank heading in the chart of accounts.",
    "accountNumberOptionalLabel": "Statement account number (optional)",
    "accountNumberMissing": "No account number yet",
    "bankNameFromChart": "The name comes from your chart of accounts, so it is not asked for here. Rename the account in the chart to change it.",
    "updateButton": "Update",
    "addAccountButton": "Add Account",
    "cancelButton": "Cancel",
    "categoryBankCharges": "Bank Charges",
    "categoryInterest": "Interest",
    "categoryNonBusiness": "Non-Business",
    "categoryOther": "Other",
    "tierRules": "Rules",
    "tierAi": "AI",
    "refPrefix": "Ref: {reference}",
    "drLabel": "DR",
    "crLabel": "CR",
    "journalEntryFallback": "Journal entry",
    "confidenceHigh": "high",
    "confidenceMedium": "medium",
    "confidenceLow": "low",
    "glDraftRecovery": "Draft journal · reject this classification to discard the draft before choosing a new route",
    "glPosted": "GL Posted",
    "postToGl": "Create draft journal",
    "rejectClassification": "Reject classification",
    "confirmMatch": "Confirm match",
    "rejectMatch": "Reject match",
    "findMatch": "Find match",
    "categorize": "Categorize",
    "unmatch": "Unmatch",
    "uncategorize": "Uncategorize",
    "doneStatus": "Done",
    "bankAccountForeignCurrencyNotice": "This account is in {accountCurrency} but your books are in {homeCurrency}. You will need a {accountCurrency} to {homeCurrency} exchange rate for each transaction date before these transactions can post to your ledger. Add rates on Accounting → Chart of Accounts.",
    "bankAccountSaveError": "Could not save this bank account. Check the details and try again.",
    "bankAccountErrors": {
      "notFound": "We couldn't find that bank account. Refresh the page and try again.",
      "unsupportedCurrency": "That currency isn't supported yet, so balances on this account couldn't be shown or converted. Pick one of the listed currencies.",
      "notABankLeaf": "That account is not one of the bank accounts in your chart, so a bank account cannot be linked to it. Pick one of the listed bank accounts.",
      "alreadyLinked": "That ledger account is already linked to another bank account. Two bank accounts sharing one ledger account cannot be reconciled separately. Pick a different account."
    },
    "bankCashScope": {
      "marked": "{code} {name} is now set up as a bank account in your chart, so it will appear in Bank / Cash.",
      "needsRepairTitle": "{code} {name} will not appear in Bank / Cash yet",
      "needsRepairBody": "The bank account is linked and reconciliation works as usual. Bank / Cash will not show this account until it is reviewed and repaired. Contact support to arrange this.",
      "reasonHistory": "It already has journal entries, so its chart setup was not changed automatically.",
      "reasonOtherSubtype": "Its chart subtype is set to something other than bank or cash, so it was left as it is.",
      "reasonDesignated": "It is already used as another posting account in Payment & posting, so it was left as it is.",
      "dismiss": "Dismiss"
    }
  },
  "x_admin_0": {
    "agentRollouts": {
      "title": "Agent rollouts",
      "subtitle": "Stage engine releases by tenant and stop a candidate immediately.",
      "saved": "Rollout saved",
      "failed": "The rollout change failed",
      "overrideSaved": "Tenant assignment saved",
      "rolledBack": "Rollout stopped",
      "promoted": "Candidate promoted",
      "rollbackConfirm": "Stop candidate traffic and shadow runs for this surface?",
      "stable": "Stable release",
      "candidate": "Candidate release",
      "percent": "Canary %",
      "shadow": "Safe shadow mode",
      "shadowDisabledReason": "Shadow runs are off for Autopilot. A second run could repeat the agent's actions, so this stays disabled until the agent can run without side effects.",
      "candidateEmpty": "No candidate",
      "candidateHint": "Only releases with a distinct runner physically included in this build can be selected.",
      "retiredStable": "{stored} (retired; serving the default {served}). Saving writes {served}.",
      "retiredCandidate": "Stored candidate release {stored} is retired and is not served. Saving clears it.",
      "reason": "Required audit reason",
      "save": "Save rollout",
      "promote": "Promote candidate",
      "promoteConfirm": "Make the candidate the stable release for this surface?",
      "rollback": "Fast rollback",
      "tenantTitle": "Tenant assignment",
      "chooseTenant": "Choose a tenant",
      "inherit": "Use cohort assignment",
      "apply": "Apply",
      "telemetry": "Recent telemetry",
      "tenant": "Tenant",
      "version": "Served release",
      "runs": "Runs",
      "errors": "Errors",
      "latency": "Avg latency",
      "shadowTelemetry": "Shadow run / skipped / failed",
      "diffs": "Mismatches",
      "noTelemetry": "No rollout telemetry yet.",
      "noAssignments": "No tenant overrides for this surface.",
      "recentDiffs": "Recent shadow differences",
      "shadowOff": "Shadow comparison is off, so nothing was compared.",
      "rollbackOnlyHint": "Emergency rollback releases can be the stable release but are never offered as a candidate.",
      "summaryNoCandidate": "Every business is on {stable}. No candidate.",
      "summaryCandidate": "{percent}% of businesses are trying {candidate}; the rest are on {stable}.",
      "summaryCandidateIdle": "{candidate} is set as the candidate at 0%, so every business is still on {stable}.",
      "summaryCandidateAll": "Every business is trying {candidate} (100%). The stable release is {stable}.",
      "summaryOverrides": "Businesses pinned by hand: {count} (listed under Tenant assignment).",
      "confirmTitle": "Change which engine businesses use?",
      "confirmAll": "Every business moves to {release}.",
      "confirmBack": "Every business moves back to {release}.",
      "confirmClearIdle": "Every business stays on {release}. The candidate is removed.",
      "confirmCandidateIdle": "No business moves to {candidate} yet (0%). Every business is on {stable}.",
      "confirmPercent": "About {percent}% of businesses move to {candidate}. The rest are on {stable}.",
      "confirmNextMessage": "This takes effect on the next message each business sends.",
      "confirmAction": "Yes, change it",
      "confirmCancel": "Cancel",
      "rollbackOnlyCandidate": "{release} cannot be a candidate. Set it as the stable release to roll back to it.",
      "rollbackOnlyCandidateStored": "The stored candidate, {stored}, cannot be a candidate. Saving clears it."
    },
    "agentScorecard": {
      "title": "Agent scorecard",
      "subtitle": "Is the agent doing its job? The last 8 weeks. Weeks start on Monday (UTC).",
      "refresh": "Refresh",
      "loading": "Loading the scorecard",
      "loadFailed": "The scorecard could not be loaded. Try again in a moment.",
      "internalRule": "A business is tagged internal when it is a demo workspace or when one of its owners is Groot staff. Every other business is a customer.",
      "runNote": "A run is a conversation's latest Autopilot run, counted in the week its first run started.",
      "truncatedNotice": "Some sources hit their read limit, so the oldest weeks may be undercounted: {sources}.",
      "sourceRuns": "runs",
      "sourceThumbs": "thumbs",
      "sourceProposals": "write proposals",
      "sourceMetrics": "turn counters",
      "sourceBusinesses": "business lookups",
      "kindCustomer": "Customer",
      "kindInternal": "Internal",
      "reasonDemo": "Demo workspace",
      "reasonStaff": "Owned by Groot staff",
      "audienceTitle": "Customers and internal use",
      "audienceCustomers": "Customers",
      "audienceInternal": "Internal",
      "outcomeTitle": "Task outcome",
      "outcomeHelp": "Success rate is done divided by done, error and stuck. Waiting runs stopped to ask something and are not counted. Stuck means still running with no update for 15 minutes.",
      "speedTitle": "Speed",
      "speedHelp": "Run duration (start to last update) covers the whole conversation, including time spent waiting for a reply. Turn time is the server time of one reply.",
      "writesTitle": "Writes",
      "writesHelp": "Changes the agent proposed for a person to confirm.",
      "thumbsTitle": "Thumbs",
      "recentDownTitle": "Recent thumbs down",
      "adoptionTitle": "Adoption",
      "adoptionHelp": "Businesses with at least one run in the week.",
      "byBusinessTitle": "By business",
      "colWeek": "Week of (Monday, UTC)",
      "colRuns": "Runs",
      "colDone": "Done",
      "colError": "Error",
      "colWaiting": "Waiting",
      "colSuperseded": "Superseded",
      "colRunning": "Running",
      "colStuck": "Stuck",
      "colSuccess": "Success rate",
      "colMeasured": "Done runs",
      "colP50": "Run duration p50",
      "colP90": "Run duration p90",
      "colTurns": "Turns",
      "colAvgTurn": "Avg turn time",
      "colProposed": "Proposed",
      "colExecuted": "Executed",
      "colCancelled": "Cancelled",
      "colExpired": "Expired",
      "colFailed": "Failed",
      "colOpen": "Open",
      "colUp": "Thumbs up",
      "colDown": "Thumbs down",
      "colCustomers": "Customers",
      "colInternal": "Internal",
      "colBusinesses": "Businesses",
      "colBusiness": "Business",
      "colType": "Type",
      "noRuns": "No agent runs in the last 8 weeks.",
      "noThumbsDown": "No thumbs down in this period.",
      "noGoal": "No goal recorded",
      "noBusinesses": "No activity in this period.",
      "conversationLabel": "Conversation"
    },
    "tools": {
      "feeClassification": "Fee Classification",
      "bankRecon": "Bank Recon",
      "arMatching": "AR Matching",
      "poMatching": "PO Matching",
      "vendorItems": "Vendor Items",
      "chatIntent": "Chat Intent",
      "chatToolSelect": "Chat Tool Select",
      "chatParams": "Chat Params"
    },
    "costPanel": {
      "title": "Cost & Efficiency",
      "tooltipIntro": "Tracks AI costs and efficiency metrics for classification tools.",
      "tier1Label": "Tier 1",
      "tier1Desc": "= free rule-based matching (no AI cost).",
      "tier2Label": "Tier 2",
      "tier2Desc": "= AI/LLM classification (costs money but handles edge cases).",
      "total": "Total: {cost}",
      "colBusiness": "Business",
      "colTier1Rate": "Tier 1 Rate",
      "colTier2Calls": "Tier 2 Calls",
      "colEstCost": "Est. Cost",
      "colAccuracy": "Accuracy",
      "colCostPerCorrect": "Cost/Correct",
      "tier1RateTooltip": "% of cases handled by free rule-based logic (no AI cost). Higher = more cost-efficient.",
      "tier2CallsTooltip": "Number of AI/LLM calls (these cost money). Tier 2 handles edge cases that rules can't.",
      "estCostTooltip": "Estimated Gemini API cost based on token usage (input: $0.25/M, output: $1.50/M)",
      "accuracyTooltip": "% of classifications that didn't need manual override. Higher = AI is doing better.",
      "costPerCorrectTooltip": "Cost per correct classification (lower = more efficient). As accuracy improves, this should decrease."
    },
    "dashboard": {
      "window24h": "24h",
      "window7d": "7 days",
      "window30d": "30 days",
      "allBusinesses": "All Businesses",
      "searchPlaceholder": "Search businesses...",
      "businessCount": "{count} businesses",
      "noBusinessesMatch": "No businesses match \"{search}\"",
      "correctionsCount": "{count} corrections",
      "classificationsCount": "{count} classifications",
      "noActivity": "No activity",
      "loading": "Loading DSPy metrics...",
      "emptyTitle": "No DSPy Metrics Yet",
      "emptyDescription": "Metrics will appear here once DSPy tools are used. This includes chat corrections, fee classification, bank reconciliation, AR/PO matching, and vendor item matching.",
      "heading": "DSPy Observability",
      "subheading": "Is DSPy making our AI smarter, or just burning Gemini credits?",
      "refresh": "Refresh"
    },
    "businessDetail": {
      "back": "Back",
      "noDetailedMetrics": "No detailed metrics available for {businessName}.",
      "correctionProgress": "Correction Progress → BootstrapFewShot",
      "active": "Active",
      "legendAvgConfidence": "Avg Confidence %",
      "legendDspyConfidence": "DSPy Confidence %",
      "legendBaseConfidence": "Base Confidence %",
      "statTotal": "Total",
      "statOverrides": "Overrides",
      "statRefineRetries": "Refine Retries",
      "statFallbacks": "Fallbacks"
    },
    "selfImprovement": {
      "active": "Active",
      "title": "Self-Improvement: Correction Funnels",
      "tooltipHeading": "How Corrections Work",
      "tooltipPara1": "When you click thumbs-down in the chat or override an AI classification, your correction is stored here.",
      "tooltipPara2": "After 20 corrections per tool, BootstrapFewShot retrains the model weekly using your feedback as examples.",
      "tooltipPara3": "The AI learns from your corrections and gets smarter over time. No manual retraining needed!",
      "subtitle": "BootstrapFewShot activates after 20 corrections per tool. Higher bar = closer to self-improving AI.",
      "defaultTooltip": "Correction count for this tool",
      "activeMessage": "✓ Active: Model is now using your {count} corrections to self-improve!",
      "neededMessage": "{count} more corrections needed to activate BootstrapFewShot",
      "confidenceComparison": "Confidence: Base vs BootstrapFewShot",
      "baseLabel": "Base:",
      "baseTooltip": "Original AI confidence without your corrections",
      "dspyLabel": "DSPy:",
      "dspyTooltip": "AI confidence after learning from your corrections",
      "greenDelta": "Green delta = AI improved after training on your feedback!",
      "baseValue": "Base: {value}",
      "dspyValue": "DSPy: {value}",
      "toolShort": {
        "fees": "Fees",
        "bank": "Bank",
        "ar": "AR",
        "po": "PO",
        "vendor": "Vendor",
        "receipt": "Receipts",
        "invoice": "Invoices",
        "docClass": "Doc Class"
      },
      "toolTooltip": {
        "classifyFees": "Corrections from fee breakdown classification (manual overrides when AI misclassifies expense line items)",
        "classifyBankTransaction": "Corrections from bank transaction reconciliation (overrides when AI matches wrong transactions)",
        "matchOrders": "Corrections from AR matching (overrides when AI matches sales orders to wrong invoices)",
        "matchPoInvoice": "Corrections from PO matching (overrides when AI matches purchase orders to wrong invoices)",
        "matchVendorItems": "Corrections from vendor item matching (overrides when AI matches wrong vendor items)",
        "receiptExtraction": "Receipt-extraction corrections are user fixes to OCR-extracted receipt fields. Wired to the flywheel (#747): trains the combined receipt extractor.",
        "invoiceExtraction": "Invoice-extraction corrections are captured for training, but the invoice trainer hasn't been built yet.",
        "documentClassification": "Corrections here TRAIN the email-forward document classifier (receipt vs invoice): few-shot examples deploy back to the live classifier bi-weekly. Gate: 20 pooled corrections."
      },
      "captureOnlyBadge": "capture-only",
      "pooledBadge": "pooled",
      "captureOnlyMessage": "{count} corrections captured. No trainer consumes these yet, so the volume is shown for honesty, not training progress.",
      "pooledMessage": "The {threshold}-correction gate is pooled across ALL businesses; this bar shows only this tenant's share."
    },
    "healthOverview": {
      "noData": "No data",
      "degraded": "Degraded",
      "healthy": "Healthy",
      "title": "Health Overview",
      "tooltipPara1": "Shows performance metrics for classification tools (fee classification, bank recon, AR/PO matching, vendor items).",
      "tooltipPara2": "Chat tools show \"No data\" here because they don't run classifications - they only collect corrections via thumbs-down feedback.",
      "tooltipPara3": "Classifications = number of times the AI tool ran (e.g., classifying a fee, matching an invoice)",
      "degradedCount": "{count} degraded",
      "classificationsCount": "{count} classifications",
      "conf": "Conf: {value}",
      "confTooltip": "Average confidence score (0-100%). Higher = AI is more certain about its classifications.",
      "latency": "Latency: {value}",
      "latencyTooltip": "Average time for AI to complete classification. Lower is better.",
      "retry": "Retry: {value}",
      "retryTooltip": "How often the AI had to retry due to constraint violations (e.g., invalid format, missing required fields). Lower is better."
    },
    "flywheelHistory": {
      "title": "Flywheel History",
      "subtitle": "What the flywheel learned and what fired: model versions, optimizer runs, and async training jobs (platform-wide).",
      "jobsTitle": "Async training jobs",
      "jobsTooltip": "Each submitted training (ADR-0036): pending → settling → completed, failed, or stale. Failed and stale jobs consume no corrections.",
      "runsTitle": "Optimizer runs",
      "runsTooltip": "Every optimization attempt with before → after accuracy. A rejected run keeps the previous model and preserves its corrections.",
      "versionsTitle": "Model versions",
      "versionsTooltip": "The trained model lineage per domain. Active/promoted models serve live traffic; superseded and failed versions are kept for rollback.",
      "noJobs": "No trainings submitted yet.",
      "noRuns": "No optimizer runs yet.",
      "noVersions": "No model versions yet.",
      "colDomain": "Domain",
      "colStatus": "Status",
      "colCorrections": "Corrections",
      "colSubmitted": "Submitted",
      "colOutcome": "Outcome",
      "colPlatform": "Domain / key",
      "colAccuracy": "Accuracy",
      "colExamples": "Examples",
      "colWhen": "When",
      "colVersion": "Version",
      "trainVal": "{total} ({train} train / {val} eval)",
      "promotedTag": "✓ promoted",
      "trainLabel": "train",
      "evalSize": "{count} eval",
      "promptHashTitle": "Prompt fingerprint {hash}: identifies the exact prompt text this accuracy was measured on",
      "evalUnknown": "eval size n/a",
      "evalTooltip": "Held-out eval-set size behind this accuracy figure.",
      "smallEvalTooltip": "Small eval set: accuracy is measured on a deterministic tail split of under 10 examples. Treat this figure as directional, not statistical."
    },
    "modelPromotions": {
      "title": "Model Promotions",
      "subtitle": "Tenant models promote automatically after evaluation. This queue is only for deliberately shared candidates and live-model rollback.",
      "pendingTitle": "Pending approval",
      "pendingTooltip": "Only explicitly shared candidates wait here. Review their evidence and scope before allowing cross-tenant use.",
      "noPending": "No model versions are waiting for approval.",
      "activeTitle": "Live models",
      "activeTooltip": "The model currently serving traffic for each domain. Roll back to the immediately prior version if a promotion turns out to be wrong.",
      "noActive": "No live models yet.",
      "colDomain": "Domain / key",
      "colVersion": "Version",
      "colAccuracy": "Accuracy",
      "colExamples": "Examples",
      "colTrainedAt": "Trained",
      "colActions": "Actions",
      "approve": "Approve",
      "reject": "Reject",
      "rollback": "Roll back to v{version}",
      "reasonPlaceholder": "Reason (required)",
      "reasonRequired": "Enter a reason before you approve, reject, or roll back a model.",
      "approveConfirm": "Promote v{version} ({platform}) to live for every tenant?",
      "rejectConfirm": "Reject v{version} ({platform})? The current live model keeps serving.",
      "rollbackConfirm": "Roll {platform} back from v{fromVersion} to v{toVersion}?",
      "approveSuccess": "v{version} is now live for {platform}.",
      "rejectSuccess": "v{version} was rejected.",
      "rollbackSuccess": "{platform} rolled back to v{version}.",
      "actionError": "Couldn't complete that action. Please try again.",
      "noRollbackTarget": "No prior version to roll back to.",
      "reasonTitle": "Promotion decision",
      "conditionsTitle": "Safety conditions",
      "policyVersion": "Policy version {version}",
      "decidedAt": "Decided {when}",
      "firstFailing": "First failing condition: {condition}",
      "firstUnverifiable": "First unverifiable condition: {condition}",
      "observedRequired": "{observed} (required: {required})",
      "scopeTenant": "Tenant-isolated",
      "scopeShared": "Shared",
      "scopeNote": "{applicable} of {total} checks apply to this scope; the rest are not evaluated.",
      "evidenceExamples": "{training} training, {evaluated} evaluated",
      "evidenceContributors": "{count} contributor(s)",
      "evidenceContributorsTruncated": "Contributor sample truncated",
      "healthTitle": "Live model health",
      "healthMonitored": "Monitored since promotion ({signals})",
      "healthUnmonitored": "Not monitored",
      "rollbackTrail": "Rolled back from v{fromVersion} to v{toVersion} ({trigger})",
      "rollbackTrailTitle": "Automatic rollback",
      "rollbackWhen": "Rolled back {when}",
      "rollbackMeasurement": "Measured {observed}, limit {threshold}",
      "statusPass": "Passed",
      "statusFail": "Failed",
      "statusAbsent": "Could not be checked",
      "statusNotApplicable": "Not applicable",
      "statusNotRecorded": "Not recorded",
      "condAccuracyImproved": "Accuracy improved",
      "condEvalFloor": "Enough evaluated examples",
      "condTrustedProvenance": "Trusted correction provenance",
      "condSampleSize": "Adequate sample size",
      "condTenantDiversity": "Tenant diversity",
      "condContributorCap": "No single tenant dominates",
      "condHoldoutIndependence": "Independent holdout",
      "condPerClassRegression": "No per-class regression",
      "condProtectedCohortRegression": "No protected-cohort regression",
      "condMonitoringAvailable": "Monitoring available"
    },
    "portalHints": {
      "title": "Portal hint learning",
      "subtitle": "What the e-invoice flywheel has learned about merchant portals, and the reason each lesson was promoted. A global hint reaches every tenant, so it can be withdrawn here without waiting for the next optimizer run.",
      "empty": "Nothing has been promoted yet. A hint is recorded once labelled outcomes from at least five distinct portals agree.",
      "readOnly": "You can read this ledger but not act on it. Withdrawing a hint needs the manage DSPy promotions capability.",
      "hintLabel": "Hint text",
      "noVersion": "No recorded version for this artifact.",
      "withdraw": "Withdraw",
      "withdrawHint": "Stop serving this hint on the next claim. The artifact stays in storage as evidence.",
      "reinstate": "Reinstate",
      "restoreVersion": "Restore {version}",
      "reasonCode": "Reason",
      "reasonLabel": "Reason for withdrawing this hint",
      "reasonPlaceholder": "What went wrong, and how you know",
      "reasonRequired": "Enter a reason before you withdraw, restore, or reinstate a hint.",
      "policyVersion": "Policy version {version}",
      "statusLive": "Serving",
      "statusRevoked": "Withheld",
      "statusAbsent": "Not checked",
      "statusFailed": "Failed",
      "absentMeans": "This check could not run. It is not a pass, and it does not block on its own: an absent verdict needs review.",
      "revokedByStaff": "Withdrawn by staff",
      "revokedByMonitor": "Withdrawn automatically",
      "revocationEvidence": "Helped {helped}, not helped {notHelped}, over {windowDays} days.",
      "evidenceTruncated": " A capped sample is stored, not the full list.",
      "observedRequired": "Observed {observed}, required {required}",
      "tierGlobal": "Global",
      "tierQuirk": "Quirk",
      "tierPortal": "Portal",
      "actionError": "Couldn't complete that action. Please try again.",
      "actionErrorCapability": "You no longer hold the capability this action needs.",
      "actionErrorNotFound": "That version is no longer recorded.",
      "withdrawSuccess": "Withheld {key}. It stops reaching prompts on the next claim.",
      "reinstateSuccess": "Reinstated {key}.",
      "restoreSuccess": "Restored {version} for {key}.",
      "conditions": {
        "condEvidenceIndependence": "Independent portals",
        "condHintTextRecorded": "Hint text recorded",
        "condNotRefutedByDecay": "Still helping",
        "condNoTenantDataVerified": "No buyer values",
        "condQualityGate": "Quality gate"
      },
      "notApplicable": {
        "noHintTier": "No hint tier has this evidence by design. A promoted hint is judged by labelled outcomes, not by an eval set. This is not a missing check."
      },
      "reasonCodes": {
        "staff_withdrew": "Staff withdrew it",
        "regression_hint_not_helping": "Hint stopped helping",
        "regression_cross_tenant": "Cross-tenant regression",
        "wrong_portal_attribution": "Attributed to the wrong portal",
        "contains_unacceptable_instruction": "Contains an unsafe instruction",
        "manual_override": "Manual override",
        "stale_no_recent_evidence": "No recent evidence it still helps"
      }
    }
  },
  "x_ap_howitworks": {
    "title": "How Full AP Management Works",
    "agingHeading": "Vendor aging & spend analytics",
    "agingDesc": "See what you owe each vendor, bucketed by how overdue it is, plus spend trends and top-vendor breakdowns so you can prioritise payments and spot cost creep.",
    "paymentsHeading": "Recording payments",
    "paymentsDesc": "Record a payment against a posted supplier invoice. Groot writes the double-entry journal (Dr AP, Cr Cash) and updates the invoice's outstanding balance automatically.",
    "matchingHeading": "3-way matching",
    "matchingDesc": "Match purchase orders, goods-received notes, and supplier invoices so you only pay for what was ordered and received. Mismatches are surfaced before money leaves the business.",
    "boundaryHeading": "What's included on your plan",
    "boundaryDesc": "Capturing and reviewing incoming supplier documents and managing vendors stays available on every plan. The full-AP depth (aging, payments, purchase orders, goods-received and matching) is part of the Pro tier. Contact support to upgrade."
  },
  "x_ar_howitworks": {
    "title": "How Full AR Management Works",
    "debtorsHeading": "Customers & debtor ledger",
    "debtorsDesc": "Drill into each customer's outstanding invoices, payment history, and aging so you know exactly who owes you what, and for how long.",
    "statementsHeading": "Statements & aging reports",
    "statementsDesc": "Generate AR aging reports and send debtor statements to chase collections. Groot prepares the document and records that it was sent.",
    "reconciliationHeading": "Reconciliation",
    "reconciliationDesc": "Match incoming customer receipts to the right sales invoices so your AR ledger always reflects what has actually been paid.",
    "boundaryHeading": "What's included on your plan",
    "boundaryDesc": "Creating and sending sales invoices and viewing the AR dashboard stays available on every plan. The full-AR depth is part of the Pro tier: the Customers (debtors) tab, reconciliation, aging reports, statements and recording customer payments. Contact support to upgrade."
  },
  "profitLossReport": {
    "header": {
      "title": "Profit & Loss",
      "subtitle": "A simple income statement built from your expense claims"
    },
    "states": {
      "noBusinessSelected": "Select a business to view its Profit & Loss.",
      "noAccess": "You don't have permission to view this Profit & Loss statement.",
      "loadError": "Couldn't load the statement. Please try again."
    },
    "actions": {
      "howItWorks": "How it works"
    },
    "howItWorks": {
      "title": "How the Profit & Loss works",
      "intro": "This report adds up your posted journal entries by month. Choose a period, read it as one total or month by month, and compare it with the same period last year.",
      "stepsHeading": "How to read it",
      "step1Title": "Pick a period and a view",
      "step1Desc": "Choose a period such as This financial year or Last 12 months. One period shows a single total; 12 months shows each month from oldest to newest, then the total.",
      "step2Title": "Compare with last year",
      "step2Desc": "Turn on Compare with last year to add the figure for the same period last year and the change. A rise in profit is good; a rise in a cost is shown as worse.",
      "step3Title": "Click a figure to see why",
      "step3Desc": "Click any account figure to see the journal entries behind it. Owners and finance admins can open each voucher from there.",
      "step4Title": "Read Needs attention first",
      "step4Desc": "The Needs attention list flags a cost of sales of zero, months with a loss, and periods too large to be complete.",
      "goodToKnowHeading": "Good to know",
      "goodToKnow1": "Only posted entries are included. Drafts are ignored.",
      "goodToKnow2": "Figures are shown in your business's home currency.",
      "goodToKnow3": "Months after today are never shown, and months before your first entry are hidden with a note under the table.",
      "goodToKnow4": "This report is read-only and never changes your data."
    }
  },
  "errorBoundary": {
    "title": "Something went wrong",
    "description": "An error occurred while loading this page. Please reload, or contact support if the problem persists.",
    "reload": "Reload page",
    "tryAgain": "Try again",
    "goHome": "Go home",
    "errorIdLabel": "Error ID",
    "card": {
      "title": "This section could not be loaded",
      "body": "Something went wrong loading this card. The rest of the page is unaffected and no data was changed. Try again, or reload the page if it keeps happening.",
      "retry": "Try again"
    }
  },
  "products": {
    "header": {
      "title": "Products & Stock",
      "subtitle": "The item master every invoice line comes from. Plus stock levels, formulas, and incoming confirmations."
    },
    "stockAddon": {
      "title": "Stock management is an add-on",
      "body": "Stock levels, formulas and stock reports are not switched on for this business. Your product catalogue works as normal. Contact us if you would like stock management."
    },
    "searchPlaceholder": "Search by code, name, or category…",
    "loading": "Loading products…",
    "totalCount": "{count} products",
    "backToList": "Back to products",
    "table": {
      "code": "Code",
      "name": "Name",
      "category": "Category",
      "uom": "Unit",
      "price": "Price"
    },
    "empty": {
      "noneYet": "No products yet",
      "noneFound": "No products found",
      "adjustSearch": "Try a different search term.",
      "importHint": "Products appear here once your catalog is imported."
    },
    "detail": {
      "code": "Code",
      "uom": "Unit",
      "sku": "SKU",
      "tracked": "Tracked",
      "heading": "Catalog details",
      "notTracked": "Not tracked",
      "barcode": "Barcode",
      "category": "Category",
      "brand": "Brand",
      "model": "Model",
      "unitOfMeasure": "Unit of measure",
      "itemType": "Item type",
      "trackingMode": "Tracking mode",
      "inventory": "Inventory",
      "defaultCost": "Default cost",
      "currency": "Currency",
      "preferredVendor": "Preferred vendor",
      "lifecycle": "Lifecycle",
      "barcodeAliases": "Barcode aliases",
      "saleAvailability": "Sales catalog",
      "availableForSale": "Available for sale",
      "notForSale": "Not for sale",
      "regularPrice": "Regular price",
      "promotion": "Promotion",
      "promotionRange": "{price} from {from} until {until}",
      "promotionFrom": "{price} from {from}",
      "promotionUntil": "{price} until {until}",
      "promotionOpen": "{price}"
    },
    "suppliers": {
      "title": "Bought from",
      "loading": "Loading suppliers…",
      "empty": "No suppliers recorded for this product yet.",
      "confidenceLabel": "Confidence"
    },
    "draftBadge": {
      "label": "Draft · needs review",
      "tooltip": "Found on a supplier document and not yet confirmed as a product. Hidden from sales invoices until confirmed.",
      "sqlSuffix": "· pending SQL code",
      "sqlTooltip": "It also has no SQL stock code yet, so it exports as an expense line until one is assigned."
    },
    "stripePrices": {
      "heading": "Plans & prices",
      "noActive": "No active price",
      "showArchived": "Show archived ({count})",
      "hideArchived": "Hide archived",
      "archivedBadge": "Archived",
      "expand": "Show prices",
      "collapse": "Hide prices"
    },
    "tabs": {
      "catalog": "Catalog",
      "review": "Needs review",
      "stock": "Stock",
      "formulas": "Formulas",
      "incoming": "Incoming"
    },
    "stock": {
      "views": {
        "overview": "Overview",
        "locations": "Locations",
        "setup": "Stock management",
        "openingAdjustments": "Opening stock and adjustments",
        "production": "Production",
        "customerHeld": "Customer-held stock",
        "delivery": "Delivery Orders",
        "settings": "Settings",
        "stockTake": "Stock count",
        "valueDishCosts": "Stock overview",
        "items": "Items",
        "supplierLinks": "Supplier links",
        "activity": "Activity",
        "transfer": "Transfer stock"
      },
      "disabledMode": {
        "title": "Inventory workflows are disabled",
        "description": "Catalog products remain available, but stock levels, adjustments, Delivery Orders, and locations are hidden until inventory is re-enabled in settings."
      },
      "production": {
        "heading": "Formulas",
        "description": "Manage formulas for stock used on sale and formulas for stock made during production. Production run controls stay under On production.",
        "editBom": "Edit",
        "postFromBom": "Post",
        "bomLibraryTitle": "Formulas",
        "bomLibraryDescription": "Each formula fixes what goes into one finished item. Review it before posting production.",
        "emptyBomTitle": "No production formulas yet",
        "emptyBomDescription": "Portion an item or combine items to create your first formula.",
        "historyDescription": "Every posted production run stays visible here with input cost detail.",
        "never": "Never",
        "unknownItem": "Unknown item",
        "cancel": "Cancel",
        "existingBom": "Formula",
        "selectBom": "Select formula",
        "finishedProduct": "Finished product",
        "selectFinishedProduct": "Select finished product",
        "bomName": "Formula name",
        "outputQuantity": "Output quantity",
        "components": "Inputs",
        "noComponents": "Tick at least one stock-tracked item.",
        "componentItem": "Input item",
        "componentQuantity": "Quantity consumed",
        "removeComponent": "Remove input",
        "componentBreakdownTitle": "Input breakdown",
        "componentBreakdownDescription": "Formula quantities are defined per {outputQuantity} finished units.",
        "componentFormula": "{componentQuantity} per {outputQuantity} finished units",
        "componentRequired": "{quantity} required",
        "savingBom": "Saving...",
        "saveBom": "Save formula",
        "postTitle": "Post production",
        "noBomSelected": "Select a formula before posting production.",
        "componentCount": "{count} inputs",
        "quantityProduced": "Quantity produced",
        "productionDate": "Production date",
        "componentSource": "Input source",
        "destination": "Finished goods destination",
        "selectLocation": "Select location",
        "notes": "Notes",
        "posting": "Posting...",
        "postRun": "Post production run",
        "historyTitle": "Production history",
        "showComponents": "Show inputs",
        "noRuns": "No production runs recorded yet.",
        "table": {
          "run": "Run",
          "finished": "Finished product",
          "quantity": "Qty",
          "locations": "Source / destination",
          "unitCost": "Unit cost",
          "totalCost": "Total cost",
          "status": "Status",
          "actions": "Actions"
        },
        "summary": {
          "activeBoms": "Active production formulas",
          "productionRuns": "Production runs",
          "lastRun": "Last run"
        },
        "dialog": {
          "editBomTitle": "Edit formula",
          "postTitle": "Post production",
          "portionTitle": "Portion an item",
          "combineTitle": "Combine items",
          "portionDescription": "Split something you bought into the sizes you sell. The cost of each portion follows the price you paid.",
          "combineDescription": "Tick the items that go into one finished product and say how much of each."
        },
        "errors": {
          "saveFailed": "The formula could not be saved.",
          "postFailed": "Production run could not be posted.",
          "duplicateComponent": "This formula already includes that item. Remove the duplicate row before saving.",
          "invalidOutputQuantity": "Enter an output quantity greater than zero.",
          "invalidComponentQuantity": "Enter an input quantity greater than zero.",
          "componentsRequired": "Tick at least one stock-tracked item before saving.",
          "selfReference": "The finished product cannot also be an input.",
          "finishedNotTracked": "Choose a stock-tracked finished product.",
          "invalidFinishedType": "The finished product must be an assembly or stocked product.",
          "componentNotTracked": "Choose stock-tracked inputs only.",
          "invalidComponentType": "Formula inputs must be Stock Items.",
          "bomNotFound": "This formula is no longer available. Refresh and choose another formula.",
          "invalidProductionQuantity": "Enter a production quantity greater than zero.",
          "inventoryDisabled": "Inventory workflows are disabled for this business.",
          "inventoryNotManaged": "Production can only be posted when Groot manages inventory stock.",
          "catalogItemNotFound": "One of the selected products is no longer available.",
          "locationNotFound": "One of the selected locations is no longer available.",
          "notAuthorized": "You do not have permission to manage production.",
          "featureNotEnabled": "Inventory is not enabled for this business.",
          "insufficientStock": "Insufficient input stock for this production run.",
          "insufficientLine": "{item}: required {required}, available {available}.",
          "selectFinishedProduct": "Select a finished product before saving.",
          "selectComponent": "Select an input item before saving.",
          "selectLocations": "Select both the input source and finished goods destination.",
          "createItemFailed": "The portion item could not be created.",
          "portionNameRequired": "Give the portion item a name.",
          "formulaZeroYield": "Say how many this formula makes. It must be more than zero.",
          "formulaAlreadyExists": "This product already has a formula. Edit that one instead of adding a second.",
          "formulaCycle": "A product cannot be made from itself, even through other formulas. Remove the part that loops back.",
          "formulaTooDeep": "These formulas are nested too deeply (more than 5 levels). Simplify one of the parts.",
          "formulaTooManyParts": "A formula can have at most 50 parts.",
          "formulaYieldNotExact": "These quantities do not divide evenly by the yield. Use a yield of 1 and enter the amount per product, or change the quantities.",
          "formulaInBothTables": "This product has a formula in both places. Archive one of the two formulas first.",
          "formulaProductChange": "A formula belongs to one product. Create a new formula for the other product."
        },
        "correction": {
          "action": "Correct run",
          "actionAria": "Correct production run {number}",
          "dialogTitle": "Correct production run {number}",
          "dialogDescription": "This reverses the whole run. Inputs go back to the location they were drawn from and the finished goods leave the location they were added to, valued at the figures this run recorded.",
          "loadingPreview": "Checking what this correction would move...",
          "previewTitle": "What will move",
          "previewDescription": "Every line is valued from the figures run {number} recorded on {date}.",
          "componentReturn": "Input returned",
          "finishedRemoval": "Finished goods removed",
          "legLine": "{quantity} at {unitCost}",
          "legLocation": "Location: {location}",
          "totalsComponents": "Inputs returned",
          "totalsFinished": "Finished goods removed",
          "totalsNet": "Net inventory value",
          "noJournalEntry": "No journal entry will be created. A production run moves value from one inventory item to another, so it posts nothing to the ledger, and neither does its correction.",
          "reasonLabel": "Reason for this correction",
          "reasonPlaceholder": "Explain why this production run is being reversed",
          "reasonHint": "Finance reviewers will see this reason in the activity trail for this run.",
          "reasonRequired": "Give a reason of at least 3 characters before correcting this run.",
          "confirm": "Correct run",
          "confirming": "Correcting...",
          "close": "Close",
          "detailsTitle": "Run detail",
          "linkToCorrection": "Corrected by {number}",
          "linkToOriginal": "Corrects {number}",
          "correctedOn": "Corrected on {date}",
          "correctedReason": "Reason: {reason}",
          "status": {
            "posted": "Posted",
            "corrected": "Corrected",
            "correction": "Correction"
          },
          "errors": {
            "runNotFound": "This production run is no longer available.",
            "notCorrectable": "This production run cannot be corrected. It has already been corrected, or it is itself a correction record.",
            "finishedStockUnavailable": "Correcting this run needs all {produced} finished units still at their destination, and {onHand} are on hand. Record a stock adjustment instead.",
            "outOfOrder": "A later production run ({number}) has already been posted for this finished product. Correct that run first.",
            "staleVersion": "This production run changed while you were reviewing it. Close this dialog and open it again.",
            "factsUnreadable": "One of this run's dependencies could not be read, so it cannot be corrected right now. Refresh and try again.",
            "periodClosed": "The accounting period for this run is closed, so it cannot be corrected. Ask your accountant for an adjustment.",
            "beforeConversionDate": "This run is dated before your opening balance date, so it cannot be corrected here.",
            "unauthenticated": "Your session has expired. Sign in again.",
            "userNotFound": "Your user account could not be read. Sign in again.",
            "notAMember": "You are no longer a member of this business.",
            "previewFailed": "The correction preview could not be loaded. Refresh and try again.",
            "correctFailed": "The correction could not be saved. Try again.",
            "preSwitchRecord": "This production run was recorded before the stock costing method changed to first-in, first-out, so it cannot be corrected. Nothing was changed. Record a stock adjustment instead, or contact support."
          }
        },
        "portionItem": "Portion an item",
        "combineItems": "Combine items",
        "formulaRow": "{outputQuantity} × {finished} ← {inputs}",
        "formulaInput": "{quantity} × {item}",
        "formulaUnitCost": "{cost} each",
        "portion": {
          "sourceItem": "Item you bought",
          "selectSourceItem": "Select the item to portion",
          "portionItem": "Sellable portion",
          "selectPortionItem": "Select the portion item",
          "createPortionItem": "+ Create portion item",
          "newItemName": "Portion name",
          "newItemNamePlaceholder": "e.g. Fries 200g",
          "newItemPrice": "Selling price",
          "newItemUnit": "Unit",
          "defaultUnit": "portion",
          "createItem": "Create item",
          "creatingItem": "Creating...",
          "backToList": "Choose an existing item instead",
          "yieldPrefix": "1 {unit} makes",
          "yieldSuffix": "portions",
          "unitFallback": "unit",
          "derivedCost": "Each portion costs about {cost}",
          "derivedCostUnknown": "The cost per portion appears once the item has been received into stock."
        },
        "combine": {
          "pickInputs": "Add input",
          "filterPlaceholder": "Search stock-tracked items",
          "noMatches": "No stock-tracked items match.",
          "selectedCount": "{count} ticked"
        },
        "recipeLaneTitle": "Recipes and formulas",
        "recipeLaneDescription": "A recipe says what goes into one finished item and how much of each input it uses. Posting a run moves inputs into the finished item at their current cost.",
        "recipeExampleDumplings": "Example: 1 x dumpling 4-piece set uses 4 pcs of dumpling.",
        "recipeExampleFries": "Example: 1 x 200g fries pack uses 0.2 kg of fries, or 5 packs use 1 kg.",
        "salesGuardTitle": "Sales sell what production made",
        "salesGuardDescription": "A Sales Invoice deducts the finished item it sells. Inputs leave stock when you post a production run, not when a customer buys the finished item.",
        "unitSnapshot": "Recipe v{version} · output in {outputUnit} · inputs in {inputUnits}",
        "runSnapshot": "Posted from recipe v{version} · output in {outputUnit} · inputs in {inputUnits}",
        "componentBaseUnit": "base unit {unit}, profile v{version}",
        "unitSnapshotUnknown": "unit not set",
        "quantityNotRepresentable": "This quantity cannot be represented at the item base-unit precision.",
        "gaps": {
          "title": "{count, plural, one {# product needs a formula} other {# products need a formula}}",
          "description": "Stock is switched on for these products, but nothing can put stock in: they have no formula and no purchase has ever been received. Until one of those happens, a sale of any of them is refused for insufficient stock. Add a formula if you cook it, or receive it on a purchase invoice if you resell it as bought.",
          "addFormula": "Add formula",
          "truncated": "Showing the first 50"
        },
        "trigger": {
          "label": "Formula trigger",
          "sale": "On sale",
          "saleDescription": "Relieve inputs when a Sales Product is sold.",
          "production": "On production",
          "productionDescription": "Build or portion stock before it is sold.",
          "formulaCount": "{count, plural, one {# formula} other {# formulas}}"
        },
        "saleFormula": {
          "listTitle": "On sale formulas",
          "listDescription": "Choose what stock leaves when a Sales Product is sold.",
          "emptyTitle": "No on sale formulas yet",
          "emptyDescription": "Pick a Sales Product and confirm its Stock Item inputs.",
          "editTitle": "Edit on sale formula",
          "createTitle": "Create on sale formula",
          "editorDescription": "Define inputs per one sales unit. Nothing is saved until you confirm.",
          "salesProduct": "Sales Product",
          "chooseSalesProduct": "Choose Sales Product",
          "searchSalesProducts": "Search Sales Products by name or SKU",
          "noSalesProductMatches": "No Sales Products match your search.",
          "stockItem": "Stock Item input",
          "chooseStockItem": "Choose Stock Item",
          "searchStockItems": "Search Stock Items by name or SKU",
          "noStockItemMatches": "No Stock Items match your search.",
          "confirmedStockItemsOnly": "Only confirmed Stock Items appear here. Supplier suggestions stay unavailable until their Incoming setup is complete.",
          "openIncoming": "Open Incoming",
          "addComponent": "Add input",
          "noComponents": "Add at least one Stock Item input.",
          "componentHint": "Consumed when one sales unit is posted.",
          "quantityForItem": "Quantity per sales unit for {item}",
          "removeComponent": "Remove {item}",
          "create": "Create formula",
          "replace": "Replace formula",
          "saving": "Saving...",
          "archive": "Archive formula",
          "archiving": "Archiving...",
          "saved": "Formula saved. Future sales use this route.",
          "archived": "Formula archived. Future sales need another route.",
          "unsavedDirectDefault": "Unsaved draft from the current stock route. Review and save to confirm an explicit formula.",
          "componentSummary": "{quantity} x {item}",
          "version": "Version {version}",
          "backToProduct": "Back to product",
          "writeReason": "Updated from Formulas workspace",
          "archiveReason": "Archived from Formulas workspace",
          "state": {
            "formula": "Active on sale formula is already confirmed for this Sales Product.",
            "legacyLink": "A legacy relief link is active. Replace it with an on sale formula when ready.",
            "self": "Compatibility self relief is active. Save the draft to make the route explicit.",
            "blocked": "This Sales Product has a stock route problem. Fix the setup before saving.",
            "none": "No stock route is confirmed yet.",
            "selfClosed": "This product relieves its own stock from before the formula model. Link a separate Stock Item to replace it.",
            "assembly": "This product sells from its own stock. Only what is short at the sale is assembled from its formula."
          },
          "errors": {
            "salesProductRequired": "Choose a Sales Product.",
            "componentRequired": "Add at least one Stock Item input.",
            "quantityRequired": "Enter a positive quantity per sales unit.",
            "duplicateComponent": "{item} is already in this formula.",
            "duplicateComponentGeneric": "A Stock Item can appear only once in a sales formula.",
            "stale": "This formula changed. Reload and try again.",
            "duplicateActive": "This Sales Product has multiple active formulas. Ask support to repair it.",
            "saveFailed": "Could not save the formula. Check the inputs and try again.",
            "alreadyExists": "This product already has a formula. Edit that one instead of adding a second.",
            "cycle": "A product cannot be made from itself, even through other formulas. Remove the part that loops back.",
            "tooDeep": "These formulas are nested too deeply (more than 5 levels). Simplify one of the parts.",
            "yieldNotExact": "These quantities do not divide evenly by the yield. Use a yield of 1 and enter the amount per product, or change the quantities.",
            "inBothTables": "This product has a formula in both places. Archive one of the two formulas first.",
            "productChange": "A formula belongs to one product. Create a new formula for the other product."
          },
          "setupTitle": "Formula setup review",
          "setupDescription": "Review older stock routes and direct resale candidates before claiming they are active formulas.",
          "explicitLegacyTitle": "Legacy relief links",
          "explicitLegacyDescription": "These Sales Products still use an older stock relief link. Review and save to create a confirmed on sale formula.",
          "implicitSelfTitle": "Direct resale candidates",
          "implicitSelfDescription": "These Sales Products also have Stock enabled. Groot can start a quantity 1 draft, but you must save it before it becomes an explicit formula.",
          "setupComponent": "{quantity} x {item}",
          "reviewMigration": "Review formula",
          "confirmSelfFormula": "Confirm formula",
          "legacyDraftReview": "Draft copied from a legacy relief link. Review and save to create an active on sale formula.",
          "implicitSelfComponent": "Quantity 1 of the same Stock Item",
          "selfFormulaForbidden": "A Sales Product cannot be its own formula input. Choose a separate Stock Item.",
          "scopeLabel": "Show sales products",
          "scopeNeeds": "Needs formula ({count})",
          "scopeHas": "Has formula ({count})",
          "scopeAll": "All ({count})",
          "optionNoFormula": "No formula yet",
          "optionOlderRoute": "Older stock route",
          "optionMore": "{summary} +{count} more",
          "coverage": "{done} of {total} sales products have a formula",
          "quickMap": {
            "title": "Quick map: {count} without a formula",
            "description": "One Stock Item per sales unit, confirmed row by row. Groot pre-fills a match when a name or SKU is unambiguous; pick another when it is wrong. Products needing two or more inputs use the editor above.",
            "product": "Sales Product",
            "stockItem": "Stock Item",
            "quantity": "Qty per sale",
            "confirm": "Confirm",
            "saving": "Saving",
            "suggested": "Suggested by name",
            "saved": "Saved: {product}",
            "showMore": "Show {count} more",
            "searchStockItems": "Search Stock Items"
          }
        },
        "emptyBomSaleHint": "{count, plural, one {You have # on-sale formula} other {You have # on-sale formulas}}, which relieve stock when a product is sold.",
        "emptyBomSaleHintAction": "Show on-sale formulas"
      },
      "customerHeld": {
        "heading": "Customer-held stock",
        "description": "Track invoiced stock that is already sold but still physically held for the customer.",
        "allLocations": "All customer-held locations",
        "balancesTitle": "Balances",
        "movementsTitle": "Movement history",
        "fromSource": "From {location}",
        "releasedSuffix": "released",
        "release": "Release",
        "reverseRelease": "Reverse release",
        "released": "Released",
        "noBalances": "No customer-held stock balances yet.",
        "noMovements": "No customer-held stock movements yet.",
        "summary": {
          "remainingQty": "Remaining quantity",
          "openInvoices": "Open invoices",
          "remainingValue": "Remaining cost"
        },
        "status": {
          "held": "Held",
          "released": "Released",
          "voided": "Voided"
        },
        "movement": {
          "holdCreated": "Hold created",
          "released": "Released",
          "releaseReversed": "Release reversed",
          "voided": "Voided"
        },
        "table": {
          "customer": "Customer",
          "invoice": "Invoice",
          "item": "Item",
          "remaining": "Remaining",
          "location": "Status",
          "actions": "Actions",
          "date": "Date",
          "movement": "Movement",
          "quantity": "Qty",
          "value": "Value"
        },
        "releaseDialog": {
          "title": "Release customer-held stock",
          "description": "Release up to {remaining} of {item} for invoice {invoice}. This records delivery only and does not create a journal entry.",
          "quantity": "Quantity to release",
          "date": "Release date",
          "notes": "Notes",
          "cancel": "Cancel",
          "confirm": "Release",
          "releasing": "Releasing..."
        },
        "reverseDialog": {
          "title": "Reverse customer-held release",
          "description": "Reverse up to {released} released quantity of {item} for invoice {invoice}. Use this only when the release was recorded by mistake.",
          "quantity": "Quantity to reverse",
          "date": "Reversal date",
          "reason": "Reason",
          "cancel": "Cancel",
          "confirm": "Reverse release",
          "reversing": "Reversing..."
        },
        "errors": {
          "releaseFailed": "Customer-held stock could not be released.",
          "reverseFailed": "Customer-held stock release could not be reversed.",
          "invalidReleaseQuantity": "Enter a release quantity greater than zero and not more than the remaining quantity.",
          "invalidReverseQuantity": "Enter a reversal quantity greater than zero and not more than the released quantity.",
          "balanceVoided": "This customer-held stock line has been voided, so it can no longer be released or corrected. Refresh the page to see the current balances."
        }
      },
      "settings": {
        "receiving": {
          "title": "Purchased goods land in stock by default",
          "description": "When on, posting a purchase invoice opens the receive sheet immediately and moves the cost from expense to inventory. Cost of sales is then recognised when stock is used or at month-end close.",
          "derivedOn": "On because this business has not posted a purchase invoice yet. Switch it off to keep receiving stock by hand.",
          "derivedOff": "Off because this business already posts purchases straight to cost of sales. Switching it on applies to invoices posted from now on.",
          "disabledWhenNotGroot": "Purchased goods can only land in stock when Groot manages inventory."
        }
      },
      "incomingBanner": {
        "title": "{count, plural, =1 {1 item to confirm before it reaches stock} other {# items to confirm before they reach stock}}",
        "action": "Review incoming"
      },
      "reportLink": "Stock balance report",
      "cardLink": "Stock card",
      "priceHistoryLink": "Price history"
    },
    "priceHistory": {
      "title": "Price history",
      "loading": "Loading price history…",
      "empty": "No price history recorded for this item yet.",
      "cheapest": "Cheapest"
    },
    "review": {
      "loading": "Loading reviews…",
      "intro": "{count} items need a quick match.",
      "suggestedLabel": "Suggested",
      "pickerPlaceholder": "Search products to match…",
      "pickerLoading": "Searching products…",
      "pickerEmpty": "No matching products. Try another term or use Suggest.",
      "suggest": "Suggest",
      "suggestError": "Couldn't fetch suggestions. Try again.",
      "suggestionsTitle": "Suggested matches",
      "noSuggestions": "No suggestions found for this item.",
      "selectedLabel": "Selected",
      "confirm": "Confirm",
      "confirmError": "Couldn't confirm the match. Try again.",
      "dismiss": "Dismiss",
      "dismissError": "Couldn't dismiss. Try again.",
      "empty": {
        "title": "Nothing to review",
        "subtitle": "Nothing to review. New items get matched automatically."
      },
      "columns": {
        "select": "Select",
        "line": "Supplier line",
        "product": "Product",
        "code": "Item code",
        "unit": "Unit",
        "actions": "Actions"
      },
      "bulk": {
        "selectAll": "Select all",
        "selectedCount": "{count} selected",
        "confirmSelected": "Confirm selected ({count})",
        "confirmAll": "Confirm all {count}",
        "confirming": "Confirming...",
        "confirmed": "{count} confirmed",
        "confirmError": "Couldn't confirm the selected items. Nothing was changed. Try again.",
        "skuTaken": "The item code {sku} is already used by another product. Change it and try again.",
        "needsPick": "Pick a product first",
        "keyboardHint": "j / k move · x tick · Enter confirm",
        "sqlNote": "Confirming marks these as real products in Groot. Their SQL stock codes are assigned from the SQL stock write-back.",
        "truncated": "Showing the first page of reviews. Confirm all applies only to the rows shown; more reviews remain after this page."
      },
      "newProductTag": "New product",
      "existingProductTag": "Existing product",
      "changeProduct": "Change",
      "cancelPick": "Keep suggested",
      "codePlaceholder": "Item code",
      "unitPlaceholder": "Unit",
      "catalogSectionTitle": "Catalog item matches",
      "supplierPack": {
        "sectionTitle": "Supplier pack setup",
        "sectionDescription": "Confirm how a supplier purchase pack becomes this Stock Item's base stock unit. OCR and description text can suggest a pack, but a person must confirm it before it affects stock.",
        "pendingSummary": "{count} pack decisions need review.",
        "selectRow": "Select supplier pack review",
        "unknownSupplier": "Unknown supplier",
        "brand": "Brand: {brand}",
        "suggestedChip": "Suggested",
        "suggestedNotConfirmed": "Suggested by source text only. Review before confirming.",
        "sameUnitHint": "The bill and the Stock Item use the same unit, so 1 {purchaseUom} = 1 {baseUom} is filled in. Check it, then confirm.",
        "ready": "Ready to confirm",
        "needsFields": "Needs a Stock Item, purchase unit, stock unit and pack contents",
        "activeDefault": "Current default: 1 {purchaseUom} = {quantity} {baseUom}",
        "sourceHeading": "Source purchase evidence",
        "sourceQuantity": "Source qty",
        "purchaseUnit": "Purchase unit",
        "listPrice": "List price",
        "discount": "Line discount",
        "netCost": "Net cost",
        "lineTotal": "Line total",
        "observedAt": "Document date",
        "documentLink": "Open source document",
        "targetHeading": "Stock Item and pack contents",
        "needsTarget": "Pick the Stock Item this supplier item should affect.",
        "pickerPlaceholder": "Search Stock Items...",
        "pickerLoading": "Searching products...",
        "pickerEmpty": "No matching products. Try another term.",
        "changeIngredient": "Change Stock Item",
        "keepIngredient": "Keep Stock Item",
        "baseUom": "Stock unit",
        "packContents": "Stock units per purchase unit",
        "packContentsPlaceholder": "e.g. 15",
        "baseQuantityPreview": "{sourceQuantity} {purchaseUom} will receive {baseQuantity} {baseUom}.",
        "baseQuantityPreviewEmpty": "Enter pack contents to preview the received base quantity.",
        "actionHeading": "Confirmation action",
        "confirmRow": "Confirm pack",
        "counts": {
          "ready": "{count} ready",
          "missingPack": "{count} missing pack",
          "ambiguous": "{count} ambiguous",
          "changed": "{count} changed"
        },
        "bulk": {
          "selectAll": "Select all ready packs",
          "selectedCount": "{count} ready packs selected",
          "confirmSelected": "Confirm selected ({count})",
          "confirmAll": "Confirm all ready {count}",
          "confirmed": "{count} supplier pack decisions confirmed",
          "confirmError": "Could not confirm the selected supplier packs. Nothing was changed. Review the rows and try again."
        },
        "actions": {
          "confirm_default": {
            "title": "Save as default",
            "description": "Use this pack for future lines from the same supplier item."
          },
          "use_once": {
            "title": "Use once for this document",
            "description": "Record this source line without changing the durable supplier default."
          },
          "supersede_default": {
            "title": "Replace default",
            "description": "Close the old supplier pack and make this the new default for future lines."
          },
          "refuse": {
            "title": "Refuse pack",
            "description": "Keep this review auditable, but do not create a mapping, supplier pack, or stock effect."
          }
        },
        "reasons": {
          "no_vendor": "Missing supplier",
          "no_catalog_item": "Needs Stock Item",
          "missing_base_uom": "Missing stock unit",
          "missing_pack_contents": "Missing pack contents",
          "ambiguous_pack_contents": "Ambiguous pack",
          "pack_changed": "Pack changed",
          "base_uom_conflict": "Stock unit conflict",
          "multiple_active_pack_mappings": "Multiple active packs",
          "unconfirmed_catalog_mapping": "Unconfirmed item match"
        },
        "step": {
          "one": "Step 1",
          "two": "Step 2"
        },
        "packHeading": "Pack contents",
        "create": {
          "trigger": "Create new product",
          "nameLabel": "Product name",
          "namePlaceholder": "e.g. Potato Fries",
          "skuLabel": "Item code (optional)",
          "skuPlaceholder": "Leave blank to auto-generate",
          "baseUomLabel": "Base unit (optional)",
          "baseUomPlaceholder": "e.g. kg",
          "submit": "Create",
          "cancel": "Cancel",
          "error": "Could not create the product."
        },
        "deepLinkNotFound": "That review is not in the pending queue. It may already be resolved.",
        "requestedFromRegister": "Requested from Supplier Items",
        "noPurchaseLine": "No purchase line is attached, so there are no quantity or price facts to show.",
        "nextStep": {
          "pickStockItem": "Pick the Stock Item, then enter the pack contents.",
          "enterPack": "Enter the pack contents to confirm."
        }
      }
    },
    "actions": {
      "newProduct": "New Product",
      "editProduct": "Edit Product",
      "archiveProduct": "Archive Product",
      "importProducts": "Import Products",
      "assignCodes": "Assign item codes",
      "assigningCodes": "Assigning...",
      "assignCodesDone": "{count} item codes assigned",
      "assignCodesFailed": "Couldn't assign item codes. Try again.",
      "confirmProduct": "Confirm product",
      "confirmProductDone": "Product confirmed in the item master. Sale availability is unchanged.",
      "confirmProductFailed": "Couldn't confirm the product. Try again."
    },
    "archive": {
      "title": "Archive product?",
      "message": "Archive {name}? This removes it from active product lists and future invoice/catalog selection. Historical invoices, supplier records, stock movements, and audit history are kept. Products with non-zero stock must be adjusted to zero first.",
      "confirm": "Archive",
      "cancel": "Cancel",
      "success": "Product archived.",
      "failed": "Product could not be archived. Check stock balances and try again.",
      "errors": {
        "hasStock": "This product still has stock on hand, committed, incoming or unavailable. Bring all four to zero before archiving it.",
        "notFound": "We couldn't find this product. It may already be archived. Refresh the page."
      }
    },
    "importFlow": {
      "title": "Import product catalog",
      "description": "Download the Groot template, upload the completed file, review changes, then import.",
      "downloadTemplate": "Download template",
      "uploadFile": "Upload file",
      "rowCount": "{count} rows",
      "parseErrors": "File issues",
      "previewTitle": "Import preview",
      "previewHint": "Review generated SKUs, duplicate warnings, and update matches before confirming.",
      "dirtyHint": "Changes need to be validated before import.",
      "emptyPreview": "Upload a Groot product template to preview rows here.",
      "validate": "Validate",
      "cancel": "Cancel",
      "close": "Close",
      "confirmImport": "Confirm import",
      "validateBeforeImport": "Validate before import",
      "previewFailed": "Product import preview failed. Check the file and try again.",
      "confirmFailed": "Product import failed. Fix validation errors and try again.",
      "successToast": "Imported products: {created} created, {updated} updated.",
      "resultTitle": "Import complete",
      "resultSummary": "{created} created, {updated} updated.",
      "downloadResult": "Download result CSV",
      "dismissResult": "Dismiss import result",
      "unchanged": "Unchanged",
      "emptyValue": "Blank",
      "booleanYes": "Yes",
      "booleanNo": "No",
      "statusMessages": "Review issues",
      "rowDetails": "Row {row} details",
      "fields": {
        "description": "Description",
        "barcode": "Barcode",
        "brand": "Brand",
        "modelNumber": "Model"
      },
      "updateReview": {
        "changed": "Changing",
        "kept": "Kept from existing",
        "current": "Current",
        "keptCurrent": "No change",
        "importValue": "Import",
        "otherChanges": "Other changes",
        "hiddenKept": "Other blank fields keep existing values: {fields}",
        "fromTo": "{field}: {from} -> {to}",
        "keptValue": "{field}: {value}",
        "moreKept": "+{count} more kept",
        "noChanges": "No field changes detected."
      },
      "columns": {
        "row": "Row",
        "status": "Status",
        "sku": "SKU",
        "name": "Name",
        "salePrice": "Sale price",
        "cost": "Cost",
        "currency": "Currency",
        "track": "Track",
        "itemType": "Item type",
        "tracking": "Tracking",
        "notes": "Notes",
        "openingQuantity": "Opening qty",
        "location": "Location",
        "image": "Image",
        "content": "Content",
        "regularPrice": "Regular price",
        "promoPrice": "Promo price"
      },
      "actions": {
        "create": "Create",
        "update": "Update",
        "error": "Error"
      },
      "source": {
        "label": "Import source",
        "spreadsheet": "Spreadsheet",
        "grabfood": "Delivery products",
        "grabfoodUpload": "Upload product export",
        "grabfoodHint": "Upload the product export from your delivery platform (GrabFood: the ZIP from MerchantGrab). Items are imported as non-stocked products with their listed prices; option groups, photos and schedules are reported, not imported.",
        "reportTitle": "Not imported (reported)",
        "reportOptions": "{count, plural, =0 {No items with option groups} one {# item with option groups (priced separately on the platform)} other {# items with option groups (priced separately on the platform)}}",
        "reportPhotos": "{count, plural, =0 {No items with photos} one {# item with product photos} other {# items with product photos}}",
        "reportSchedules": "{count, plural, =0 {No items on custom schedules} one {# item on a custom availability schedule} other {# items on custom availability schedules}}",
        "reportSkipped": "{count, plural, =0 {No items skipped} one {# item skipped (not currently available)} other {# items skipped (not currently available)}}",
        "reportTotalWarning": "Some option groups list absolute bundle prices (\"Total\" options). Bundle and add-on prices are never applied automatically: review them on the platform or set them as separate products.",
        "fileLabel": "{store} product export",
        "woocommerce": "WooCommerce"
      },
      "plan": {
        "sellableFromStock": "Takes {quantity} from stock",
        "sellable": "Stock not tracked",
        "stockOnly": "Stock item only, not for sale",
        "notForSale": "Not for sale",
        "stockCreate": "New stock item {stockSku}",
        "stockUpdate": "Updates stock item {stockSku}",
        "stockLinked": "Uses existing stock item {stockSku}",
        "formulaKeep": "Sales formula already in place",
        "formulaCustom": "Keeps its own sales formula",
        "openingSet": "Opening stock {quantity} at {location}",
        "openingSkip": "Opening stock not set",
        "bundleTakes": "Takes {quantity} × {baseSku}",
        "bundleStock": "Uses {baseSku}'s stock item {stockSku}",
        "soldAsItself": "Sold as itself, takes 1 from stock per sale"
      },
      "summarySellable": "{count, plural, =0 {No rows sell from stock} one {# row sells from stock} other {# rows sell from stock}}",
      "summaryOpening": "{count, plural, =0 {No opening stock} one {# opening stock balance} other {# opening stock balances}}",
      "confirmSavesFormulas": "Confirming saves each row as shown, including the sales formula that takes stock out when the product is sold.",
      "importingProgress": "Importing rows {done} of {total}",
      "partialTitle": "Import stopped part way",
      "partialBody": "{done} of {total} rows were imported. Rows {from} to {to} were not imported, and the rows after them were not tried.",
      "partialRetry": "Upload the same file again after fixing it. Rows already imported are updated, never duplicated.",
      "staleRows": "Some rows changed since you checked the file. Validate again, then import.",
      "successDetail": "{sellable} sell from stock, {opening} opening stock balances set.",
      "notices": {
        "OPENING_QUANTITY_INVALID": "Opening quantity must be zero or a positive number.",
        "OPENING_COST_REQUIRED": "Purchase cost is required when an opening quantity is given; it becomes the opening unit cost.",
        "OPENING_NEEDS_TRACKING": "Opening quantity needs Track inventory = Yes.",
        "STOCK_ADDON_REQUIRED": "This row tracks stock, which needs Stock management, an add-on that is not switched on for this business. Remove the stock columns to import it as a plain product, or contact us to switch it on.",
        "INVENTORY_NOT_MANAGED": "Opening stock can't be set because this business does not manage its inventory in Groot.",
        "NO_LOCATION": "Add an inventory location under Stock before importing opening quantities.",
        "LOCATION_REQUIRED": "Fill in Location for the opening quantity; this business has more than one inventory location.",
        "LOCATION_AMBIGUOUS": "More than one inventory location is named {location}.",
        "LOCATION_NOT_FOUND": "Location {location} was not found. Use the name of an existing inventory location.",
        "OPENING_TARGET_DUPLICATE": "Another row in this file already sets opening stock for the same stock item.",
        "OPENING_STOCK_EXISTS": "Opening stock not set: this item already has stock records, and Groot never overwrites them. Adjust its stock under Stock instead.",
        "OPENING_ACCOUNT_NOT_READY": "Opening stock can't be posted: no inventory account is set up. Choose one under Accounting → Chart of Accounts → Payment & posting.",
        "OPENING_ACCOUNT_IS_HEADING": "Opening stock can't be posted: the inventory account is a heading. Choose one of its sub-accounts under Accounting → Chart of Accounts → Payment & posting.",
        "OPENING_EQUITY_NOT_READY": "Opening stock can't be posted: no owner's equity account is set up. Add an active equity account under Accounting → Chart of Accounts.",
        "OPENING_PERIOD_CLOSED": "Opening stock can't be posted: today's accounting period is closed.",
        "OPENING_BEFORE_GO_LIVE": "Opening stock can't be posted: today is before your opening-balance go-live date.",
        "UOM_DEFAULTED": "UOM was blank, so Groot will count this item in {unit}. Change it before importing if it is sold by weight or volume.",
        "STOCK_UNIT_KEPT": "The stock item keeps counting in {unit}; change its unit from the stock item if needed.",
        "STOCK_BASE_UNIT_CONFLICT": "The stock item {stockSku} has no single active base unit. Fix it under Stock Items first.",
        "ITEM_NOT_ACTIVE": "This product is inactive, archived or still a draft. Activate it before importing.",
        "STOCK_ITEM_NOT_ACTIVE": "This product's stock item is inactive, archived or still a draft. Activate it before importing.",
        "STOCK_SKU_TAKEN": "The code {stockSku} is already used by another product, and Groot keeps it free for an older stock item of this product. Rename one of them, then import again.",
        "STOCK_SKU_IN_FILE": "Another row in this file uses the code {stockSku}, which Groot keeps free for an older stock item of this product. Give that row another SKU.",
        "ITEM_ROLE_UNCLEAR": "Groot can't tell whether this existing product is for sale or a stock item. Edit it under Products first.",
        "STOCK_ITEM_SOLD_ELSEWHERE": "{sku} is a stock item already sold through {salesSku}. Use that product's SKU in the file to update it.",
        "FORMULA_DUPLICATE_ACTIVE": "This product has a formula in two places. Ask support to archive one of them first.",
        "FORMULA_CONFLICT": "This product already takes stock from a different stock item than {stockSku}. Change it under Products → Formulas, or give the row another SKU.",
        "FORMULA_CUSTOM": "Uses its own sales formula, unchanged.",
        "BUNDLE_FORMULA_DIFFERS": "Keeps its saved formula, which takes {current}. The import suggested {suggested}.",
        "FORMULA_CUSTOM_OPENING": "Opening quantity can't be placed: this product's sales formula uses more than one stock item or a quantity other than 1. Set opening stock under Stock instead.",
        "BUNDLE_BASE_REQUIRED": "Quantity per sale needs a Takes stock from SKU setting.",
        "BUNDLE_OPENING_STOCK": "A bundle holds no stock of its own. Set Opening quantity on its base product.",
        "BUNDLE_BASE_IS_BUNDLE": "Takes stock from SKU must name a base product, not this product or another bundle.",
        "BUNDLE_BASE_NOT_FOUND": "Takes stock from SKU must name a tracked, priced base row in this file, an existing product with a one-to-one formula, or an active Stock Item.",
        "BUNDLE_QUANTITY_INVALID": "Quantity per sale must be a positive decimal that fits the base stock item's quantity precision.",
        "BUNDLE_NEEDS_TRACKING": "Takes stock from SKU needs a Sales Product with Track inventory on and a sale price.",
        "PROMO_PRICE_INVALID": "The promo price must be greater than zero.",
        "PROMO_NOT_BELOW_REGULAR": "The promo price must be lower than the regular price.",
        "PROMO_PRICE_REQUIRED": "A promotion needs a promo price. Add one, or remove the promotion dates.",
        "PROMO_DATE_INVALID": "Promotion dates must be real dates written YYYY-MM-DD.",
        "PROMO_END_BEFORE_START": "The promotion cannot end before it starts.",
        "ORPHAN_STOCK_ITEM_LEFT": "An older stock item {stockSku} exists with no sales formula linking it to this product. It is left as it is, and this product is sold as itself.",
        "UNTRACK_HAS_STOCK": "Track inventory can't be turned off for this item: it has stock records or a sales formula uses it. Leave Track inventory on, or move its stock first.",
        "BUNDLE_PRODUCT_HAS_BOM": "This product already has a production formula, and a product has one formula. Change it under Products → Formulas, or leave Takes stock from SKU empty."
      },
      "woocommerce": {
        "notConnected": "Connect your WooCommerce store in Settings, under Integrations and E-commerce, to import from it.",
        "hint": "Groot reads your store's products and shows them below to check before anything is saved.",
        "fetch": "Get products from WooCommerce",
        "refetch": "Get products again",
        "reportDrafts": "{count, plural, one {# draft without a price was left out} other {# drafts without a price were left out}}",
        "reportStatus": "{count, plural, one {# product that is neither published nor a draft was left out} other {# products that are neither published nor drafts were left out}}",
        "reportVariable": "{count, plural, one {# product with variations was left out. Variations are not supported yet.} other {# products with variations were left out. Variations are not supported yet.}}",
        "reportUnpriced": "{count, plural, one {# product has no price, so it comes in as stock that is not for sale} other {# products have no price, so they come in as stock that is not for sale}}",
        "reportGeneratedSkus": "{count, plural, one {# product had no SKU, so Groot gave it a code like {example}} other {# products had no SKU, so Groot gave them codes like {example}}}",
        "reportKeptSkus": "{count, plural, one {# product changed its SKU in WooCommerce. Groot kept the code it already uses.} other {# products changed their SKU in WooCommerce. Groot kept the codes it already uses.}}",
        "reportOnSale": "{count, plural, one {# product is} other {# products are}} on promotion in your store. Groot stores each promotion beside the regular price and uses it on invoices dated inside it; for example {sku} is {price} until {date}, then back to its regular price.",
        "reportOnSaleNoEnd": "{count, plural, one {# product is} other {# products are}} on promotion in your store. Groot stores each promotion beside the regular price and uses it on invoices dated inside it; for example {sku} is on promotion at {price}.",
        "reportTruncated": "Your store has {total} products. One import takes up to 1,000, so only the first 1,000 are shown.",
        "reportNotInStore": "WooCommerce does not keep barcodes, cost or stock. Add those later from your purchases.",
        "linkFailed": "Products imported, but Groot could not remember their WooCommerce link. Importing again is safe.",
        "content": {
          "title": "Product content",
          "images": "Product images",
          "sectionTitle": "Section title for {field}",
          "syncing": "Bringing product content from your store...",
          "synced": "{count, plural, one {Product content brought for # product} other {Product content brought for # products}}",
          "syncFailed": "Your products were imported, but their content could not be brought from the store. Import again to try once more.",
          "choiceFailed": "Groot could not save your product content choice, so no content will be brought this time. Your products will still be imported.",
          "fieldLimit": "You can bring up to {max} fields. Leave one out to bring another.",
          "sectionsFull": "{count, plural, one {# product already has 12 content sections, so new sections were not added to it. Remove some in the product form, then import again.} other {# products already have 12 content sections, so new sections were not added to them. Remove some in the product form, then import again.}}",
          "imagesChip": "Images ({count})",
          "rename": "Rename {field}",
          "leaveOut": "Leave out {field}",
          "bringBack": "Bring {field}",
          "tooltip": "Product content brings your store's pictures and product information onto each product. Prices, stock and postings stay the same. Groot remembers your choice for the next import.",
          "excerptHidden": "The text comes with the import."
        },
        "loading": "Getting your store's products...",
        "empty": "Your store has no products to import."
      },
      "infoLabel": "About this import",
      "moreColumns": "More columns",
      "summary": {
        "creates": "{count} new",
        "updates": "{count, plural, one {# update} other {# updates}}",
        "warnings": "{count, plural, one {# warning} other {# warnings}}",
        "errors": "{count, plural, one {# error} other {# errors}}",
        "toImport": "{count} to import",
        "draftsLeftOut": "{count, plural, one {# draft left out} other {# drafts left out}}",
        "statusLeftOut": "{count} unpublished left out",
        "variableLeftOut": "{count} with variations left out",
        "unpriced": "{count} without a price",
        "generatedSkus": "{count, plural, one {# SKU made by Groot} other {# SKUs made by Groot}}",
        "keptSkus": "{count, plural, one {# SKU kept} other {# SKUs kept}}",
        "onSale": "{count} on promotion",
        "truncated": "First 1,000 of {total}",
        "bundlePrices": "Check bundle prices"
      },
      "bundle": {
        "edit": "Edit stock formula",
        "detected": "Bundle",
        "base": "Takes stock from SKU",
        "ownStock": "Its own stock",
        "quantity": "Quantity per sale"
      },
      "resizeColumn": "Resize {column}",
      "resetColumnWidths": "Reset column widths",
      "promo": {
        "short": "Promo {price}",
        "onPromotion": "{price} on promotion",
        "datesFrom": "from {from}",
        "datesUntil": "until {until}",
        "datesRange": "from {from} to {until}",
        "explanation": "Groot stores this promotion beside the regular price and uses it on invoices dated inside it. A customer's own price list still comes first."
      },
      "storeChoice": {
        "price": "Store: {price}",
        "promo": "Store promo: {promo}",
        "useStorePrice": "Use store price",
        "useStorePromo": "Use store promo",
        "keepPrice": "Keep current price",
        "keepPromo": "Keep current promo"
      },
      "columnsReadWithCode": "Your file has no product name column, so we read {name} as the product name and {code} as the SKU.",
      "columnsReadNameOnly": "Your file has no product name column, so we read {name} as the product name."
    },
    "form": {
      "createTitle": "Create Product",
      "editTitle": "Edit Product",
      "saveFailed": "Product could not be saved. Check the fields and try again.",
      "cancel": "Cancel",
      "saving": "Saving...",
      "create": "Create",
      "update": "Update",
      "fields": {
        "name": "Name *",
        "sku": "SKU",
        "barcode": "Barcode",
        "brand": "Brand",
        "modelNumber": "Model",
        "category": "Category",
        "uom": "Unit of measure",
        "customUom": "Custom unit",
        "purchaseCost": "Default cost",
        "currency": "Currency",
        "itemType": "Item type",
        "trackingMode": "Tracking mode",
        "description": "Description",
        "trackInventory": "Track inventory",
        "trackInventoryHelp": "Use stock locations, commitments, Delivery Orders, and movement history for this product.",
        "availableForSale": "Available for sale",
        "availableForSaleHelp": "Show this item in sales invoices and AR sales pickers. Turn off for raw materials, packaging, and internal components.",
        "regularPrice": "Regular price"
      },
      "uomOptions": {
        "unit": "Unit",
        "piece": "Piece",
        "set": "Set",
        "box": "Box",
        "carton": "Carton",
        "pack": "Pack",
        "pair": "Pair",
        "kg": "kg",
        "g": "g",
        "l": "L",
        "ml": "mL",
        "m": "m",
        "roll": "Roll",
        "custom": "Custom"
      },
      "itemTypes": {
        "stocked_product": "Stocked product",
        "service": "Service",
        "component": "Component",
        "assembly": "Assembly",
        "bundle": "Bundle",
        "non_stock": "Non-stock"
      },
      "trackingModes": {
        "none": "None",
        "quantity": "Quantity",
        "lot_batch": "Lot / batch",
        "serial": "Serial"
      },
      "confirmAndSave": "Save and confirm",
      "draftNotice": "This item was found on a supplier document and has not been confirmed yet. Save and confirm to add it to the item master. Turn on Available for sale separately if customers can buy it.",
      "errors": {
        "skuTaken": "That item code is already used by another product.",
        "stockAddonRequired": "Stock management is an add-on that is not switched on for this business. Save the product without stock tracking, or contact us to switch it on."
      },
      "content": {
        "title": "Product content (optional)",
        "help": "Pictures and information for this product. Not used for prices, stock or postings.",
        "images": "Images",
        "imagesHelp": "Images come from your store. You can remove them here. Importing again with images ticked brings the store's images back.",
        "removeImage": "Remove image {number}",
        "sectionTitle": "Section title",
        "sectionText": "Text",
        "moveUp": "Move {title} up",
        "moveDown": "Move {title} down",
        "removeSection": "Remove {title}",
        "addSection": "Add section",
        "fromWooCommerce": "From WooCommerce. Importing again with this field ticked replaces this section.",
        "errors": {
          "incomplete": "Every content section needs a title and some text.",
          "tooMany": "A product can have up to 12 content sections.",
          "tooLong": "A content section is too long.",
          "imageNotKnown": "Images can only be removed here, not added."
        }
      },
      "promotion": {
        "title": "Promotion (optional)",
        "help": "A promo price used automatically on invoices dated inside these dates. A customer's own price list still comes first. Leave a date empty for no start or no end.",
        "price": "Promo price",
        "from": "From",
        "until": "Until",
        "remove": "Remove promotion",
        "errors": {
          "PROMO_PRICE_INVALID": "Enter a promo price above zero.",
          "PROMO_NOT_BELOW_REGULAR": "The promo price must be lower than the regular price.",
          "PROMO_PRICE_REQUIRED": "Add a promo price, or remove the dates.",
          "PROMO_DATE_INVALID": "Enter a valid date.",
          "PROMO_END_BEFORE_START": "The end date cannot be before the start date."
        }
      }
    },
    "stockSetup": {
      "stock": {
        "title": "Current stock",
        "loading": "Loading stock rows...",
        "empty": "No stock rows yet. Initialize stock to load starting quantities by location.",
        "lowStockSummary": "{count} stock row(s) are at or below their low-stock threshold.",
        "lowStockBadge": "Low stock",
        "columns": {
          "product": "Product",
          "location": "Location",
          "onHand": "On hand",
          "committed": "Committed",
          "available": "Available",
          "unavailable": "Unavailable",
          "reorder": "Threshold",
          "actions": "Actions"
        }
      },
      "actions": {
        "opening": "Initialize stock",
        "adjust": "Adjust stock",
        "adjustRow": "Adjust this stock row",
        "viewHistory": "View movement history"
      },
      "settings": {
        "title": "Inventory settings",
        "inventoryMode": "Source of truth",
        "fulfillmentPolicy": "Fulfillment",
        "negativeStockPolicy": "Negative stock",
        "save": "Save settings",
        "saving": "Saving...",
        "inventoryModes": {
          "groot_source_of_truth": "Groot manages stock",
          "external_source_of_truth": "External system manages stock",
          "disabled": "Inventory disabled"
        },
        "fulfillmentPolicies": {
          "invoice_send_fulfills": "Invoice send deducts stock",
          "explicit_delivery_order": "Delivery Order deducts stock"
        },
        "negativeStockPolicies": {
          "block": "Block",
          "warn": "Warn",
          "allow": "Allow"
        },
        "customerHeldStock": {
          "title": "Customer-held stock",
          "description": "Enable bill-and-hold stock tracking. Sales invoices and Delivery Orders can send stock into a customer-held location, and the final release is tracked separately.",
          "disabledWhenNotGroot": "Customer-held stock requires Groot-managed inventory because it creates Groot stock movements and customer-held balances."
        },
        "descriptions": {
          "inventoryMode": {
            "groot_source_of_truth": "Groot is the stock source of truth. Sales-invoice fulfillment can update stock when enabled, and warehouse users manage quantities here.",
            "external_source_of_truth": "Another system owns stock. Groot keeps catalog and reference data, but sales invoices, Delivery Orders, receiving, returns, and manual adjustments do not update Groot stock.",
            "disabled": "Disables stock workflows. Catalog products remain available, but stock levels and stock-moving actions are hidden or blocked."
          },
          "fulfillmentPolicy": {
            "invoice_send_fulfills": "Sending a sales invoice deducts stock immediately. For multiple warehouses, choose the ship-from location on each stock-tracked invoice line.",
            "explicit_delivery_order": "Delivery Orders reserve and issue goods. Sales invoices handle billing; stock moves when the Delivery Order is reserved or posted.",
            "disabledWhenNotGroot": "Fulfillment settings only apply when Groot manages stock. External or disabled inventory modes do not move Groot stock."
          },
          "negativeStockPolicy": {
            "block": "Prevents stock issues that would make available quantity negative.",
            "warn": "Allows negative available stock but should warn users before they continue.",
            "allow": "Allows stock to go negative without blocking."
          },
          "costingMethod": {
            "weighted_average": "Every receipt is blended into one average cost, and every sale takes stock out at that average.",
            "fifo": "Every sale takes stock out at the cost of the oldest receipt still on the shelf, so the stock value follows your most recent purchases."
          }
        },
        "errors": {
          "inventoryModeChangeLocked": "This business already has inventory activity. Contact support to change the inventory source of truth safely.",
          "saveFailed": "Inventory settings could not be saved. Check the current stock setup and try again."
        },
        "costingMethod": "Costing method",
        "costingMethods": {
          "weighted_average": "Weighted average",
          "fifo": "First in first out (FIFO)"
        },
        "costingRecommended": "Recommended by most auditors",
        "costingPreselectedHint": "Recommended. Select it and press Save to apply.",
        "costingStandardNote": "MPERS section 13.18 and MFRS 102 accept both methods. Last in first out (LIFO) is not permitted.",
        "costingSwitchRule": "A business that already holds stock cannot move to FIFO yet. A new business picks its method before its first receipt.",
        "costingLocked": "The costing method cannot change once stock has moved. Contact support to change it safely.",
        "negativeStockFifoFixed": "First in first out blocks sales that exceed stock",
        "costingSwitched": "Switched from weighted average on {date}. The stock you had then was carried into first-in, first-out at its average cost.",
        "activity": {
          "valuationMode": "Stock valuation",
          "valuationModes": {
            "accounting_only": "Accounting only",
            "weighted_average": "Weighted average"
          },
          "receivingDerived": "Set by the books"
        }
      },
      "modeBanners": {
        "external_source_of_truth": {
          "title": "Stock is managed externally",
          "description": "Groot is keeping this stock view read-only. Sales invoices, Delivery Orders, receiving, returns, and manual adjustments will not update Groot stock while this mode is selected.",
          "short": "Stock is managed externally. Switch inventory settings to Groot manages stock before updating stock."
        },
        "disabled": {
          "title": "Inventory is disabled",
          "description": "Stock workflows are turned off for this business. Re-enable inventory in settings before creating stock rows or adjustments.",
          "short": "Inventory is disabled. Re-enable inventory before updating stock."
        }
      },
      "form": {
        "openingTitle": "Initialize stock",
        "adjustmentTitle": "Adjust stock",
        "product": "Product",
        "productPlaceholder": "Select product",
        "location": "Location",
        "locationPlaceholder": "Select location",
        "noOpeningLocations": "All locations for this product already have stock rows. Use Adjust stock instead.",
        "currentStatus": "Current stock status",
        "targetQty": "Opening quantity",
        "adjustmentType": "Adjustment type",
        "adjustmentIncrease": "Increase stock",
        "adjustmentDecrease": "Decrease stock",
        "adjustmentQty": "Quantity",
        "adjustmentQtyHelp": "Enter a positive quantity. Groot applies the increase or decrease selected above.",
        "quantityMustBePositive": "Enter a valid positive quantity.",
        "unitCost": "Unit cost",
        "currency": "Currency",
        "unitCostHelp": "Prefilled from the product default cost. Use the actual cost for opening stock or positive stock-in adjustments; stock decreases use the current stock cost.",
        "unitCostOpeningHelp": "Prefilled from the product default cost. Use the actual cost for this opening balance.",
        "unitCostAdjustmentHelp": "Prefilled from this stock row's current weighted average cost. For stock increases, enter the actual incoming cost; stock decreases use the current stock cost.",
        "reorderPoint": "Low-stock threshold",
        "reorderPointHelp": "Show a low-stock warning when available quantity is at or below this number.",
        "negativeStockWarningTitle": "Available stock will go negative",
        "negativeStockWarningMessage": "This adjustment will leave available stock at {quantity}. The current policy is Warn, so confirm before saving.",
        "negativeStockWarningConfirm": "Continue",
        "negativeStockWarningCancel": "Review adjustment",
        "negativeStockBlocked": "This adjustment would leave available stock at {quantity}. Negative stock is blocked for this business.",
        "ledgerAccountMissingAdjustment": "Your chart of accounts has no inventory adjustments account, so this stock change has nowhere to post. Add an expense account for inventory adjustments under Accounting → Chart of Accounts, then try again.",
        "ledgerAccountMissingOpeningBalance": "Your chart of accounts has no owner's equity account, so this opening stock balance has nowhere to post. Add an equity account under Accounting → Chart of Accounts, then try again.",
        "ledgerAccountIsHeading": "The account this stock change posts to has sub-accounts, so it cannot take postings. Choose one of its sub-accounts under Accounting → Chart of Accounts → Posting accounts, then try again.",
        "notes": "Notes",
        "cancel": "Cancel",
        "saving": "Saving...",
        "save": "Save",
        "saveFailed": "Stock update failed. Check the product, location, and available quantity.",
        "reason": "Reason",
        "reasons": {
          "manual_adjustment": "Stocktake or correction",
          "free_of_charge": "Received free of charge",
          "owner_supplied": "Supplied by owner",
          "wastage": "Wastage or spoilage",
          "rnd_testing": "R&D and testing",
          "staff_meal": "Staff meal",
          "sample_marketing": "Sample given away"
        },
        "reasonHelp": {
          "manual_adjustment": "A count that differs from the books. Posts the difference to Inventory Adjustments.",
          "free_of_charge": "Samples, promo stock or a voucher you were given. Cost is 0, nothing posts, and the average cost blends down.",
          "owner_supplied": "Bought with the owner’s own money. Enter the unit cost paid; it posts to the related-party payable so the business owes the owner.",
          "wastage": "Spoiled, dropped or expired. Leaves stock at book cost and posts to Inventory Adjustments.",
          "rnd_testing": "Used to develop or test a product. Leaves stock at book cost and posts to Other Expenses.",
          "staff_meal": "Eaten by staff. Leaves stock at book cost and posts to Other Expenses.",
          "sample_marketing": "Given away to customers or at events. Leaves stock at book cost and posts to Marketing & Advertising."
        },
        "reasonCostRequired": "Enter the unit cost actually paid, above zero.",
        "reasonFreeCost": "Received free: the unit cost is 0.",
        "ledgerAccountMissingRole": "This reason posts to the {role} account, which is not set up yet. Choose it under Accounting → Chart of Accounts → Posting accounts, then try again.",
        "noCost": "No cost (free or sample)",
        "noCostHelp": "Tick this only if the stock really cost nothing. It is carried with no cost, so sales of it will not show a margin.",
        "openingCostRequired": "Enter the unit cost, or tick \"No cost (free or sample)\". Stock with no cost would make every sale of it look like pure profit.",
        "adjustmentCostRequired": "This item has no recorded cost. Enter the unit cost, or choose the reason \"Received free of charge\"."
      },
      "adjustment": {
        "defaultReason": "Manual stock adjustment"
      },
      "history": {
        "title": "Movement history",
        "loading": "Loading movement history...",
        "empty": "No movements recorded for this product and location yet.",
        "close": "Close",
        "columns": {
          "date": "Date",
          "type": "Type",
          "reason": "Reason",
          "sourceType": "Source type",
          "source": "Source",
          "quantity": "Qty",
          "balance": "Before / after"
        },
        "types": {
          "stock_in": "Stock In",
          "stock_out": "Stock Out",
          "adjustment": "Adjustment",
          "transfer": "Transfer"
        },
        "reasons": {
          "delivery_order_post": "Delivery Order posted",
          "delivery_order_void": "Voided Delivery Order reversal",
          "opening_balance": "Opening balance",
          "manual_adjustment": "Manual adjustment",
          "restockable": "Returned to sellable stock",
          "damaged": "Returned damaged",
          "production_component_issue": "Production component issue",
          "production_finished_good": "Production finished good",
          "free_of_charge": "Received free of charge",
          "owner_supplied": "Supplied by owner",
          "wastage": "Wastage or spoilage",
          "rnd_testing": "R&D and testing",
          "staff_meal": "Staff meal",
          "sample_marketing": "Sample given away"
        },
        "sources": {
          "manual": "Manual adjustment",
          "opening": "Opening balance"
        },
        "sourceTypes": {
          "sales_invoice": "Sales Invoice",
          "credit_note": "Credit Note",
          "delivery_order": "Delivery Order",
          "ap_invoice": "AP Invoice",
          "production_run": "Production Run",
          "manual_adjustment": "Manual",
          "opening_balance": "Opening Balance"
        }
      }
    },
    "deliveryOrders": {
      "title": "Delivery Orders",
      "description": "Reserve and issue goods separately from sales invoice financial posting.",
      "listTitle": "Delivery Order list",
      "loading": "Loading Delivery Orders...",
      "empty": "No Delivery Orders yet.",
      "createTitle": "Create Delivery Order",
      "createFailed": "Delivery Order could not be created. Check the invoice and stock locations.",
      "actionFailed": "Delivery Order action failed. Check available stock and document status.",
      "alreadyExists": "Delivery Order {number} already exists for this invoice.",
      "noEligibleInvoices": "No sales invoices are ready for a new Delivery Order.",
      "invoice": "Sales invoice",
      "invoicePlaceholder": "Select sales invoice",
      "location": "Ship from",
      "defaultLocation": "Default ship from",
      "locationPlaceholder": "Default location",
      "deliveryDate": "Delivery date",
      "voidReason": "Voided from Products inventory workflow",
      "lineCount": "{count, plural, one {# line} other {# lines}}",
      "createPreview": "Creates a draft Delivery Order for {count, plural, one {# stock-tracked line} other {# stock-tracked lines}}. Stock does not move until you reserve or post it.",
      "lineAllocationUnavailable": "Line allocation data is not available yet. Sync Convex, refresh this page, then try Choose per line again.",
      "lineLocationRequired": "Choose a source location for every Delivery Order line.",
      "negativeStockBlocked": "This action would leave one or more stock rows negative. Negative stock is blocked for this business.",
      "negativeStockWarningTitle": "Available stock will go negative",
      "negativeStockWarningMessage": "The current policy is Warn. Review the affected lines before continuing.",
      "createNegativeStockWarningTitle": "Reserve/post will go negative",
      "createNegativeStockWarningMessage": "Draft creation does not move stock, but the current source allocation will go negative when reserved or posted.",
      "destination": {
        "title": "Delivery destination",
        "standard": "Standard delivery",
        "customerHeld": "Customer-held stock",
        "standardDescription": "Post the Delivery Order as a normal customer shipment.",
        "customerHeldDescription": "Post the Delivery Order into this customer's held-stock balance instead of treating final delivery as complete."
      },
      "customerHeld": {
        "destinationLabel": "Customer-held destination",
        "destinationPlaceholder": "Select customer-held location",
        "createDestination": "Create destination",
        "creatingDestination": "Creating...",
        "destinationRequired": "Choose the customer-held destination for this Delivery Order.",
        "customerRequired": "Customer-held Delivery Orders require a linked customer.",
        "createFailed": "Customer-held stock location could not be created.",
        "disabled": "Enable customer-held stock in Inventory settings before choosing this destination."
      },
      "modeBanners": {
        "invoice_send_fulfills": {
          "title": "Delivery Orders are not the stock-deduction step",
          "description": "This business deducts stock when sales invoices are sent. For customer-held stock, use the invoice fulfillment section; switch fulfillment to Delivery Order deducts stock before using DO stock workflows.",
          "short": "This business deducts stock on invoice send. Switch fulfillment to Delivery Order deducts stock before using Delivery Orders."
        },
        "external_source_of_truth": {
          "title": "Delivery Orders are reference-only",
          "description": "Stock is managed externally, so Groot will not create, reserve, post, void, or otherwise move stock from Delivery Orders.",
          "short": "Stock is managed externally. Delivery Orders cannot move Groot stock."
        },
        "disabled": {
          "title": "Delivery Orders are disabled",
          "description": "Inventory is disabled for this business, so Delivery Order stock workflows are blocked.",
          "short": "Inventory is disabled. Delivery Orders cannot move stock."
        }
      },
      "actions": {
        "create": "Create Delivery Order",
        "reserve": "Reserve",
        "post": "Post",
        "cancel": "Cancel",
        "void": "Void",
        "close": "Close",
        "creating": "Creating...",
        "processing": "Processing...",
        "viewExisting": "View existing"
      },
      "tooltips": {
        "reserve": "Reserve stock",
        "post": "Post / issue stock",
        "cancel": "Cancel Delivery Order",
        "void": "Void and reverse stock"
      },
      "allocation": {
        "title": "Source allocation",
        "single": "One location",
        "perLine": "Choose per line",
        "perLineTitle": "Line source locations",
        "perLineDescription": "Override the default location when a product needs to ship from a different warehouse.",
        "available": "{count} available"
      },
      "columns": {
        "number": "Number",
        "source": "Source",
        "customer": "Customer",
        "status": "Status",
        "lines": "Lines",
        "actions": "Actions"
      },
      "status": {
        "draft": "Draft",
        "reserved": "Reserved",
        "posted": "Posted",
        "cancelled": "Cancelled",
        "voided": "Voided"
      },
      "details": {
        "title": "Delivery Order lines",
        "description": "Products and source locations included in this Delivery Order.",
        "product": "Product",
        "quantity": "Qty",
        "location": "Ship from",
        "reservation": "Reservation",
        "reserved": "Reserved",
        "notReserved": "Not reserved",
        "inOrderUnit": "{quantity} {unit} of the order",
        "ratio": "1 {unit} = {ratio} {orderUnit}",
        "onInvoice": "{quantity} {unit} on the invoice",
        "overOrdered": "{quantity} {unit} over the ordered quantity"
      },
      "confirm": {
        "reserve": {
          "title": "Reserve stock?",
          "message": "Groot will commit these quantities to this Delivery Order. On hand stays the same; available stock decreases."
        },
        "post": {
          "title": "Post Delivery Order?",
          "message": "Groot will issue these goods from inventory. On hand stock decreases, and any reservation is released."
        },
        "cancel": {
          "title": "Cancel Delivery Order?",
          "message": "Groot will cancel this Delivery Order. If stock is reserved, the committed quantities are released."
        },
        "void": {
          "title": "Void Delivery Order?",
          "message": "Groot will reverse this posted Delivery Order and add the issued quantities back to the source locations."
        }
      },
      "fromOrder": {
        "action": "Create from sales order",
        "title": "Create delivery order from a sales order",
        "order": "Sales order",
        "orderPlaceholder": "Select sales order",
        "noEligible": "No sales order is ready for a delivery. An order appears here once it is accepted and has catalogue items still to deliver. It does not appear if everything was delivered, if it has only free-text lines, or if its items leave stock and your business moves stock on the invoice instead of on a delivery order.",
        "linesTitle": "Quantity to deliver now",
        "progress": "Ordered {ordered}, delivered {delivered}, still to deliver {remaining}",
        "quantityLabel": "Quantity to deliver for {description}",
        "errors": {
          "exceeds": "That is more than the order still has to deliver. Lower the quantity and try again.",
          "exceeds_remaining": "Only {remaining} is still to deliver on this line.",
          "not_positive": "Enter a quantity above zero, or clear it to leave this line out.",
          "not_a_number": "Enter a valid quantity.",
          "createFailed": "The delivery order could not be created. Check the sales order, the quantities and the ship from location.",
          "sourceVoided": "The sale behind this delivery order was voided, deleted or cancelled, so no stock can move against it. Cancel or void the delivery order instead.",
          "not_representable": "That quantity cannot be written exactly in the order's unit. Use fewer decimal places.",
          "unitNotConvertible": "This item cannot be delivered in that unit. Deliver it in the unit it is stocked in.",
          "deliveredUnitMismatch": "The units on this order, its invoice and the deliveries already made cannot be converted into each other, so what is left to deliver cannot be worked out. Correct the unit on the invoice line, then try again.",
          "invoiceNotRepresentable": "This invoice line's quantity cannot be written exactly in the unit the item is stocked in. Correct the quantity on the invoice line, then try again.",
          "linesInUnrelatedUnits": "This order has the same item in two units Groot cannot add together. Change the units on the order so they match, then try again.",
          "invoiceLinesInUnrelatedUnits": "This invoice has the same item in two units Groot cannot add together. Change the units on the invoice so they match, then try again.",
          "deliveredUnitUnknown": "An earlier delivery of this item was recorded without a unit, and the item is on lines in more than one unit, so Groot cannot tell which unit it was counted in. Make the units on the lines match, or contact support.",
          "not_representableTry": "That quantity cannot be written exactly in the order's unit. Try {options} {unit} instead.",
          "invoiceNotRepresentableTry": "This invoice line's quantity cannot be written exactly in the unit the item is stocked in. Change the quantity on the invoice line to {options} {unit}, then try again.",
          "stockUnitUnconfirmed": "Set the stock unit of this item first. It has no stock unit yet, so Groot cannot convert a delivery in another unit into the unit it is stocked in.",
          "exceedsTolerance": "This order may still take {allowed}, including its {percent}% tolerance. Lower the quantity, or replace the order with the customer's amended PO.",
          "exceeds_tolerance": "Only {allowed} may still be delivered on this line, including this order's {percent}% tolerance.",
          "featureOff": "Delivery orders are part of the Invoices plan, and it is not switched on for this business. Contact support to add it.",
          "nothingLeft": "There is nothing left to deliver on this order.",
          "periodClosed": "That delivery date is in a closed accounting period, so stock cannot leave on it. Choose a date in an open period.",
          "stockAlreadyRelieved": "The invoice for this sale already took this stock out when it was sent, so this delivery would take it out a second time. Cancel this delivery order.",
          "stockAddonOff": "Delivering goods out of stock needs the Stock add-on, and it is not switched on for this business. Contact support to add it."
        },
        "loadMore": "Load older orders",
        "orderGone": "That sales order is no longer available to deliver (someone else delivered or cancelled it). Pick another.",
        "loadFailed": "Some sales orders could not be loaded, so what is deliverable could not be checked. Your entries are kept. Close and reopen to retry.",
        "progressWithUnit": "Ordered {ordered} {unit}, delivered {delivered} {unit}, still to deliver {remaining} {unit}",
        "convertedLine": "{quantity} {unit} is {converted} {orderUnit} of the order",
        "estimate": "At the order price: {amount} (estimate)",
        "blockedTitle": "Cannot be delivered from here yet",
        "overOrdered": "{quantity} {unit} over the ordered quantity, within this order's tolerance.",
        "toleranceNote": "Over-delivery tolerance on this order: {percent}%",
        "unitLabel": "Unit for {description}",
        "stockUnit": {
          "unset": "No stock unit is set for this item, so it can only be delivered in the order's own unit. Choose the unit its stock is counted in to deliver in another unit.",
          "label": "Stock unit for {description}",
          "confirm": "Set stock unit",
          "saving": "Saving...",
          "hint": "Stock already received or moved is read as being in this unit. It cannot be changed once stock has moved, so check it first.",
          "failed": "The stock unit could not be set. Check the item and try again.",
          "financeOnly": "No stock unit is set for this item. Ask an owner or finance admin to set it before delivering in another unit."
        },
        "lineBlocked": "This product cannot be delivered until its stock setup is fixed, for example an inactive item in its formula. Open it under Products to check.",
        "noEligibleOwn": "No sales order of yours is ready for a delivery. An order appears here once it is accepted and has catalogue items still to deliver. It does not appear if everything was delivered, if it has only free-text lines, or if its items leave stock and your business moves stock on the invoice instead of on a delivery order. Only your own orders are listed.",
        "loadingOrders": "Looking for orders to deliver...",
        "ordersFailed": "The orders could not be read. Close this window and try again."
      },
      "pdf": {
        "download": "Download delivery order PDF",
        "failed": "The delivery order PDF could not be created. Please try again.",
        "title": "DELIVERY ORDER",
        "number": "Delivery order no.",
        "date": "Delivery date",
        "customer": "Deliver to",
        "source": "Order reference",
        "shipFrom": "Ship from",
        "lineNo": "No.",
        "description": "Description",
        "quantity": "Qty",
        "location": "From",
        "receivedBy": "Goods received in good order by the customer",
        "name": "Name",
        "signature": "Signature and company stamp",
        "receivedDate": "Date received",
        "voided": "VOIDED",
        "customerPo": "Your PO"
      },
      "proof": {
        "title": "Proof of delivery",
        "description": "Keep the customer's signed copy with this Delivery Order, with who received the goods and when.",
        "signedCopyReceived": "Signed copy received",
        "signedCopy": "Signed copy",
        "receivedBy": "Received by",
        "receivedByPlaceholder": "Name of the person who signed",
        "receivedDate": "Date received",
        "recordedLabel": "Recorded",
        "recordedBy": "By {name} on {when}",
        "recordedOn": "On {when}",
        "fileFormats": "PDF, JPG, PNG or HEIC, up to 10 MB.",
        "fileRequired": "Choose the signed copy to upload.",
        "open": "Open signed copy",
        "opening": "Opening...",
        "openFailed": "The signed copy could not be opened. Please try again.",
        "replace": "Replace signed copy",
        "replaceReason": "Reason for replacing",
        "replaceReasonPlaceholder": "For example, the first scan was cut off",
        "replaceNote": "The earlier copy is kept in the audit trail.",
        "save": "Save proof of delivery",
        "saving": "Saving...",
        "cancel": "Cancel",
        "saved": "Proof of delivery saved.",
        "replacedToast": "Signed copy replaced.",
        "unchanged": "This signed copy is already recorded.",
        "uploadFailed": "The signed copy could not be uploaded. Please try again.",
        "saveFailed": "Proof of delivery could not be saved. Please try again.",
        "refusals": {
          "DELIVERY_ORDER_NOT_DELIVERED": "A signed copy can be recorded once this Delivery Order is posted.",
          "DELIVERY_ORDER_VOIDED": "This Delivery Order was voided, so a signed copy can no longer be recorded.",
          "INVALID_FILE_TYPE": "That file cannot be used. Choose a PDF, JPG, PNG or HEIC file.",
          "FILE_TOO_LARGE": "That file is too large. The limit is 10 MB.",
          "RECEIVED_BY_REQUIRED": "Enter the name of the person who received the goods.",
          "RECEIVED_BY_TOO_LONG": "That name is too long. Use 120 characters or fewer.",
          "RECEIVED_DATE_INVALID": "Enter the date the goods were received.",
          "RECEIVED_DATE_IN_FUTURE": "The date received cannot be in the future.",
          "REPLACE_REASON_REQUIRED": "Enter a reason for replacing the signed copy.",
          "REPLACE_REASON_TOO_LONG": "That reason is too long. Use 500 characters or fewer.",
          "RECEIVED_BEFORE_DELIVERY": "The date received cannot be earlier than the delivery date on this order."
        }
      },
      "activity": {
        "source": "Made from",
        "lines": "Lines",
        "stockCost": "Stock cost",
        "reason": "Reason",
        "returnedStockCost": "Returned stock cost",
        "returnedAs": "Returned as",
        "stockMovements": "Stock movements",
        "dispositions": {
          "restockable": "Sellable stock",
          "damaged": "Damaged",
          "no_stock_movement": "Not returned to stock"
        }
      },
      "poNumber": "PO: {number}",
      "noStockMoved": "No stock moved",
      "billing": {
        "action": "Create invoice",
        "title": "Create an invoice from deliveries",
        "description": "One invoice line for each delivered line, in the unit it was delivered in, at the price agreed on the order. This makes a draft: nothing is sent.",
        "loading": "Reading the deliveries...",
        "unavailable": "You cannot create invoices from deliveries.",
        "customer": "Customer",
        "order": "Sales order",
        "yourPo": "Your PO",
        "columns": {
          "delivery": "Delivery",
          "item": "Item",
          "quantity": "Quantity",
          "price": "Price",
          "amount": "Amount"
        },
        "subtotal": "Subtotal",
        "tax": "Tax",
        "total": "Total",
        "invoiceDate": "Invoice date",
        "invoiceDateHint": "Defaults to the delivery date ({date}).",
        "terms": "Payment terms",
        "dueDate": "Due date",
        "termsDiffer": "These terms ({chosen}) differ from the order's ({order}).",
        "cancel": "Cancel",
        "confirm": "Create draft invoice",
        "created": "Draft invoice {number} created",
        "failed": "We could not create the invoice. Nothing was changed. Please try again.",
        "selected": "{count, plural, one {# delivery selected} other {# deliveries selected}}",
        "clearSelection": "Clear selection",
        "createSelected": "Create invoice",
        "select": "Select {number}",
        "invoicedBy": "Invoiced: {number}",
        "voidRefused": "This delivery order is billed by an invoice. Void or credit the invoice first, then void the delivery order.",
        "refusals": {
          "generic": "We could not create this invoice. Nothing was changed.",
          "NO_DELIVERIES": "Choose at least one delivery order to invoice.",
          "TOO_MANY_DELIVERIES": "One invoice can bill at most {max} delivery orders. Choose fewer.",
          "DELIVERY_NOT_FOUND": "One of these delivery orders could not be found. Refresh the page and try again.",
          "DELIVERY_NOT_POSTED": "Delivery order {deliveryOrderNumber} is not posted yet, so there is nothing delivered to invoice. Post it first.",
          "DELIVERY_ALREADY_INVOICED": "Delivery order {deliveryOrderNumber} is already billed by invoice {invoiceNumber}. Void or delete that invoice first to bill it again.",
          "DELIVERY_NOT_FROM_ORDER": "Delivery order {deliveryOrderNumber} was not raised from a sales order, so there is no agreed price to invoice.",
          "DELIVERY_LINE_UNRESOLVED": "A line of delivery order {deliveryOrderNumber} no longer matches its sales order, so its price cannot be found.",
          "DELIVERIES_MIXED": "These deliveries belong to different sales orders. Create one invoice for each order, so each one carries its own PO number.",
          "ORDER_ALREADY_INVOICED": "Sales order {orderNumber} was already invoiced whole, so its deliveries cannot be invoiced again.",
          "FIXED_DISCOUNT_NOT_PRORATABLE": "The order gives a fixed discount for the whole quantity, and delivery order {deliveryOrderNumber} is only part of it, so the discount cannot be split. Invoice the whole quantity in one delivery, or change the order.",
          "SALES_UNIT_NOT_CONVERTIBLE": "Delivery order {deliveryOrderNumber} is counted in a unit that does not convert to the unit on the order, so it cannot be priced.",
          "PRICE_UNIT_NOT_CONVERTIBLE": "The order price cannot be expressed exactly in the unit of delivery order {deliveryOrderNumber}.",
          "SALES_QUANTITY_NOT_REPRESENTABLE": "The quantity on delivery order {deliveryOrderNumber} cannot be converted exactly into the order's unit.",
          "LINE_AMOUNT_ROUTES_DISAGREE": "The amount of delivery order {deliveryOrderNumber} could not be confirmed two ways, so no invoice was made. Contact support.",
          "INVALID_INVOICE_DATE": "The invoice date must be a real date.",
          "INVALID_DUE_DATE": "The due date must be a real date on or after the invoice date.",
          "DUE_DATE_REQUIRED": "Custom terms have no day count, so choose a due date.",
          "FEATURE_NOT_ENABLED": "Invoicing is not enabled for this business.",
          "INVOICE_LIMIT_REACHED": "This month's invoice limit is reached. Upgrade to create more invoices.",
          "PRICE_OVERRIDE_REASON_REQUIRED": "A price on this order differs from the catalogue. Fix the order line or the catalogue price first."
        }
      },
      "notInvoiced": {
        "title": "Delivered, not yet invoiced",
        "description": "Posted deliveries that no invoice bills yet, oldest first. This is a reminder: nothing is booked and nothing is blocked.",
        "empty": "Every posted delivery has been invoiced.",
        "loading": "Loading...",
        "columns": {
          "delivery": "Delivery",
          "customer": "Customer",
          "goods": "Goods",
          "since": "Since delivery",
          "amount": "Would bill (estimate)",
          "actions": "Actions"
        },
        "days": "{count, plural, =0 {today} one {# day ago} other {# days ago}}",
        "billedWhole": "Its order was invoiced whole",
        "more": "Show more",
        "advisory": "The amount is an estimate at the order price. Revenue is recognised on the invoice date; for stock goods the cost of sales is already booked at delivery."
      },
      "draftingDescription": "Raise a delivery for an accepted sales order. You can cancel it while it is a draft. Finance reserves the stock and posts it.",
      "cancelNotDraft": "Finance has already moved this delivery on, so it can no longer be cancelled here. Ask an owner or finance admin if it still needs to be undone.",
      "emptyOwn": "No delivery orders of yours yet. Only your own are listed."
    },
    "priceTiers": {
      "title": "Customer price tiers",
      "subtitle": "Base catalog price is {price}. Tier prices use effective-dated revisions.",
      "newTierPlaceholder": "New tier name",
      "addTier": "Add tier",
      "loading": "Loading price tiers...",
      "noTiersTitle": "No price tiers yet",
      "noTiersDescription": "Create the default tier before setting tier-specific product prices.",
      "createDefault": "Create default tier",
      "defaultCreated": "Default price tier created.",
      "tierCreated": "Price tier created.",
      "priceSaved": "Price saved.",
      "saveFailed": "Could not save price tier changes.",
      "defaultBadge": "Default",
      "currentRevision": "Current: {price} from {date}",
      "fallsBackToCatalog": "Falls back to catalog price {price}",
      "notesPlaceholder": "Optional note",
      "savePrice": "Save price",
      "revisionHistory": "Revision history",
      "noRevisions": "No revisions for this tier yet.",
      "effectiveFrom": "Effective from {date}",
      "createdByAt": "By {user} at {time}",
      "changeHistory": "Pricing change history",
      "loadingHistory": "Loading pricing history...",
      "noChangeEvents": "No pricing changes recorded yet.",
      "eventActorAt": "{user} - {time}",
      "invoiceBadge": "Invoice {invoice}",
      "overrideEventDetail": "Resolved {resolved} -> override {override}. Reason: {reason}",
      "unknownUser": "Unknown user",
      "errors": {
        "nameRequired": "Give the price tier a name.",
        "duplicateTierName": "You already have a price tier with that name. Pick a different one.",
        "tierNotFound": "We couldn't find that price tier. Refresh the page and try again.",
        "itemNotFound": "We couldn't find this product. It may have been archived. Refresh the page and try again.",
        "currencyMismatch": "This price is in a different currency from the product. Enter the price in the product's own currency.",
        "duplicateRevision": "There's already a price for this tier starting on that date. Change the date, or edit the existing price.",
        "invalidPrice": "Enter a price of zero or more.",
        "invalidDate": "Pick a valid start date for this price."
      }
    },
    "purchaseHistory": {
      "title": "Purchase history"
    },
    "boughtAs": {
      "title": "Bought as",
      "description": "Supplier-specific packs that feed this Stock Item.",
      "loading": "Loading supplier packs...",
      "unknownSupplier": "Unknown supplier",
      "brand": "Brand: {brand}",
      "observedAt": "Document {date}",
      "documentLink": "Open document",
      "contents": "Pack contents",
      "packContents": "1 {purchaseUom} = {quantity} {baseUom}",
      "lastBaseCost": "Last base-unit cost",
      "noCost": "No source cost yet",
      "status": {
        "active": "Active",
        "superseded": "Superseded",
        "archived": "Archived",
        "pending": "Pending",
        "resolved": "Resolved",
        "dismissed": "Dismissed"
      }
    },
    "roles": {
      "views": {
        "salesProducts": "Sales Products",
        "salesProductsDescription": "Items customers can buy. Pricing, taxes, and sales channels live here.",
        "stockItems": "Stock Items",
        "stockItemsDescription": "Items you count, receive, produce, consume, or value in inventory.",
        "supplierItems": "Supplier Items",
        "supplierItemsDescription": "What each supplier calls an item, mapped to a confirmed Stock Item."
      },
      "badges": {
        "salesOnly": "Sales only",
        "sellsFromStock": "Sells from stock",
        "sellsFromStockOne": "Takes {quantity} × {item} per sale",
        "sellsFromStockMany": "{count, plural, one {Takes # stock item per sale} other {Takes # stock items per sale}}",
        "stockOnly": "Stock only",
        "both": "Sales and Stock",
        "supplierAlias": "Supplier item",
        "needsSetup": "Setup needed"
      },
      "picker": {
        "stockItemTitle": "Choose a Stock Item",
        "ingredientTitle": "Choose a Stock Item",
        "stockItemPlaceholder": "Search Stock Items by name, code, or supplier text",
        "defaultHint": "Default results show Stock Items only, so purchase lines cannot land on sales-only products by mistake.",
        "showAllItems": "Show all items",
        "hideAllItems": "Show Stock Items only",
        "showAllHint": "Use this only when an existing Sales Product should be converted or linked to stock.",
        "disabledReasonLabel": "Why disabled",
        "noStockItems": "No matching Stock Items.",
        "noAllItems": "No matching items.",
        "createStockIngredient": "Create Stock Item",
        "createStockIngredientHint": "Creates a Stock Item that is not for sale until you enable Sales separately.",
        "sourceFactsTitle": "Supplier evidence stays visible",
        "sourceFactsDescription": "Confirm the Stock Item from the supplier code, description, pack, and cost. Do not infer stock from a similar product name."
      },
      "createStockIngredient": {
        "title": "Create Stock Item",
        "description": "Use this for raw materials, packaging, or bought items that need to be counted before they can be received.",
        "nameLabel": "Stock Item name",
        "namePlaceholder": "e.g. Chicken thigh",
        "codeLabel": "Internal item code",
        "codePlaceholder": "Optional. Leave blank to generate one.",
        "baseUnitLabel": "Base unit",
        "baseUnitPlaceholder": "e.g. kg, pcs, bottle",
        "baseUnitRequired": "Base unit is required before this item can be confirmed or received.",
        "notForSaleNote": "New Stock Items are not shown on sales invoices. Enable Sales later if customers can buy the same item.",
        "submit": "Create Stock Item",
        "creating": "Creating...",
        "cancel": "Cancel",
        "success": "Stock Item created.",
        "error": "The Stock Item could not be created. Check the name and base unit, then try again."
      },
      "disabledReasons": {
        "salesOnly": "This is a Sales Product only. Enable Stock before it can receive, produce, or consume inventory.",
        "stockRoleDisabled": "Stock is not enabled for this item.",
        "baseUnitRequired": "This Stock Item needs a base unit before stock can move.",
        "archived": "Archived items cannot be selected for new stock setup.",
        "draft": "Draft items must be confirmed before they can be used for stock.",
        "inactive": "Inactive items cannot be selected for this workflow.",
        "inventoryDisabled": "Inventory workflows are disabled for this business.",
        "foreignOrUnavailable": "This item is unavailable.",
        "supplierMissing": "Choose a supplier before saving a durable Supplier Item mapping.",
        "supplierMappingRequired": "Map this supplier description to a Stock Item before confirming the pack.",
        "packContentsRequired": "Enter the pack contents before this supplier pack can affect stock.",
        "formulaRequiresStockItem": "Recipes can use Stock Items only.",
        "reliefTargetRequired": "Sales stock relief needs a Stock Item target and a positive quantity.",
        "stockEvidenceLocked": "This Stock Item already has stock evidence. Use a replacement or correction route instead of editing the base unit in place.",
        "activeReliefLinks": "One or more Sales Products relieve stock from this item. Move or archive those links before disabling Stock.",
        "activeSupplierPacks": "Active Supplier Items or packs target this Stock Item. Review those mappings before disabling Stock.",
        "formulaReferences": "A formula uses this Stock Item. Update the formula before disabling Stock.",
        "unrepresentableQuantity": "The quantity cannot be represented at this Stock Item precision."
      },
      "setupActions": {
        "enableStock": "Enable Stock",
        "addBaseUnit": "Add base unit",
        "openItemSetup": "Open item setup",
        "createStockIngredient": "Create Stock Item",
        "chooseStockItem": "Choose a Stock Item",
        "reviewSupplierItem": "Review Supplier Item",
        "enterPackContents": "Enter pack contents",
        "addReliefLink": "Add stock relief link",
        "replaceReliefLink": "Replace relief link",
        "archiveReliefLink": "Archive relief link",
        "openInventorySettings": "Open inventory settings",
        "useReplacementRoute": "Use replacement route",
        "useCorrectionRoute": "Use correction route"
      },
      "reliefLink": {
        "title": "Sales stock relief",
        "description": "Choose which Stock Item is relieved when this Sales Product is sold, and how much stock leaves per sales unit.",
        "salesProductLabel": "Sales Product",
        "stockItemLabel": "Stock Item relieved",
        "quantityLabel": "Quantity relieved per sales unit",
        "quantityPlaceholder": "e.g. 1",
        "selfReliefBadge": "Relieves itself",
        "linkedReliefBadge": "Relieves another Stock Item",
        "noRouteTitle": "No stock route set",
        "noRouteDescription": "Groot will not guess a Stock Item, formula, or SKU match. Link this Sales Product to a Stock Item with a sale formula.",
        "directResaleHelp": "When the item sold is the same item you count in stock, link them with a one-component formula of quantity 1.",
        "sharedTargetHelp": "Multiple Sales Products may relieve the same Stock Item when channels or product names differ.",
        "saveLink": "Save relief link",
        "saving": "Saving...",
        "archiveLink": "Archive link",
        "targetRequired": "Choose a Stock Item to relieve.",
        "quantityRequired": "Enter a positive quantity per sales unit.",
        "snapshotNote": "Posted sales keep the Stock Item and quantity resolved at posting time. Later setup changes affect future sales only.",
        "invoiceLineGuidance": "This Sales Product has no stock relief route. Groot will not guess from its name, SKU, or formula. Open Formulas to choose the Stock Items consumed per sale.",
        "invoiceLineGuidanceLink": "Open Products Sales role",
        "invoiceLineGuidanceFormula": "This Sales Product has no stock route. Groot will not guess from its name, SKU, or recipe. Open Formulas to choose the Stock Items consumed per sale.",
        "invoiceLineGuidanceFormulaLink": "Open Formulas"
      },
      "knownErrors": {
        "baseUnitRequired": "Add a base unit before enabling Stock or receiving this item.",
        "stockRoleRequired": "Choose a Stock Item. Sales-only products cannot be used for stock movement.",
        "salesRoleRequired": "Enable Sales before this item can be selected on a sales invoice.",
        "reliefTargetRequired": "Choose the Stock Item and quantity this Sales Product should relieve.",
        "invalidReliefQuantity": "Enter a positive stock relief quantity that fits the Stock Item precision.",
        "duplicateActiveReliefLink": "This Sales Product already has an active stock relief link. Replace or archive the existing link first.",
        "stockDisableBlocked": "Stock cannot be disabled while evidence, formulas, supplier packs, or relief links still depend on it.",
        "roleWriteLocked": "This role change is locked by posted stock evidence. Use the guided replacement or correction route.",
        "baseUnitLocked": "Base unit is locked: stock has already been received or moved in the current unit. Create a replacement Stock Item, or post a correction.",
        "baseUnitFormulaDependency": "A sale formula uses this item in its current unit and cannot be converted to the new one. Update the formula first, or choose a unit of the same family (for example kg to g).",
        "supplierTargetInvalid": "Supplier Items must map to a valid Stock Item.",
        "formulaTargetInvalid": "Formula inputs and outputs must be Stock Items.",
        "pickerUnavailable": "The item list is unavailable right now. Refresh and try again before deciding this row is empty.",
        "unauthorized": "You do not have permission to change product roles for this business.",
        "staleVersion": "This item changed while you were reviewing it. Refresh and try again.",
        "notFound": "This item is no longer available.",
        "foreignOrUnavailable": "This item is unavailable.",
        "unknownPassThrough": "Something unexpected happened. Groot will show the original error instead of guessing the cause."
      },
      "agentSetup": {
        "title": "Product setup guidance",
        "salesProduct": "For a customer-facing item, open Products and set it up as a Sales Product. Do not enable Stock unless the business counts this item.",
        "stockItem": "For raw materials, packaging, resale stock, and recipe outputs, open Products and set up a Stock Item with a base unit.",
        "supplierItem": "For supplier descriptions, open Incoming and map the Supplier Item to a confirmed Stock Item before confirming pack contents.",
        "reliefLink": "For a sold item that should deduct another stock bucket, open Products and add a stock relief link from the Sales Product to the Stock Item.",
        "missingRoute": "If a sale has no stock route, guide the user to Products. Do not infer a route from names, SKUs, recipes, or supplier text.",
        "noBypass": "Agent mode can explain the setup and open the human-confirmed surface, but it cannot bypass role, tenant, or no-inference checks.",
        "openProducts": "Open Products & Stock",
        "formulaDialogGuidance": "Formulas consume and produce Stock Items only. From Products, link a Sales Product to the produced Stock Item when it should relieve this output."
      },
      "states": {
        "loading": "Loading items…",
        "unavailable": "This role view is unavailable",
        "truncated": "This list is truncated. Search to narrow the results before making setup decisions.",
        "emptySales": "No Sales Products match this view.",
        "emptyStock": "No Stock Items match this view."
      },
      "formulaSummary": {
        "title": "Formula",
        "description": "Manage this Sales Product stock route in the Formulas workspace. Legacy relief links are shown there as setup state, not as new confirmed formulas.",
        "action": "Open formula"
      },
      "laneReadOnly": {
        "salesOnStockItem": "This stock item also has a Sales Product role from before. Switch off to remove it; new sales products are created in Catalog.",
        "stockOnSalesProduct": "This sales product also has a Stock Item role from before. Switch off to remove it; stock items are created in Stock Items or Incoming."
      },
      "sellStockItem": {
        "title": "Sell this stock item",
        "description": "Choose which Sales Product this stock item supplies when it sells, and how much stock leaves per sale. A simple resale is one component with quantity 1.",
        "action": "Set up sale formula"
      }
    },
    "supplierItems": {
      "knownErrors": {
        "identifierRequired": "Enter the supplier item code or description before saving this Supplier Item.",
        "relatedRecordNotFound": "The supplier, Stock Item, or Supplier Item is no longer available. Refresh and try again.",
        "mappingExists": "This supplier already has a Supplier Item with that code. Open the existing one instead of creating a duplicate.",
        "mappingNotFound": "This Supplier Item is no longer available.",
        "versionStale": "This supplier item changed while you were editing it. Refresh and try again.",
        "notActive": "This Supplier Item is not active. Reactivate it before making this change.",
        "notInactive": "Only a deactivated Supplier Item can be reactivated.",
        "targetUnchanged": "That is already the Stock Item for this Supplier Item. Choose a different one.",
        "notHistorical": "Only a historical Supplier Item can be mapped from this action."
      },
      "picker": {
        "title": "Choose a Stock Item",
        "changeTitle": "Change the Stock Item",
        "description": "Search by name or Groot SKU. The Supplier Item will point at the Stock Item you confirm here.",
        "searchPlaceholder": "Search Stock Items by name or SKU",
        "showAll": "Show all items",
        "hideAll": "Show Stock Items only",
        "showAllHint": "Sales-only and incomplete items are shown disabled with the setup step they need.",
        "unavailable": "The Stock Item list is unavailable right now. Refresh and try again before deciding it is empty.",
        "truncated": "This list is truncated. Search to narrow the results before choosing.",
        "empty": "No matching Stock Items.",
        "current": "Current Stock Item",
        "confirm": "Use this Stock Item",
        "cancel": "Cancel",
        "baseUnit": "Base unit",
        "sku": "SKU"
      },
      "toasts": {
        "created": "Supplier Item mapped.",
        "changed": "Stock Item changed. Pack defaults for the previous Stock Item were superseded.",
        "deactivated": "Supplier Item deactivated.",
        "reactivated": "Supplier Item reactivated. Confirm its pack again in Incoming before it affects stock.",
        "packReviewRequested": "Pack review requested. Find it under Incoming.",
        "packReviewExists": "A pack review for this Supplier Item is already pending in Incoming.",
        "recovered": "Supplier Item mapped. Confirm its pack in Incoming before it affects stock."
      },
      "register": {
        "title": "Supplier Items",
        "searchPlaceholder": "Search by supplier item code or description",
        "loading": "Loading Supplier Items...",
        "unavailable": "The Supplier Items register could not be loaded. Refresh and try again before deciding it is empty.",
        "partial": "Showing part of the register. Search or filter to narrow the list before deciding a row is missing.",
        "empty": "No Supplier Items yet. Confirm a supplier line in Incoming, or add one by hand.",
        "emptyFiltered": "No Supplier Items match this search or filter.",
        "addSupplierItem": "Add supplier item",
        "loadMore": "Load more",
        "loadingMore": "Loading...",
        "filters": {
          "vendor": "Supplier",
          "allVendors": "All suppliers",
          "vendorsTruncated": "Only the first {count} suppliers are listed. Search by code or description to reach the rest.",
          "status": "Status",
          "allStatuses": "Current statuses"
        },
        "columns": {
          "supplier": "Supplier",
          "supplierItemCode": "Supplier item code",
          "description": "Description / brand",
          "stockItem": "Mapped Stock Item",
          "pack": "Purchase unit and conversion",
          "status": "Status",
          "lastObserved": "Last observed",
          "actions": "Actions"
        },
        "status": {
          "active": "Active",
          "inactive": "Inactive",
          "refused": "Refused suggestion",
          "unmapped": "Unmapped",
          "duplicate_superseded": "Superseded duplicate",
          "source_deleted": "Discarded with deleted invoice",
          "mapped_current": "Mapped current"
        },
        "noSupplier": "No supplier",
        "noCode": "No code",
        "notMapped": "Not mapped",
        "showCurrentRow": "Show current row",
        "noPack": "No confirmed pack",
        "inIncoming": "In Incoming",
        "packConfidence": {
          "verified": "Verified",
          "imported": "Imported"
        },
        "openSource": "Open source",
        "noSource": "Not observed yet",
        "brand": "Brand: {brand}",
        "actions": {
          "map": "Map to Stock Item",
          "change": "Change Stock Item",
          "editPack": "Edit pack",
          "deactivate": "Deactivate",
          "reactivate": "Reactivate",
          "history": "History",
          "rowLabel": "Actions for {code}",
          "recover": "Map current Supplier Item"
        },
        "pickerDescription": "Supplier item {code} from {vendor}.",
        "deactivateDialog": {
          "title": "Deactivate this Supplier Item?",
          "description": "Future purchase lines from {vendor} with code {code} will stop matching automatically. The row and its history are kept, and you can reactivate it later.",
          "reasonLabel": "Reason",
          "reasonPlaceholder": "Optional. Why this mapping is being retired.",
          "confirm": "Deactivate",
          "cancel": "Cancel"
        },
        "howItWorks": {
          "trigger": "How it works",
          "title": "How Supplier Items work",
          "description": "A Supplier Item is what one supplier calls one of your Stock Items. Groot uses it to match future purchase lines without a review.",
          "steps": {
            "one": "A purchase line from a supplier lands in Incoming. You confirm which Stock Item it is and, if it is a pack, how many base units it holds.",
            "two": "The confirmed mapping appears here as a Supplier Item. The same supplier code will now match automatically.",
            "three": "To correct a mapping, change its Stock Item here. Pack defaults tied to the old Stock Item are superseded, and posted receipts are never rewritten.",
            "four": "Deactivate a mapping to stop it matching while keeping its history. Reactivate it later, then confirm its pack again in Incoming."
          },
          "legendTitle": "Statuses",
          "legend": {
            "active": "Live: purchase lines match it automatically.",
            "inactive": "Retired by a person; history kept; can be reactivated.",
            "refused": "Refused suggestion",
            "unmapped": "A supplier code with no Stock Item yet; map it from the row."
          },
          "tip": "Pack contents are only ever confirmed through Incoming. Edit pack sends the row there."
        }
      },
      "manual": {
        "title": "Add supplier item",
        "description": "Record what a supplier calls one of your Stock Items, so future purchase lines match without a review.",
        "vendorLabel": "Supplier",
        "vendorPlaceholder": "Search suppliers by name",
        "vendorSearchHint": "Type at least one character to search.",
        "vendorNoResults": "No suppliers match.",
        "vendorChange": "Change supplier",
        "codeLabel": "Supplier item code",
        "codePlaceholder": "The code printed on the supplier invoice",
        "descriptionLabel": "Supplier description",
        "descriptionPlaceholder": "Optional. The wording the supplier uses for this item.",
        "stockItemLabel": "Stock Item",
        "noStockItemChosen": "No Stock Item chosen yet.",
        "changeStockItem": "Change Stock Item",
        "baseUnit": "Base unit {unit}",
        "packNote": "Pack contents are confirmed in Incoming, never here.",
        "submit": "Save supplier item",
        "saving": "Saving...",
        "cancel": "Cancel",
        "existsTitle": "This supplier item already exists.",
        "openExisting": "Open existing"
      },
      "history": {
        "title": "Supplier item history",
        "description": "Mapping facts, pack timeline, and audit events for this supplier item.",
        "unavailable": "History could not be loaded for this supplier item. Refresh and try again.",
        "loading": "Loading history...",
        "facts": {
          "title": "Mapping",
          "supplier": "Supplier",
          "supplierItemCode": "Supplier item code",
          "description": "Supplier description",
          "stockItem": "Stock Item",
          "version": "Version",
          "createdAt": "Created",
          "updatedAt": "Last changed",
          "deactivatedAt": "Deactivated",
          "deactivationReason": "Deactivation reason",
          "refusedAt": "Refused"
        },
        "packs": {
          "title": "Pack timeline",
          "empty": "No pack has been confirmed for this supplier item.",
          "truncated": "Only the most recent packs are shown.",
          "effective": "Effective from {from}",
          "effectiveUntil": "Effective from {from} to {to}",
          "status": {
            "active": "Active",
            "superseded": "Superseded",
            "pending": "Pending"
          }
        },
        "events": {
          "title": "Audit events",
          "empty": "No audit events recorded yet.",
          "truncated": "Only the most recent events are shown.",
          "by": "by {actor}",
          "change": "{before} to {after}",
          "types": {
            "created": "Mapping created",
            "stockItemChanged": "Stock Item changed",
            "deactivated": "Deactivated",
            "reactivated": "Reactivated",
            "packReviewRequested": "Pack review requested",
            "recovered": "Current Supplier Item mapped"
          },
          "mappedTo": "Mapped to {after}"
        }
      }
    },
    "help": {
      "open": "Help",
      "description": "Contextual guide for this page",
      "openInfo": "Open guide",
      "stockItemsAndSupplierItemsFallback": {
        "title": "Stock items and supplier items",
        "body": "The documentation for Stock items and Supplier items could not be loaded right now. The info drawer stays available so you know help exists here. Refresh the page, or contact support if this keeps happening."
      }
    },
    "autocountCuration": {
      "label": "Needs review before AutoCount",
      "hint": "Groot will not create this item in AutoCount until someone saves it with Edit Product or gives it an AutoCount or SQL item code."
    },
    "stockMenu": {
      "manage": "Manage stock"
    },
    "content": {
      "title": "Product content",
      "images": "Product images",
      "showImage": "Show image {number}",
      "imageUnavailable": "Image no longer available in the store",
      "fromWooCommerce": "From WooCommerce",
      "lastSynced": "Last brought from WooCommerce on {date}"
    },
    "price": {
      "promo": "{price} promo",
      "promoUntil": "{price} promo until {date}",
      "promoFrom": "{price} promo from {date}"
    },
    "storeChange": {
      "badge": "Store update",
      "price": "Store: {price}",
      "promo": "Store promo: {price}",
      "promoUntil": "Store promo: {price} until {date}",
      "promoFrom": "Store promo: {price} from {date}",
      "promoRange": "Store promo: {price}, {from} to {until}",
      "usePrice": "Use store price",
      "usePromo": "Use store promo",
      "keep": "Keep Groot's",
      "updatedFromStore": "Updated from store {date}",
      "priceUsed": "Price updated from the store.",
      "promoUsed": "Promotion updated from the store.",
      "priceKept": "Kept your price.",
      "promoKept": "Kept your promotion.",
      "failed": "Couldn't apply the store change. Try again."
    },
    "newInStore": {
      "banner": "{count, plural, one {# new product in your store} other {# new products in your store}}",
      "review": "Review and import",
      "show": "Show",
      "hide": "Hide",
      "listLabel": "New products in your store",
      "sku": "SKU {sku}",
      "seen": "First seen {date}",
      "dismiss": "Dismiss",
      "dismissLabel": "Dismiss {name}",
      "dismissed": "Dismissed. You can still import it from your store any time.",
      "dismissFailed": "Could not dismiss this product. Try again."
    },
    "receive": {
      "uses": {
        "title": "Which products use this, and how much per unit sold?",
        "intro": "Set it now, or skip and set it up later under Formulas.",
        "receivedLine": "Received {quantity} {unit} {name} into {location}. No product uses it yet.",
        "receivedLineNoLocation": "Received {quantity} {unit} {name}. No product uses it yet.",
        "uses": "uses",
        "perServing": "{unit} per unit sold",
        "fromName": "From the name",
        "confirm": "Confirm",
        "saving": "Saving",
        "change": "Change",
        "addAnother": "Add another product",
        "skip": "Skip",
        "done": "Done",
        "quantityAria": "Amount of {item} per unit sold, in {unit}",
        "quantityPlaceholder": "Amount",
        "quantityUnknown": "The name does not say how much. Enter the amount per unit sold.",
        "menuPlaceholder": "Search products",
        "noMenuMatches": "No products match.",
        "pickerUnavailable": "Products cannot be loaded right now. Try again in a moment.",
        "pickerNarrow": "Showing the first {count}. Type to narrow the list.",
        "savedLine": "{menu} uses {quantity} {unit} per unit sold.",
        "hasFormula": "{menu} already has a formula with {count} items. This adds one more.",
        "errors": {
          "stale": "This formula changed while you were working. Review it and confirm again.",
          "alreadyInFormula": "This product already uses this stock item.",
          "tooMany": "This formula already has the most items it can hold. Remove one under Formulas first.",
          "quantityWhole": "Enter a whole number of {unit}.",
          "quantityDecimals": "Enter an amount above zero in {unit}, with at most {dp} decimal places.",
          "quantityRefused": "That amount is not valid for this item. Enter an amount above zero.",
          "self": "A product cannot use itself. Pick a different product.",
          "stockRole": "This item is not set up as stock yet, so it cannot be added to a formula.",
          "blocked": "This product has more than one active formula. Fix it under Formulas first.",
          "formulaUnavailable": "The formula for this product cannot be read right now. Try again in a moment.",
          "saveFailed": "Could not save this. Nothing was changed. Try again.",
          "alreadyExists": "This product already has a formula. Edit that one instead of adding a second.",
          "cycle": "A product cannot be made from itself, even through other formulas. Remove the part that loops back.",
          "tooDeep": "These formulas are nested too deeply (more than 5 levels). Simplify one of the parts.",
          "yieldNotExact": "These quantities do not divide evenly by the yield. Use a yield of 1 and enter the amount per product, or change the quantities.",
          "inBothTables": "This product has a formula in both places. Archive one of the two formulas first.",
          "productChange": "A formula belongs to one product. Create a new formula for the other product."
        }
      }
    },
    "formulas": {
      "title": "Formulas",
      "description": "What each product is made of. A sale takes the product out of stock. If you have fewer made than you sold, Groot makes the rest from its parts at the sale.",
      "count": "{count, plural, one {# formula} other {# formulas}}",
      "newFormula": "New formula",
      "saved": "Formula saved.",
      "archived": "Formula archived.",
      "off": {
        "title": "Add your first stock item",
        "description": "Formulas appear once Groot counts stock for your business. Add a stock item in the catalog to start.",
        "link": "Open the catalog"
      },
      "list": {
        "emptyTitle": "No formulas yet",
        "emptyDescription": "A formula says what a product is made of, such as a gift set of three items or a portion of fries. A product you simply buy and sell needs no formula.",
        "partial": "Showing the first {count} formulas. There are more than this list can show.",
        "problemsTitle": "{count, plural, one {# product has a formula that needs fixing} other {# products have formulas that need fixing}}",
        "problemReason": {
          "bothPlaces": "It has a formula in two places, so it cannot be shown as one.",
          "yield": "Its yield is missing or zero.",
          "parts": "Its parts cannot be read (none, repeated, or the product itself).",
          "other": "Its stored formula cannot be read."
        },
        "problemArchiveHint": "Archive its recipe to clear this, then set the formula up again.",
        "problemAskSupport": "Ask support to repair it.",
        "problemArchive": "Archive recipe"
      },
      "row": {
        "unitCost": "{cost} each",
        "costUnknown": "Cost unknown",
        "part": "{item} {quantity}",
        "makes": "Makes {count}",
        "productOnHand": "{quantity} made, in stock",
        "partsOnHand": "Parts in stock: {parts}",
        "assembledAtSale": "Made from its parts at each sale",
        "assemble": "Assemble now",
        "assembleAria": "Assemble {product} now",
        "edit": "Edit",
        "editAria": "Edit {product}",
        "archiveAria": "Archive {product}"
      },
      "archive": {
        "title": "Archive this formula?",
        "description": "{product} will no longer be made from these parts when it is sold. Sales and assembled batches already recorded are not changed.",
        "confirm": "Archive formula",
        "archiving": "Archiving...",
        "failed": "Could not archive the formula. Try again.",
        "reason": "Archived from the Formulas page"
      },
      "assemble": {
        "title": "Assemble now",
        "confirm": "Assemble now",
        "confirming": "Assembling...",
        "quantity": "How many did you make",
        "noFormulaSelected": "Choose a formula to assemble.",
        "postFailed": "Could not record the assembly. Try again.",
        "done": "Assembly recorded. The parts left stock and the product was added.",
        "historyTitle": "Assembled batches",
        "historyDescription": "Every batch you assembled stays here with the cost of its parts.",
        "noRuns": "Nothing assembled yet."
      },
      "editor": {
        "newTitle": "New formula",
        "editTitle": "Edit formula",
        "description": "Say what a product is made of and how many the parts make. Nothing is saved until you press Save.",
        "product": "Product",
        "productPlaceholder": "Search products by name or SKU",
        "noProductMatches": "No products match your search.",
        "hasFormulaHint": "Has a formula",
        "createProduct": "Create a product",
        "switchedToEdit": "{product} already has a formula, so you are editing it.",
        "create": {
          "name": "Product name",
          "price": "Selling price",
          "madeAhead": "I make some ahead and count them",
          "madeAheadHint": "Tick this for a set you pack or a batch you cook before it sells. Leave it clear for a product made only when ordered.",
          "unit": "Unit it is counted in",
          "defaultUnit": "pc",
          "create": "Create product",
          "creating": "Creating...",
          "back": "Back to the list",
          "nameRequired": "Give the product a name.",
          "unitRequired": "Say what unit it is counted in.",
          "failed": "The product could not be created. Try again."
        },
        "parts": "Parts",
        "partPlaceholder": "Search stock items by name or SKU",
        "noPartMatches": "No stock items match your search.",
        "noParts": "Add at least one part.",
        "partQuantity": "How much {item} for one batch",
        "removePart": "Remove {item}",
        "unknownPart": "Stock item",
        "unitFallback": "unit",
        "yield": "This makes",
        "yieldOf": "of {product}",
        "yieldOfProduct": "of the product",
        "yieldHint": "How many the parts above make. Leave 1 when the parts make one. If 1 kg of fries makes 5 portions, put 1 kg as the part and 5 here.",
        "explainTitle": "How this works",
        "explainYield": "The parts are the amount for one batch, and this makes is how many of the product that batch gives.",
        "explainSale": "When you sell the product, it leaves stock. If you have fewer made than you sold, Groot uses the parts to make the rest at the sale, and counts nothing twice.",
        "explainAssemble": "If you pack or cook ahead, press Assemble now on the formula to record it. If you do not, your books are still right after the sale, but a stock count taken between packing and selling will show the loose parts as missing. Pressing it once keeps your shelf and your books in step.",
        "suggestionsTitle": "Suggested from the name",
        "suggestionLine": "{item}, {quantity} {unit}",
        "suggestionCheck": "Check the amount",
        "suggestionUse": "Add this",
        "suggestionUseAria": "Add {item} as a part",
        "chargeHint": "This looks like a charge such as shipping, a fee or tax. A charge normally uses no stock, so it may not need a formula.",
        "chargeHintLink": "Set how it uses stock on the product",
        "backToProduct": "Back to product",
        "save": "Save formula",
        "saving": "Saving...",
        "errors": {
          "productRequired": "Choose a product.",
          "partRequired": "Add at least one part.",
          "quantityRequired": "Enter an amount above zero for {item}.",
          "quantityRequiredAny": "Enter an amount above zero for every part.",
          "quantityPrecision": "{item} is counted in {unit}, which takes at most {places, plural, =0 {whole numbers} one {# decimal place} other {# decimal places}}.",
          "quantityPrecisionAny": "A part has more decimal places than its unit allows. Round it and try again.",
          "duplicatePart": "{item} is already a part of this formula.",
          "duplicatePartAny": "A stock item can be a part only once in a formula.",
          "selfPart": "A product cannot be one of its own parts.",
          "tooManyParts": "A formula can have at most 50 parts.",
          "zeroYield": "Enter how many the parts make, above zero.",
          "yieldNotExact": "These amounts do not divide evenly by the number it makes. Make it 1 and enter the amount for one product, or change the amounts.",
          "inBothTables": "This product has a formula in two places. Ask support to archive one of them first.",
          "productChange": "A formula belongs to one product. Create a new formula for the other product.",
          "separator": "Use one decimal mark, a comma or a point, and no thousands separators.",
          "stale": "This formula changed while you were editing. Close this and open it again.",
          "alreadyExists": "This product already has a formula. Open it from the list to edit it.",
          "cycle": "That would make the product part of itself through another formula. Remove one part and try again.",
          "tooDeep": "Formulas can be nested only a few levels deep. Simplify one of the parts.",
          "stockRole": "Every part must be a stock item that Groot counts. Check the parts you chose.",
          "notAllowed": "You do not have permission to change formulas.",
          "saveFailed": "The formula could not be saved. Check it and try again."
        }
      }
    },
    "toSetUp": {
      "chip": "To set up · {count}",
      "chipPartial": "To set up · {count}+",
      "chipUnknown": "To set up",
      "title": "To set up",
      "intro": "These items are not connected to your stock yet. Suggestions are only filled in for you; nothing is saved until you confirm.",
      "tabsLabel": "What to set up",
      "tabMenu": "Products · {count}",
      "tabStock": "Stock nothing uses · {count}",
      "partialNote": "This scan was partial, so more items may need setting up than are listed here, and one-click actions are off. Use Set up to open the editor, which reads the full picture.",
      "more": "and {count} more",
      "loadFailed": "We could not check what needs setting up.",
      "retry": "Try again",
      "emptyMenu": "No product is waiting for setup.",
      "emptyStock": "No stock is waiting for setup.",
      "emptyPartial": "Nothing found so far, but the scan was partial.",
      "skippedNote": "Skipped items come back when something changes, such as new stock arriving.",
      "row": {
        "suggestion": "Suggested: {quantity} {unit} of {item}",
        "checkQuantity": "Check the quantity before you confirm.",
        "noSuggestion": "No suggestion yet. Choose what it is made from.",
        "charge": "Looks like a charge. Uses no stock",
        "confirm": "Confirm",
        "saving": "Saving",
        "change": "Change",
        "skip": "Skip",
        "usesNoStock": "Uses no stock",
        "setUp": "Set up",
        "notUsedForSales": "Not used for sales",
        "withName": "{action}: {name}",
        "pickStock": "Choose a stock item",
        "noMatches": "No matching stock item",
        "quantityAria": "Amount per unit sold for {name}",
        "cancel": "Cancel"
      },
      "stock": {
        "onHand": "{quantity} {unit} on hand",
        "onHandNoUnit": "{quantity} on hand"
      },
      "dismissed": {
        "show": "Show dismissed ({count})",
        "hide": "Hide dismissed",
        "usesNoStock": "Uses no stock",
        "notUsedForSales": "Not used for sales",
        "undo": "Undo"
      },
      "errors": {
        "saveFailed": "We could not save that. Please try again.",
        "formulaExists": "This item already has a formula. Open it to change it.",
        "formulaCycle": "That formula would use the item in itself. Pick different parts.",
        "quantity": "Check the quantity and try again.",
        "hasFormula": "This item already has a formula, so it cannot be marked as using no stock.",
        "tracksStock": "This item is a stock item and sells as itself.",
        "stockInFormula": "A formula already uses this item.",
        "stale": "This item changed while you were looking. The list was refreshed; check it and try again.",
        "inBothTables": "This item has formulas in two places, so Groot cannot tell which one counts. Open Formulas to fix it.",
        "notAllowed": "You do not have permission to do that."
      },
      "coverage": "{withFormula} of {total} products use stock"
    },
    "stockUse": {
      "title": "How does this use stock?",
      "description": "Answer once. Groot uses it to take the right stock out when this sells.",
      "choicesLabel": "How this item uses stock",
      "current": "Current choice",
      "stockItem": {
        "title": "It is the stock item",
        "description": "Sold as itself. You buy it and sell it as one item, with no link to set up.",
        "action": "Change stock settings"
      },
      "madeFrom": {
        "title": "Made from other items",
        "description": "Add a formula. For example, a chicken chop with fries uses one chicken chop and 200 g of fries.",
        "action": "Open formula",
        "setUp": "Set up formula",
        "parts": "Made from {parts}",
        "yield": "Makes {count}"
      },
      "noStock": {
        "title": "Uses no stock",
        "description": "A fee or a service. Nothing leaves stock when it sells.",
        "action": "Choose this",
        "undo": "Undo"
      },
      "saving": "Saving",
      "nothingBehind": "Selling this will not take anything out of stock.",
      "errors": {
        "saveFailed": "We could not save that. Please try again.",
        "hasFormula": "This item already has a formula, so it cannot be marked as using no stock.",
        "tracksStock": "This item is a stock item and sells as itself."
      },
      "conflict": {
        "title": "Fix this product's formulas",
        "description": "This product has formulas in two places, or one Groot cannot read, so Groot cannot tell what it uses. Open Formulas to fix it.",
        "action": "Open Formulas"
      }
    }
  },
  "accountingTabs": {
    "dashboard": "Dashboard",
    "journalEntries": "Journal Entries",
    "chartOfAccounts": "Chart of Accounts",
    "periods": "Periods",
    "bankRecon": "Bank Recon",
    "newEntry": "New Entry",
    "accountBalances": "Account Inquiry",
    "closingStock": "Closing stock",
    "openingBalance": "Opening balance",
    "fixedAssets": "Fixed Assets"
  },
  "fixedAssets": {
    "title": "Fixed asset register",
    "subtitle": "Register what the business owns, and let a scheduled run post straight-line depreciation for you every month.",
    "newAsset": "New asset",
    "newAssetDescription": "Cost, useful life and the two chart accounts this asset depreciates through.",
    "view": "View",
    "cancel": "Cancel",
    "save": "Save",
    "dispose": "Dispose",
    "confirmDispose": "Confirm disposal",
    "emptyTitle": "No fixed assets registered yet",
    "emptyDescription": "Register an asset to start tracking its depreciation schedule.",
    "disposalSection": "Disposal",
    "runsSection": "Depreciation posted",
    "noRunsYet": "Nothing posted yet. The next scheduled run will depreciate this asset once a full month has passed.",
    "disposeSuccess": "Asset disposed",
    "disposeGain": "Gain on disposal: {amount}",
    "disposeLoss": "Loss on disposal: {amount}",
    "createSuccess": "Asset registered",
    "columns": {
      "name": "Asset",
      "account": "Account",
      "cost": "Cost",
      "accumulatedDepreciation": "Accum. depreciation",
      "netBookValue": "Net book value",
      "status": "Status"
    },
    "form": {
      "name": "Name",
      "namePlaceholder": "e.g. Delivery van",
      "description": "Description",
      "assetAccount": "Asset account",
      "contraAccount": "Accumulated depreciation account",
      "chooseAccount": "Choose an account",
      "acquisitionDate": "Acquisition date",
      "cost": "Cost",
      "usefulLifeMonths": "Useful life (months)",
      "methodNote": "Straight-line depreciation only, for now.",
      "disposalDate": "Disposal date",
      "disposalProceeds": "Proceeds received",
      "proceedsAccount": "Where proceeds landed",
      "proceedsAccountDefault": "Default bank account"
    },
    "errors": {
      "notFound": "That asset could not be found.",
      "nameRequired": "Give the asset a name.",
      "invalidDate": "That date isn't valid.",
      "invalidCost": "Cost must be a positive amount.",
      "invalidUsefulLife": "Useful life must be a whole number of months, at least 1.",
      "invalidProceeds": "Disposal proceeds can't be negative.",
      "accountNotFound": "That asset account isn't in your chart of accounts.",
      "accountIsHeading": "That account has sub-accounts, so it can't take postings. Pick one of its sub-accounts.",
      "accountNotEligible": "That account can't hold a fixed asset. Pick a non-current asset account, such as one under Fixed Assets.",
      "contraAccountNotFound": "That accumulated-depreciation account isn't in your chart of accounts.",
      "contraAccountIsHeading": "That account has sub-accounts, so it can't take postings. Pick one of its sub-accounts.",
      "contraAccountInvalid": "That account isn't a contra asset account. Accumulated depreciation needs an asset account that carries a credit balance.",
      "sameAccount": "The asset account and its accumulated-depreciation account must be different accounts.",
      "alreadyDisposed": "This asset has already been disposed.",
      "disposalBeforeAcquisition": "Disposal date can't be before the asset's acquisition date."
    },
    "howItWorks": {
      "title": "How fixed assets work",
      "intro": "Register an asset once. A scheduled run posts its depreciation automatically every month, until it's fully depreciated or disposed.",
      "step1": "Register the asset: its cost, acquisition date, useful life in months, and the two chart accounts it lives in (the asset account and its accumulated-depreciation contra).",
      "step2": "Every day, Groot checks whether a new month has closed for your business. When one has, it posts that month's depreciation automatically: debit Depreciation Expense, credit the asset's own accumulated-depreciation account.",
      "step3": "Depreciation is capped so it never posts more than the asset's cost, however many periods have passed.",
      "step4": "When the asset is retired, dispose it: Groot clears the accumulated depreciation, removes the asset at cost, and books the resulting gain or loss.",
      "methodBadge": "Straight-line",
      "tip": "Registering an asset does not post its purchase. Record the purchase first (as a business expense or bill against a Fixed Asset account), then register it here to start its depreciation schedule."
    }
  },
  "businessCategories": {
    "defaults": {
      "expense": {
        "travelTransportation": {
          "name": "Travel & Transportation",
          "description": "Travel & Transportation category"
        },
        "officeSupplies": {
          "name": "Office Supplies",
          "description": "Office Supplies category"
        },
        "entertainmentHospitality": {
          "name": "Entertainment & Hospitality",
          "description": "Entertainment & Hospitality category"
        },
        "itSoftware": {
          "name": "IT & Software",
          "description": "IT & Software category"
        },
        "professionalFees": {
          "name": "Professional Fees",
          "description": "Professional Fees category"
        },
        "utilities": {
          "name": "Utilities",
          "description": "Utilities category"
        },
        "rentalLease": {
          "name": "Rental & Lease",
          "description": "Rental & Lease category"
        },
        "trainingDevelopment": {
          "name": "Training & Development",
          "description": "Training & Development category"
        },
        "insurance": {
          "name": "Insurance",
          "description": "Insurance category"
        },
        "otherExpenses": {
          "name": "Other Expenses",
          "description": "Other Expenses category"
        }
      },
      "cogs": {
        "directCosts": {
          "name": "Direct Costs",
          "description": "Direct Costs category"
        },
        "outsourcedServices": {
          "name": "Outsourced Services",
          "description": "Outsourced Services category"
        },
        "materialsSupplies": {
          "name": "Materials & Supplies",
          "description": "Materials & Supplies category"
        },
        "deliveryShipping": {
          "name": "Delivery & Shipping",
          "description": "Delivery & Shipping category"
        },
        "platformServiceFees": {
          "name": "Platform & Service Fees",
          "description": "Platform & Service Fees category"
        },
        "otherCogs": {
          "name": "Other COGS",
          "description": "Other COGS category"
        }
      }
    },
    "importModal": {
      "title": "Import from accounting software",
      "family": {
        "expense": "expense",
        "cogs": "COGS"
      },
      "description": {
        "choose": "Bring your chart of accounts in from your existing accounting software to create {family} categories with matching GL codes. SQL Account is supported today; AutoCount, Master Accounting and others are coming.",
        "source": "Upload your SQL Account Chart of Accounts export to create {family} categories with matching GL codes.",
        "backup": "We extract only your master data from the backup; the file itself is deleted right after.",
        "pick": "Pick the accounts to import as {family} categories.",
        "pickWithSource": "Pick the accounts to import as {family} categories. Source: {fileName}"
      },
      "source": {
        "backupFileName": "SQL Account backup",
        "backupTitle": "Upload SQL Account backup (.zip)",
        "backupDescription": "One file, we do the rest. We extract only your master data: chart of accounts, suppliers, and customers. Then we delete the backup immediately.",
        "backupHelp": "How to create a backup",
        "csvTitle": "Upload a CSV/Excel export instead",
        "csvDescription": "Grid export from Maintain Chart of Account (.csv, .txt, .psv or .xlsx), or a Groot-extracted account list.",
        "chooseFile": "Choose a file",
        "chooseFileHint": ".csv, .txt, .psv or .xlsx: grid export from Maintain Chart of Account, or a Groot-extracted account list"
      },
      "progress": {
        "uploading": "Uploading backup... {percent}%",
        "processing": "Processing your backup (~3-5 min)",
        "processingHint": "Extraction runs in the background. You can safely close this window and return to this page, or Settings > Integrations, to continue later."
      },
      "pick": {
        "searchPlaceholder": "Search by code or description...",
        "showingAllTypes": "Showing all account types",
        "showingWantedType": "Showing {type} ({family}) accounts only",
        "showAllTypes": "Show all account types",
        "selectAllFiltered": "Select all (filtered)",
        "noMatches": "No accounts match the current filters.",
        "alreadyImported": "already imported",
        "selectedSummary": "{selected} selected of {shown} shown"
      },
      "actions": {
        "open": "Import from accounting software",
        "back": "Back",
        "importing": "Importing...",
        "importCategories": "{count, plural, one {Import # category} other {Import # categories}}"
      },
      "errors": {
        "noGlAccounts": "The backup was processed but no GL accounts were found in it.",
        "processBackup": "We could not process this backup. Please try a CSV/Excel export instead.",
        "processingTimeout": "Processing is taking longer than expected. Please try uploading the backup again, or upload a CSV/Excel export instead.",
        "noRows": "No account rows found in this file. Expected columns: code, description, and optionally account type.",
        "parseFailed": "Could not parse this file.",
        "noBusiness": "No active business selected.",
        "startUploadHttp": "Could not start the backup upload (HTTP {status}).",
        "uploadHttp": "Upload failed (HTTP {status}). Please try again.",
        "uploadNetwork": "Upload failed due to a network error. Please try again.",
        "backupUploadFailed": "Backup upload failed. Please try again.",
        "importFailed": "Import failed. Please try again."
      }
    }
  },
  "aiInsights": {
    "header": {
      "title": "AI Insights",
      "subtitle": "How Groot is working for you"
    },
    "sections": {
      "rate": "Automation rate",
      "performance": "AI accuracy",
      "trend": "Automation trend",
      "byFeature": "Lifetime impact by feature"
    },
    "howCalculated": {
      "title": "How this is calculated",
      "body": "Automation rate is the share of AI decisions you accepted without edits. Time saved estimates the manual effort avoided. Numbers update as you and the agent work."
    },
    "strip": {
      "title": "AI is working for you",
      "learning": "AI is learning…",
      "rateLabel": "automated",
      "documentsLabel": "documents",
      "hoursLabel": "saved",
      "viewInsights": "View AI insights"
    }
  },
  "profitLossLocationFilter": {
    "label": "P&L Location",
    "all": "All locations",
    "unassigned": "Unassigned",
    "inactive": "(inactive)"
  },
  "trackingDimensions": {
    "title": "Tracking dimensions",
    "description": "Define the stable labels finance uses to attribute transactions and compare performance across the business.",
    "tabs": {
      "locations": "Locations",
      "departments": "Departments",
      "projects": "Projects",
      "salesAgents": "Sales agents"
    },
    "accessDenied": {
      "title": "Access restricted",
      "description": "Only owners and finance admins can manage tracking dimensions."
    },
    "picker": {
      "label": "Location",
      "placeholder": "Select Location",
      "unassigned": "Unassigned",
      "requiredHint": "Required before posting; drafts may remain unassigned.",
      "optionalHint": "Optional reporting dimension."
    },
    "locations": {
      "title": "Accounting Locations",
      "description": "Use Locations for outlets, branches, or other operating sites in AP, journal entries, and P&L reporting.",
      "actions": {
        "add": "Add Location",
        "edit": "Edit",
        "deactivate": "Deactivate",
        "reactivate": "Reactivate",
        "save": "Save",
        "cancel": "Cancel"
      },
      "policy": {
        "title": "Location policy",
        "description": "This one policy applies consistently to AP invoices, manual journal entries, and sales imports.",
        "modes": {
          "disabled": {
            "label": "Disabled",
            "hint": "Hide the field"
          },
          "optional": {
            "label": "Optional",
            "hint": "Allow blank postings"
          },
          "required": {
            "label": "Required",
            "hint": "Require before posting"
          }
        },
        "requiredNote": "Drafts can still be saved without a Location. Groot blocks posting until every required Location is assigned."
      },
      "table": {
        "name": "Name",
        "code": "Code",
        "status": "Status",
        "actions": "Actions"
      },
      "status": {
        "active": "Active",
        "inactive": "Inactive"
      },
      "empty": {
        "title": "No accounting Locations yet",
        "description": "Create a Location for each outlet or operating site before enabling Location tracking."
      },
      "form": {
        "createTitle": "Add Location",
        "editTitle": "Edit Location",
        "subtitle": "Names and codes stay unique so historical reports remain unambiguous.",
        "nameLabel": "Name",
        "namePlaceholder": "e.g. Tampines Outlet",
        "codeLabel": "Code",
        "codePlaceholder": "e.g. TAM",
        "codeHint": "A required short code used in reports and future accounting exports."
      },
      "deactivateDialog": {
        "title": "Deactivate Location",
        "message": "Deactivate “{name}”? It will be hidden from new postings, while historical entries and reports keep their Location."
      },
      "toast": {
        "created": "Location created",
        "updated": "Location updated",
        "deactivated": "Location deactivated",
        "reactivated": "Location reactivated",
        "modeUpdated": "Location policy updated"
      },
      "errors": {
        "duplicateName": "A Location with this name already exists.",
        "duplicateCode": "A Location with this code already exists.",
        "invalidName": "Enter a Location name of up to 60 characters.",
        "invalidCode": "Enter a Location code of up to 16 characters.",
        "noActiveLocation": "Create an active Location before enabling tracking.",
        "lastActiveLocation": "Disable Location tracking before deactivating the last active Location.",
        "inactiveSelected": "That Location is archived, so it can't be used on new records. Refresh the page and pick an active Location.",
        "notAuthorized": "You do not have permission to manage Locations.",
        "saveFailed": "Could not save the Location. Please try again.",
        "deactivateFailed": "Could not deactivate the Location. Please try again.",
        "modeFailed": "Could not update the Location policy. Please try again."
      },
      "howItWorks": {
        "title": "How accounting Locations work",
        "intro": "A Location is a reporting label for an outlet, branch, or operating site. It is separate from inventory warehouses and from Projects.",
        "stepsHeading": "Setting up",
        "step1": "Create each outlet or operating site with a stable short code.",
        "step2": "Choose whether Location is disabled, optional, or required before posting.",
        "step3": "Assign a Location while reviewing AP invoices or creating journal entries.",
        "step4": "Filter P&L reports by one Location, all Locations, or Unassigned.",
        "policyHeading": "Posting policy",
        "policyDescription": "Required means required at posting time. Drafts remain flexible so incomplete work can be saved and completed later.",
        "historyHeading": "Historical integrity",
        "historyDescription": "Deactivation never deletes history. Posted journal lines keep the Location code and name used when they were posted."
      }
    },
    "salesAgents": {
      "title": "Sales agents",
      "description": "The people credited with a sale. An agent is a record of its own, so someone who does not use Groot can still be credited. Link one to a team member only if they log in: an employee with Sales access works the customers assigned to the agents linked to them.",
      "actions": {
        "add": "Add agent",
        "importFromBackup": "Import from SQL backup",
        "edit": "Edit agent",
        "retire": "Retire agent",
        "reactivate": "Reactivate agent",
        "cancel": "Cancel",
        "save": "Save"
      },
      "table": {
        "name": "Name",
        "code": "Code",
        "teamMember": "Team member",
        "status": "Status",
        "actions": "Actions",
        "notLinked": "Not linked",
        "linkedUnknown": "Unknown member"
      },
      "status": {
        "active": "Active",
        "retired": "Retired"
      },
      "empty": {
        "title": "No sales agents yet",
        "description": "Add the people you credit with sales. If you imported a SQL Account backup, you can bring their agent list straight in."
      },
      "form": {
        "createTitle": "Add sales agent",
        "editTitle": "Edit sales agent",
        "subtitle": "The name shows on documents and reports. The code is what your accounting software expects.",
        "nameLabel": "Name",
        "namePlaceholder": "e.g., Ashley Tan",
        "codeLabel": "Code",
        "codePlaceholder": "e.g., ASHLEY",
        "codeHint": "Up to 10 characters. Reuse the code from your accounting software and no export mapping is needed.",
        "teamMemberLabel": "Team member (optional)",
        "teamMemberNone": "Not a team member",
        "teamMemberHint": "Link only if this agent also logs in to Groot. An employee with Sales access sees the customers assigned to the agents linked to them, so link carefully. External reps stay unlinked."
      },
      "toast": {
        "created": "Sales agent added.",
        "updated": "Sales agent updated.",
        "retired": "Sales agent retired. Past documents keep their attribution.",
        "reactivated": "Sales agent reactivated.",
        "imported": "Imported {created} agent(s). {skipped} already existed.",
        "importedNothing": "No agents found in a SQL Account backup for this business.",
        "importedAllPresent": "All {skipped} agent(s) in your backup are already here."
      },
      "errors": {
        "duplicateCode": "That code is already used by another agent. Codes must be unique.",
        "invalidCode": "Enter a code of up to 10 characters.",
        "invalidName": "Enter the agent name.",
        "notAuthorized": "You do not have permission to manage sales agents. Ask the business owner or a finance admin.",
        "saveFailed": "Could not save the sales agent. Nothing was changed, so you can try again.",
        "importFailed": "Could not read your SQL Account backup. Nothing was changed; you can add agents by hand."
      },
      "retireDialog": {
        "title": "Retire this sales agent?",
        "message": "{name} will no longer be offered when tagging documents. Past documents keep their attribution and the code stays reserved."
      }
    }
  },
  "orgDimension": {
    "title": "Departments",
    "description": "Organize your team into departments for routing and cost tracking.",
    "actions": {
      "add": "Add department",
      "edit": "Edit",
      "deactivate": "Deactivate",
      "reactivate": "Reactivate",
      "save": "Save",
      "cancel": "Cancel"
    },
    "table": {
      "name": "Name",
      "code": "Code",
      "head": "Head",
      "members": "Members",
      "status": "Status",
      "actions": "Actions"
    },
    "status": {
      "active": "Active",
      "inactive": "Inactive"
    },
    "head": {
      "placeholder": "Set a head",
      "none": "No head"
    },
    "empty": {
      "title": "No departments yet",
      "description": "Create your first department to group your team and enable department-based approval routing."
    },
    "form": {
      "createTitle": "Add department",
      "editTitle": "Edit department",
      "subtitle": "Departments are scoped to this business. The name must be unique.",
      "nameLabel": "Name",
      "namePlaceholder": "e.g. Marketing",
      "codeLabel": "Code (optional)",
      "codePlaceholder": "e.g. MKT",
      "codeHint": "A short code for export and accounting-system mapping. Optional."
    },
    "deactivateDialog": {
      "title": "Deactivate department",
      "message": "Deactivate \"{name}\"? It will be hidden from new assignments but existing members keep it and historical reports still resolve the name. You can reactivate it later."
    },
    "picker": {
      "label": "Department",
      "placeholder": "Select a department",
      "unassigned": "Unassigned",
      "inactiveSuffix": "(inactive)"
    },
    "toast": {
      "created": "Department created",
      "updated": "Department updated",
      "deactivated": "Department deactivated",
      "reactivated": "Department reactivated",
      "headUpdated": "Department head updated",
      "memberAssigned": "Department assigned"
    },
    "errors": {
      "duplicateName": "A department with this name already exists.",
      "duplicateCode": "A department with this code already exists.",
      "invalidName": "Please enter a department name (up to 60 characters).",
      "invalidCode": "The code is too long (up to 16 characters).",
      "headNotMember": "The department head must be an active member of this business.",
      "notAuthorized": "You don't have permission to manage departments.",
      "saveFailed": "Couldn't save the department. Please try again.",
      "deactivateFailed": "Couldn't deactivate the department. Please try again.",
      "headFailed": "Couldn't update the department head. Please try again.",
      "assignFailed": "Couldn't update the department. Please try again."
    },
    "accessDenied": {
      "title": "Access restricted",
      "description": "Only owners and finance admins can manage departments."
    },
    "howItWorks": {
      "title": "How departments work",
      "intro": "A department is a stable group a person belongs to. It powers department-based approval routing (the department head can approve their team's claims) and lets finance track spend by department.",
      "stepsHeading": "Setting up",
      "step1": "Create your departments (e.g. Marketing, Sales, Ops), each with an optional short code.",
      "step2": "Assign each team member to one department from the Team tab.",
      "step3": "Set a department head from this business's active members.",
      "step4": "From then on, claims can be reported and routed by department.",
      "statusHeading": "Status",
      "activeDesc": "Assignable to members and selectable on claims; can have a head.",
      "inactiveDesc": "Hidden from new assignments; existing members keep it and history still resolves.",
      "tipsHeading": "Tips",
      "tip": "Deactivating never deletes a department, so historical reports stay intact. A person belongs to exactly one department.",
      "visibilityHeading": "Who can manage this",
      "visibilityDesc": "Only owners and finance admins can create, edit, deactivate departments, or set a head."
    },
    "projects": {
      "title": "Projects",
      "description": "Track spend by project. Tag expense claims to a project for project cost reporting.",
      "actions": {
        "add": "Add project",
        "edit": "Edit",
        "close": "Close",
        "reopen": "Reopen",
        "save": "Save",
        "cancel": "Cancel"
      },
      "table": {
        "name": "Name",
        "code": "Code",
        "dates": "Dates",
        "status": "Status",
        "actions": "Actions"
      },
      "status": {
        "active": "Active",
        "closed": "Closed"
      },
      "empty": {
        "title": "No projects yet",
        "description": "Create your first project to tag expense claims and track spend by project."
      },
      "form": {
        "createTitle": "Add project",
        "editTitle": "Edit project",
        "subtitle": "Projects are scoped to this business. The name must be unique.",
        "nameLabel": "Name",
        "namePlaceholder": "e.g. Acme Rollout",
        "codeLabel": "Code (optional)",
        "codePlaceholder": "e.g. ACME",
        "codeHint": "A short code for export and accounting-system mapping. Optional.",
        "startDateLabel": "Start date (optional)",
        "endDateLabel": "End date (optional)"
      },
      "closeDialog": {
        "title": "Close project",
        "message": "Close \"{name}\"? It will stop accepting new tags, but claims already tagged keep it and still report. You can reopen it later."
      },
      "toast": {
        "created": "Project created",
        "updated": "Project updated",
        "closed": "Project closed",
        "reopened": "Project reopened"
      },
      "errors": {
        "duplicateName": "A project with this name already exists.",
        "duplicateCode": "A project with this code already exists.",
        "invalidName": "Please enter a project name (up to 60 characters).",
        "invalidCode": "The code is too long (up to 16 characters).",
        "invalidDateRange": "The start date must be on or before the end date.",
        "notAuthorized": "You don't have permission to manage projects.",
        "saveFailed": "Couldn't save the project. Please try again.",
        "closeFailed": "Couldn't close the project. Please try again."
      },
      "accessDenied": {
        "title": "Access restricted",
        "description": "Only owners and finance admins can manage projects."
      },
      "howItWorks": {
        "title": "How projects work",
        "intro": "A project is a cost bucket you tag onto expense claims. Tagging lets finance track total spend per project, separate from departments.",
        "stepsHeading": "Setting up",
        "step1": "Create your projects (e.g. Acme Rollout, Internal R&D), each with an optional short code.",
        "step2": "On an expense claim, pick the project it belongs to.",
        "step3": "Finance can then report total spend per project.",
        "step4": "Close a project when it ends. Existing tags are kept, new tags are stopped.",
        "statusHeading": "Status",
        "activeDesc": "Selectable on claims and accepts new tags.",
        "closedDesc": "Hidden from new tags; existing tags are kept and still report.",
        "tipsHeading": "Tips",
        "tip": "Closing never deletes a project, so historical reports stay intact. A claim can be tagged to one project.",
        "visibilityHeading": "Who can manage this",
        "visibilityDesc": "Only owners and finance admins can create, edit, or close projects."
      }
    },
    "claim": {
      "departmentLabel": "Department",
      "departmentAutoFilled": "auto-filled",
      "departmentPlaceholder": "Select a department",
      "departmentNone": "Unassigned",
      "departmentHint": "Auto-filled from your department; you can change it for this claim.",
      "projectLabel": "Project",
      "projectOptional": "optional",
      "projectPlaceholder": "Select a project",
      "salesAgentHint": "Who this spend is attributed to. It shows on the agent's P&L.",
      "projectNone": "No project",
      "tagFailed": "Couldn't update the department or project. Please try again."
    },
    "report": {
      "unassigned": "Unassigned",
      "untagged": "Untagged",
      "departmentFilter": "Department",
      "projectFilter": "Project",
      "allDepartments": "All departments",
      "allProjects": "All projects"
    }
  },
  "expenseApprovalSettings": {
    "title": "Expense Approval",
    "description": "Configure spending caps and automation for expense approvals. Every option is off by default. Leave them off to keep today’s behavior.",
    "restricted": "Only an owner or finance admin can change approval settings.",
    "save": "Save changes",
    "saving": "Saving...",
    "saved": "Approval settings saved.",
    "errors": {
      "invalidAmount": "Enter an amount of 0 or greater.",
      "saveFailed": "Could not save approval settings. Try again."
    },
    "caps": {
      "label": "Per-category spending caps",
      "hint": "Flag claims that exceed a category’s cap at approval time. Approvers can then approve at the cap or override with a reason."
    },
    "fastPath": {
      "label": "Fast-path small claims",
      "hint": "Claims at or below this amount need only the first approval level. Larger claims follow the full chain. This never adds an approver.",
      "amountLabel": "Fast-path amount ({currency})",
      "amountPlaceholder": "0.00"
    },
    "autoApprove": {
      "label": "Auto-approve small clean claims",
      "hint": "Up to each category’s threshold, automatically approve clean claims that have a receipt, complete data, and no risk flags.",
      "requireReceiptLabel": "Require a receipt",
      "requireReceiptHint": "Only auto-approve claims that have a receipt attached."
    },
    "spendControl": {
      "title": "Spend control",
      "description": "Three amounts per category, acting at three different moments: the monthly budget notifies after approval, the cap flags at approval, and the auto-approve threshold skips the approver at submit.",
      "empty": "Add an expense category to set spend controls for it.",
      "bandsHeading": "What happens at each amount",
      "bandRange": "{from} to {to}",
      "bandRangeOpen": "Above {from}",
      "bandAutoApproved": "approved automatically",
      "bandFastPath": "one approver",
      "bandFullChain": "{count, plural, =1 {1 approval} other {# approvals}}",
      "bandSkips": "skips {count} of {total}",
      "bandFlagged": "flagged over cap",
      "deadFastPathAutoApprove": "Your fast-path amount never applies: auto-approve already decides every claim at or below it.",
      "deadFastPathPolicy": "Your fast-path amount never applies: this business uses approval policies, and the policy decides how many approvals a claim needs."
    },
    "approvalRequired": {
      "label": "Require approval",
      "hint": "Off means a submitted claim is filed and posted straight away, with no approver.",
      "offNote": "Claims post as an expense you are owed, and stay owed until you reimburse yourself. They are not marked paid.",
      "inactiveNote": "Not used while approval is off.",
      "capsStillApply": "Still applies. A claim over its category cap is refused when you file it.",
      "policiesInactiveNote": "Approval is off for this business, so these policies do not run. Turn on Require approval above to use them.",
      "planUnavailable": "Your plan has no approvals screen, so a submitted claim has nowhere to be approved. Turn off Require approval to file claims directly.",
      "planHasNoApprovals": "Your plan has no approval step, so claims are filed and posted as soon as you submit them."
    },
    "noReceiptExemption": {
      "label": "Allow claims with no receipt",
      "hint": "Claims at or below this amount may be submitted with a reason instead of a receipt, for expenses that genuinely have none, like parking or tolls. The approver always sees the reason.",
      "amountLabel": "No-receipt limit ({currency})",
      "amountPlaceholder": "0.00"
    }
  },
  "autosave": {
    "saving": "Saving…",
    "saved": "Saved",
    "failed": "Not saved",
    "retry": "Retry"
  },
  "approvalPolicies": {
    "title": "Approval Policies",
    "summary": "Policy summary",
    "noPolicies": "No approval policies configured. Claims use the default manager chain.",
    "defaultPolicy": "Default policy",
    "steps": "Steps",
    "step": "Step",
    "manager": "Your manager",
    "conditions": "Conditions",
    "minAmount": "Minimum amount",
    "category": "Category",
    "department": "Department",
    "active": "Active",
    "inactive": "Inactive",
    "talkToGroot": "Talk to Groot to change these settings",
    "askGrootButtonLabel": "Ask Groot",
    "askGrootAriaLabel": "Ask Groot to set up or edit your expense approval policies",
    "askGrootPromptEmpty": "Set up a multi-level expense approval policy for me. Show the options and let me configure who approves what.",
    "askGrootPromptManage": "Show our expense approval policies and let me review and edit them.",
    "askGrootSettingsHint": "Multi-level approval policies are set up in chat.",
    "levelXOfY": "Level {level} of {total}",
    "policyName": "Policy: {name}",
    "needsApprover": "This claim needs an approver; no matching policy could be resolved",
    "cannotRemoveLastDefault": "Every business with active approval policies needs at least one default policy (no conditions) so any expense can be routed to an approver. Create or keep a default policy, or deactivate the override policies first.",
    "explainRouting": {
      "title": "Approval routing",
      "policyName": "Policy",
      "currentLevel": "Current level",
      "chainDepth": "Total steps",
      "matchedBecause": "Matched because",
      "steps": "Approval steps"
    }
  },
  "viewAsConsent": {
    "title": "Support access request",
    "body": "A Groot support engineer has requested temporary, read-only access to your account to help resolve an issue. They cannot make any changes, and this access ends automatically.",
    "reasonLabel": "Reason given",
    "approve": "Approve read-only access",
    "deny": "Decline",
    "approving": "Approving…",
    "denying": "Declining…",
    "approved": "Access approved. The support engineer can now view your screens read-only.",
    "denied": "Request declined. No access was granted.",
    "error": "Couldn't record your response. Please try again."
  },
  "viewAsBridge": {
    "header": {
      "title": "Read-only support view",
      "subtitle": "Temporary, audited access from Groot CRM"
    },
    "loading": "Verifying the active support session…",
    "readOnlyTitle": "Product View is read-only",
    "readOnlyBody": "The target business and access window are rechecked on every request. Customer data cannot be changed while this session is active.",
    "invalidReturnTo": "The supplied return address was not trusted, so the safe CRM home address will be used.",
    "returnToCrm": "Return to CRM",
    "requestAccessTitle": "Need access?",
    "requestAccessBody": "Return to CRM to use the existing audited request flow. Customer approval is required for routine access; break-glass is never started automatically.",
    "requestAccessAction": "Request access in CRM",
    "financeOverviewTitle": "Finance overview",
    "financeOverviewBody": "You are viewing the exact business covered by the active support session.",
    "states": {
      "missing_business": {
        "title": "Business target required",
        "body": "This link does not include a businessId. Return to CRM and open Product View from the intended account."
      },
      "not_staff": {
        "title": "Access denied",
        "body": "Only current Groot platform staff recorded in the database can use Product View."
      },
      "no_session": {
        "title": "No active support session",
        "body": "This link grants no access by itself. Start or complete the audited access request before opening Finance."
      },
      "mismatch": {
        "title": "Business does not match",
        "body": "The active support session is for a different business. Finance will not switch or use the target from this link."
      },
      "expired": {
        "title": "Support session expired",
        "body": "Read-only access has ended. Request a new time-boxed session if support work must continue."
      }
    }
  },
  "einvoiceMonitoring": {
    "header": {
      "title": "E-invoice Monitoring",
      "subtitle": "Submission blocks, error patterns, and routing-hint decay"
    },
    "accessDenied": {
      "title": "Access Denied",
      "body": "This dashboard is for Groot team members only. If you believe this is an error, please contact your administrator."
    },
    "heading": "E-invoice submission health",
    "subheading": "Triage what is blocking automated e-invoice submissions and what the system has already fixed on its own.",
    "refresh": "Refresh",
    "retry": "Try again",
    "loading": "Loading monitoring data…",
    "error": {
      "body": "We couldn't load the monitoring data right now.",
      "suggestion": "Refresh the page in a moment. If it keeps failing, check the e-invoice monitoring backend."
    },
    "emptyTitle": "No monitoring data yet",
    "emptyDescription": "Once e-invoice submissions start running, blocks, error patterns, and requeue activity will appear here.",
    "blocks": {
      "title": "Block classification",
      "subtitle": "Only hard-blocked merchants justify paid residential-proxy spend. Manual-only walls (account or PIN) never do.",
      "hardBlocked": "Hard blocked",
      "hardBlockedTile": "Bot-blocked across all tiers or needs a residential proxy.",
      "manualOnly": "Manual only",
      "manualOnlyTile": "Account, PIN, or OTP wall: not automatable, no proxy helps.",
      "recoverable": "Recoverable",
      "recoverableTile": "Succeeded or a transient failure that can retry.",
      "hardBlockedMerchantsTitle": "Hard-blocked merchants (paid-proxy candidates)",
      "hardBlockedMerchantsSubtitle": "Merchants that have produced a hard-block signal: the shortlist for paid residential-proxy spend.",
      "noHardBlocked": "No hard-blocked merchants in this window.",
      "perMerchantTitle": "Per-merchant breakdown",
      "noMerchants": "No merchant activity in this window.",
      "colMerchant": "Merchant",
      "colHardBlockedCount": "Hard-blocked claims",
      "colHardBlocked": "Hard blocked",
      "colManualOnly": "Manual only",
      "colRecoverable": "Recoverable",
      "colTotal": "Total"
    },
    "patterns": {
      "title": "Error patterns",
      "subtitle": "Recurring submission errors, grouped and de-duplicated. Set a status to triage each one.",
      "empty": "No error patterns detected.",
      "colPattern": "Pattern",
      "colMerchant": "Merchant domain",
      "colCount": "Occurrences",
      "colStatus": "Status",
      "colLastSeen": "Last seen",
      "colTriage": "Set status",
      "autoRemediatedNote": "Auto-remediated patterns were fixed automatically by the monitoring system. That is the closed loop at work.",
      "status": {
        "new": "New",
        "investigating": "Investigating",
        "resolved": "Resolved",
        "wont_fix": "Won't fix",
        "auto_remediated": "Auto-remediated"
      },
      "statusUpdated": "Status updated.",
      "statusUpdateError": "Couldn't update the status. Please try again.",
      "resolutionLabel": "Resolution: {resolution}",
      "triageAriaLabel": "Set pattern status",
      "confirmDiagnosis": "Confirm diagnosis",
      "diagnosisConfirmed": "Diagnosis confirmed and activated for future matches.",
      "diagnosisConfirmError": "Couldn't confirm the diagnosis. Please try again.",
      "diagnosisPolicyActive": "Policy active",
      "affectedIds": "Claims: {claims} · Businesses: {businesses}",
      "correctDiagnosis": "Correct",
      "cancelCorrection": "Cancel",
      "reasonCode": "Reason code",
      "recommendedAction": "Recommended action",
      "userTitle": "User-facing title",
      "userMessage": "User-facing message"
    },
    "hints": {
      "title": "Routing-hint decay",
      "subtitle": "Portal-scoped routing hints and whether each is still active or has decayed to a cheaper path.",
      "empty": "No routing hints recorded.",
      "colMerchant": "Merchant",
      "colPortal": "Portal domain",
      "colHint": "Hint",
      "colState": "State",
      "colLastValidated": "Last validated",
      "active": "Active",
      "downgraded": "Downgraded"
    },
    "requeue": {
      "title": "Requeue activity",
      "subtitle": "Previously-failed claims automatically re-triggered after a merchant improved.",
      "unknownMerchant": "Unknown merchant",
      "summary": "{requeued} of {eligible} eligible claims requeued"
    },
    "portalRegistry": {
      "title": "Portal capability registry",
      "subtitle": "How each merchant portal is driven, and when we last observed it. A capability with no date is how a stale requirement survives for months.",
      "empty": "No learned portal records yet. The form-fill Lambdas are routing off their built-in defaults.",
      "unseeded": "{count} of {total} built-in portal defaults have no row yet. Those portals still route off code, not off this table.",
      "seedCta": "Import built-in defaults",
      "seedSuccess": "Imported {count} portal records.",
      "seedNoop": "Every built-in default already has a row.",
      "seedError": "We couldn't import the built-in portal defaults. Please try again.",
      "colPortal": "Portal domain",
      "colDriver": "Driver",
      "colNavigation": "Navigation",
      "colCaptcha": "CAPTCHA",
      "colQuirks": "Quirks",
      "colActions": "Actions",
      "aliases": "Also: {list}",
      "stale": "Stale",
      "observed": "{source} · {when}",
      "override": "Override",
      "cancel": "Cancel",
      "save": "Save override",
      "overrideHelp": "Recorded as a dated claim with your reason. It outranks automated discovery until it goes stale, then the escalation ladder may correct it.",
      "overrideSuccess": "Portal capability updated.",
      "overrideError": "We couldn't save that override. Please try again.",
      "reasonLabel": "Reason",
      "reasonPlaceholder": "What did you measure, and how?",
      "reasonRequired": "Please say why you are changing this.",
      "nothingChosen": "Choose at least one capability to change.",
      "noChange": "No change",
      "source": {
        "seed": "Built-in default",
        "measurement": "Measured",
        "escalation": "Earned by escalation",
        "agent": "Agent discovery",
        "staff": "Staff override",
        "tier1": "Tier-1 probe"
      },
      "colSelectors": "Selectors",
      "driftUnprobed": "Never probed",
      "drifting": "{count, plural, =1 {# portal has} other {# portals have}} been caught mid-change by a Tier-1 run. Saved selectors no longer resolve, so every claim there falls to the agent.",
      "drift": {
        "none": "Matching",
        "suspected": "Drift suspected",
        "confirmed": "Drift confirmed"
      },
      "healed": "Healed by the agent",
      "healedAt": "Corrected {when} across {count} saved selector(s)",
      "healedSummary": "{count, plural, =1 {# portal has} other {# portals have}} been repaired by a successful agent run. Its discovery overwrote the stale selectors, so the next claim there runs deterministically."
    }
  },
  "soloLaunch": {
    "setup": {
      "title": "Set up your Solo books",
      "description": "Choose your country first, then tell Groot how you earn. We will suggest a short list of categories you can change later.",
      "countryLabel": "Business country",
      "countryHint": "Country controls the bookkeeping and official tax rules Groot uses.",
      "chooseCountry": "Choose your country",
      "countries": {
        "MY": "Malaysia",
        "SG": "Singapore"
      },
      "profileLabel": "Solo Profile",
      "profileHint": "Choose the closest match for your main source of income.",
      "chooseProfile": "Choose a profile",
      "profiles": {
        "platformDriver": {
          "title": "Platform driver or rider",
          "description": "Ride-hailing, delivery, and other platform work"
        },
        "commissionAgent": {
          "title": "Commission agent",
          "description": "Insurance, property, sales, and other commission-based work"
        },
        "homeBasedSeller": {
          "title": "Home-based seller",
          "description": "Food, products, or online sales run from home"
        },
        "soloService": {
          "title": "Independent service",
          "description": "Consulting, creative, technical, and other professional services"
        }
      },
      "continue": "Continue",
      "saving": "Saving setup...",
      "saved": "Your Solo setup is ready.",
      "countryFirst": "Choose a country before selecting a profile.",
      "lockedTitle": "This business country can no longer be changed",
      "lockedDescription": "This business already has financial or tax records. To keep those records correct, create a new Solo business for a different country.",
      "createNewBusiness": "Create a new Solo business",
      "keepCurrentBusiness": "Keep this business"
    },
    "categories": {
      "title": "My categories",
      "description": "Plain-language categories for the work you do. Renaming or hiding one never rewrites past records.",
      "profileEyebrow": "Solo Profile",
      "profileTitle": "Your work profile",
      "profileDescription": "Your profile keeps category suggestions relevant to how you earn.",
      "profileSaved": "Solo Profile updated.",
      "loading": "Loading categories",
      "add": "Add category",
      "addTitle": "Add a category",
      "cancelAdd": "Cancel adding category",
      "name": "Name",
      "family": "Category group",
      "families": {
        "income": "Money in",
        "cogs": "Direct costs",
        "expense": "Business expenses"
      },
      "nameLabel": "Category name",
      "namePlaceholder": "For example, phone and internet",
      "create": "Create category",
      "created": "Category created.",
      "renamed": "Category renamed.",
      "hidden": "Category hidden.",
      "shown": "Category shown.",
      "save": "Save category",
      "saving": "Saving...",
      "rename": "Rename",
      "renameLabel": "Rename {name}",
      "cancelRename": "Cancel renaming",
      "saveRename": "Save new name",
      "hide": "Hide",
      "show": "Show",
      "cancel": "Cancel",
      "empty": "No categories are available for this profile yet.",
      "truncated": "Showing the first 100 categories. Narrow your view to see more.",
      "visibleCount": "{count, plural, =1 {# visible category} other {# visible categories}}",
      "kinds": {
        "ordinary": "Business expense",
        "expense": "Business expense",
        "costOfGoods": "Cost of sales",
        "capital": "Capital purchase",
        "personal": "Personal contribution",
        "personal_contribution": "Personal contribution",
        "home_workspace": "Home workspace",
        "blocked": "Not a business expense",
        "disallowed": "Not a business expense"
      },
      "routing": {
        "ordinary": "This will be recorded as a business expense.",
        "capital": "Record this as a capital purchase instead of an ordinary expense.",
        "personal_contribution": "Record this in personal tax contributions, not as a business expense.",
        "blocked": "This item cannot be recorded as an ordinary business expense. Review the guidance before continuing."
      }
    },
    "allocation": {
      "title": "Home workspace share",
      "description": "Set the business-use share once. You will still choose who paid for each receipt.",
      "policyTitle": "Business-use policy",
      "editPolicy": "Edit policy",
      "businessUsePercent": "Business-use percentage",
      "basis": "How you worked this out",
      "bases": {
        "floorArea": "Floor area",
        "time": "Time used",
        "other": "Other reasonable basis"
      },
      "rationale": "Short reason",
      "effectiveDate": "Effective from",
      "savePolicy": "Save policy",
      "savingPolicy": "Saving policy...",
      "policySaved": "Home workspace policy saved.",
      "policyHistory": "Changes apply only from their effective date and never rewrite earlier receipts.",
      "fundingTitle": "Who paid for this receipt?",
      "fundingDescription": "Choose the actual payment source so Groot can balance the entry correctly.",
      "businessFunds": "Paid from business funds",
      "businessFundsHint": "The full bank or cash payment stays visible; the personal share goes to owner drawings.",
      "ownerFunds": "I paid personally",
      "ownerFundsHint": "Only the business share is recorded, balanced through owner contribution. No business cash movement is created.",
      "fundingRequired": "Choose who paid before continuing.",
      "previewTitle": "Allocation preview",
      "grossAmount": "Receipt total",
      "businessShare": "Business expense",
      "personalShare": "Personal share",
      "balancingEntry": "Balancing treatment",
      "ownerDrawings": "Owner drawings",
      "ownerContribution": "Owner contribution",
      "confirm": "Confirm and record",
      "recording": "Recording...",
      "recorded": "Expense and allocation recorded.",
      "evidenceTitle": "Allocation details",
      "businessShareExplanation": "Only the business share appears in your profit and loss.",
      "sourceLabel": "Official guidance",
      "openSource": "Open official source",
      "redirectTitle": "Choose the right treatment",
      "redirectCapital": "This looks like a capital purchase. Record it through the capital-purchase flow.",
      "redirectContribution": "This is personal tax evidence. Record it as a personal contribution instead.",
      "redirectDisallowed": "This item is not an allowable ordinary business expense.",
      "nextAction": "Go to the recommended action",
      "refusals": {
        "notApplicable": "This receipt does not qualify for the selected allocation.",
        "protected": "This recorded receipt is protected and cannot be reallocated.",
        "accountsUnavailable": "Groot cannot record this allocation yet because a required account is not set up. Please contact Groot support.",
        "stale": "The policy changed while you were reviewing this receipt. Refresh and check the new split.",
        "missingPolicy": "Set a home workspace policy before allocating this receipt.",
        "generic": "The allocation was not recorded. Review the details and try again.",
        "missingEquityAccount": "This allocation needs two accounts your chart does not have yet: Owner's Capital and Owner's Drawings. Add them now and Groot will continue."
      },
      "setupAccounts": "Set up these accounts",
      "settingUpAccounts": "Setting up accounts...",
      "accountsSetupSuccess": "Owner's Capital and Owner's Drawings accounts have been set up. You can now record this allocation.",
      "accountsSetupFailed": "Groot could not add Owner's Capital and Owner's Drawings to your books, because those account numbers are already used for something else. Please contact Groot support, then record this expense again."
    },
    "tax": {
      "title": "Tax",
      "description": "See the available methods, personal contributions, and saved tax calculations for each tax year.",
      "loading": "Loading tax details",
      "year": "Tax year",
      "heading": {
        "title": "Tax",
        "description": "Methods, personal contributions, and saved tax calculations for the selected year.",
        "year": "Tax year"
      },
      "status": {
        "available": "Official rules reviewed",
        "reviewRequired": "Policy review required",
        "unsupported": "This activity is not supported by the selected method",
        "unavailable": "No reviewed official rules",
        "noJurisdictionMethod": "No fixed expense method"
      },
      "source": {
        "title": "Official source",
        "observedAt": "Reviewed {date}",
        "open": "Open official source"
      },
      "policy": {
        "title": "Official policy status",
        "source": "Official source",
        "openSource": "Open official source",
        "reviewedOn": "Reviewed {date}",
        "effectivePeriod": "Effective {period}",
        "statuses": {
          "available": "Official rules reviewed",
          "unavailable": "No reviewed official rules",
          "reviewRequired": "Policy review required",
          "ineligible": "Not eligible",
          "needsInformation": "More information needed"
        },
        "unavailable": "Groot will not show a rate, threshold, or entitlement until a current official policy has been reviewed."
      },
      "eligibility": {
        "title": "Eligibility",
        "description": "Confirm the facts for this activity and tax year before choosing a method.",
        "eligible": "Eligible based on the details provided",
        "ineligible": "Not eligible for this method",
        "incomplete": "Answer the remaining questions to check eligibility",
        "review": "Review eligibility",
        "missing": "Add the missing eligibility details to continue",
        "fields": {
          "taxpayerKind": "Are you filing as an individual?",
          "allActivityIncomeSourcesIncluded": "Have you included every income source for this activity?",
          "expenseAllocationComplete": "Have you completed the business and personal expense allocation?",
          "drivingKind": "Driving activity",
          "deliveryMode": "Delivery mode"
        },
        "values": {
          "choose": "Choose an answer",
          "yes": "Yes",
          "no": "No",
          "individual": "Individual",
          "other": "Not an individual",
          "phc": "Private-hire car",
          "taxi": "Taxi",
          "footPublicTransportBicycle": "On foot, public transport, or bicycle",
          "motorised": "Motorcycle, motorised device, or power-assisted bicycle",
          "van": "Van"
        }
      },
      "methods": {
        "title": "Expense method",
        "activity": "Qualifying activity",
        "activities": {
          "phcTaxi": "Private-hire car or taxi",
          "commissionAgent": "Commission agent",
          "delivery": "Delivery work"
        },
        "description": "Choose which official method Groot uses to work out this income group's tax figures. Your records stay complete either way.",
        "actual": {
          "title": "Actual expenses",
          "description": "Use supported expenses recorded in your books."
        },
        "fixed": {
          "title": "Fixed expense method",
          "description": "Use the reviewed official fixed method only when this activity and your facts qualify."
        },
        "actualExpense": {
          "title": "Actual expenses",
          "description": "Use supported expenses recorded in your books."
        },
        "fixedExpense": {
          "title": "Fixed expense method",
          "description": "Use the reviewed official fixed method only when this activity and your facts qualify."
        },
        "notSelected": "No method selected",
        "selected": "Selected method",
        "choose": "Choose method",
        "select": "Select method",
        "save": "Save method",
        "saving": "Saving method...",
        "saved": "Tax method saved.",
        "bookkeepingBoundary": "Keep recording every real business expense. A fixed method changes only the tax calculation and excludes overlapping actual expenses there; it never removes them from your books.",
        "mixedActivity": "Mixed or unsupported activity uses the actual-expense method.",
        "noTaxActivity": "Your work profile has no prescribed tax method, so there is no method to choose. Keep recording expenses as usual and Groot reports the figures from your books.",
        "noJurisdictionMethod": "There is no fixed expense method to choose in your country. Groot works out your business income from the actual expenses in your books."
      },
      "methodChoices": {
        "activity": "Qualifying activity",
        "activities": {
          "phcTaxi": "Private-hire car or taxi",
          "commissionAgent": "Commission agent",
          "delivery": "Delivery work"
        }
      },
      "bookkeeping": {
        "title": "Your books stay complete",
        "actual": "The actual-expense method uses supported expenses from your books.",
        "fedr": "The fixed method changes only the tax calculation and excludes overlapping actual expenses only from that calculation.",
        "expenseCaptureEnabled": "Keep recording every real business expense."
      },
      "contributions": {
        "title": "Personal contributions",
        "description": "Keep personal tax evidence here. These records never create business income, expenses, cash movements, or journal entries.",
        "add": "Add contribution",
        "continue": "Load more contributions",
        "personalNotBooks": "Personal contributions are tax evidence only and never enter your business books.",
        "addTitle": "Record a personal contribution",
        "edit": "Edit",
        "delete": "Delete",
        "correct": "Create correction",
        "void": "Void record",
        "cancel": "Cancel",
        "save": "Save contribution",
        "saving": "Saving...",
        "created": "Contribution recorded.",
        "updated": "Contribution updated.",
        "deleted": "Contribution deleted.",
        "corrected": "Correction recorded without changing the original.",
        "voided": "Contribution voided without changing the original.",
        "date": "Contribution date",
        "amount": "Amount",
        "scheme": "Scheme",
        "currency": "Currency",
        "evidenceReference": "Evidence reference",
        "evidenceHint": "Add a short reference you can recognize later. Do not paste sensitive document contents.",
        "taxYear": "Relevant tax year",
        "schemes": {
          "medisave": "MediSave",
          "cpfEpf": "CPF / EPF",
          "cpfVoluntary": "Voluntary CPF",
          "epfISaraan": "EPF i-Saraan",
          "socso": "SOCSO",
          "socsoSksps": "SOCSO SKSPS",
          "iSaraan": "i-Saraan",
          "zakat": "Zakat",
          "other": "Other supported contribution"
        },
        "statuses": {
          "active": "Active",
          "superseded": "Corrected",
          "voided": "Voided"
        },
        "actions": {
          "edit": "Edit",
          "delete": "Delete",
          "correct": "Create correction",
          "void": "Void record"
        },
        "dialog": {
          "createTitle": "Record a personal contribution",
          "editTitle": "Edit contribution",
          "correctTitle": "Correct contribution",
          "voidTitle": "Void contribution",
          "deleteTitle": "Delete contribution",
          "confirmDelete": "Delete this unused contribution?",
          "confirmVoid": "Void this contribution while preserving its history?",
          "fields": {
            "scheme": "Scheme",
            "amount": "Amount",
            "currency": "Currency",
            "date": "Contribution date",
            "dateYearHint": "Must be a {year} date",
            "evidenceReference": "Evidence reference",
            "note": "Note",
            "reason": "Reason for correction"
          },
          "attestations": {
            "iSaraanOwnContribution": "This is my own voluntary contribution, not a government incentive or match.",
            "iSaraanNoOtherCompulsoryEpf": "I am not making compulsory EPF contributions as an employee elsewhere.",
            "skspsNoOtherContributions": "I am not also covered by SOCSO contributions as an employee."
          },
          "save": "Save contribution",
          "saving": "Saving...",
          "cancel": "Cancel"
        },
        "empty": "No personal contributions recorded for this tax year.",
        "locked": "This contribution is part of a saved tax calculation. Correct or void it instead of changing the original.",
        "truncated": "Showing the first 100 contributions.",
        "loadMore": "Load more contributions"
      },
      "snapshots": {
        "title": "Saved tax calculations",
        "description": "Save an immutable copy of the current policy, election, contribution versions, inputs, and result.",
        "preview": "Snapshot preview",
        "save": "Save tax snapshot",
        "saving": "Saving snapshot...",
        "saved": "Tax snapshot saved.",
        "history": "Snapshot history",
        "empty": "No saved tax calculations for this year.",
        "immutable": "This saved snapshot will not change when policies or contributions change later.",
        "currentGuidance": "Current calculation",
        "savedOn": "Saved {date}",
        "truncated": "Showing the first 100 saved snapshots.",
        "loadMore": "Load more snapshots",
        "continue": "Load more snapshots",
        "created": "Saved {date}",
        "policyVersion": "Policy version",
        "view": "View snapshot",
        "grossIncome": "Gross income",
        "businessExpenseDeduction": "Business expense deduction",
        "adjustedTradeIncome": "Adjusted trade income",
        "eligiblePersonalReliefInput": "Eligible personal relief input",
        "bookkeepingGrossIncome": "Gross income in your books",
        "bookkeepingAllowableExpenses": "Allowable expenses in your books",
        "notApplicable": "Not applicable for this profile",
        "noTaxActivity": "Your work profile has no prescribed tax method, so Groot shows the figures from your books and does not work out an adjusted trade income."
      },
      "disclaimer": "Groot is AI software, not a tax adviser. The tax figures here are worked out only from your own records and published official rules, for your information. They are not tax advice and do not suggest ways to reduce your tax. For advice on your situation, please consult a licensed tax professional.",
      "iSaraanExplanation": "i-Saraan voluntary EPF contributions for self-employed qualify for personal relief up to RM7,000 (RM4,000 under paragraph 49(1)(b) + RM3,000 under paragraph 49(1)(a)). This is shared with life insurance premiums.",
      "skspsExplanation": "PERKESO Self-Employment Social Security Scheme contributions qualify for SOCSO personal relief up to RM350 per year. This cap is shared with any SOCSO contributions from employment.",
      "errors": {
        "policyUnavailable": "No reviewed official rules are available, so Groot has not calculated a number.",
        "eligibilityIncomplete": "Complete the eligibility details before choosing this method.",
        "methodUnavailable": "This method is not available for the selected activity or circumstances.",
        "contributionInvalid": "Check the contribution details and try again.",
        "contributionLocked": "This contribution is part of a saved tax calculation. Create a correction or void instead.",
        "stale": "Tax information changed elsewhere. Refresh and review the latest details.",
        "snapshotStale": "The calculation changed after this preview. Review the current result before saving.",
        "saveFailed": "Nothing was saved. Keep your entries and try again.",
        "generic": "Tax details could not be loaded. Please try again.",
        "draftRetained": "Nothing was saved. Your draft is still here so you can review it and try again."
      },
      "capitalAllowance": {
        "title": "Vehicle capital allowance inputs",
        "description": "Record your vehicle details. Groot will compute the capital allowance deduction once official rates are reviewed.",
        "vehicleCost": "Vehicle cost",
        "vehicleCostPlaceholder": "0.00",
        "purchaseYear": "Purchase year",
        "businessUsePct": "Business use percentage",
        "businessUsePctPlaceholder": "100",
        "save": "Save vehicle details",
        "saving": "Saving...",
        "saved": "Vehicle details saved.",
        "saveFailed": "Groot could not save the vehicle details. Check the values and try again.",
        "inputsRecordedNote": "Vehicle details recorded. The tax figure excludes vehicle capital allowance until official rates are reviewed."
      }
    },
    "confirmation": {
      "title": "Review before confirming",
      "description": "Check these details carefully. Nothing changes until you confirm.",
      "confirm": "Confirm change",
      "confirming": "Confirming...",
      "cancel": "Cancel",
      "prepared": "Ready for your confirmation",
      "completed": "Change confirmed.",
      "expired": "This confirmation has expired. Review the latest details and try again.",
      "alreadyUsed": "This change was already confirmed. Nothing was applied twice.",
      "changed": "The details changed after this review was prepared. Please review them again.",
      "retry": "Try confirmation again",
      "reviewAgain": "Review again",
      "confirmed": "Confirmed",
      "cancelled": "Confirmation cancelled. Nothing changed.",
      "historical": "This past confirmation is read-only.",
      "unavailable": "Confirmation is temporarily unavailable. Nothing was applied."
    },
    "settings": {
      "eyebrow": "Solo settings",
      "title": "Keep your Solo business up to date",
      "description": "The everyday settings you need for your Solo business.",
      "loading": "Loading Solo settings",
      "saving": "Saving settings...",
      "save": "Save changes",
      "saved": "Solo settings saved.",
      "saveFailed": "Could not save these settings. Please try again.",
      "readOnly": "You can view these settings, but only an owner or finance administrator can change them.",
      "businessProfile": {
        "title": "Business profile",
        "description": "Country, business details, and how you work.",
        "name": "Business name",
        "country": "Country",
        "currency": "Operational currency",
        "chooseCountry": "Choose a country",
        "chooseCurrency": "Choose a currency",
        "currencyHint": "Country and currency are separate. Groot will not guess one from the other."
      },
      "categories": {
        "title": "My categories",
        "description": "The short list used when recording income and expenses.",
        "action": "Manage categories"
      },
      "tax": {
        "title": "Tax",
        "description": "Methods, eligibility, personal contributions, and saved tax calculations.",
        "unavailable": "Tax settings will appear when reviewed official rules are available for this business."
      },
      "language": {
        "title": "Language",
        "description": "Choose the language Groot uses with you."
      },
      "plan": {
        "title": "Plan",
        "description": "Features available to this Solo business.",
        "current": "Current plan"
      },
      "sections": {
        "business": {
          "title": "Business profile",
          "description": "Country, business details, and how you work."
        },
        "categories": {
          "title": "My categories",
          "description": "The short list used when recording income and expenses."
        },
        "tax": {
          "title": "Tax",
          "description": "Methods, eligibility, personal contributions, and saved tax calculations."
        },
        "language": {
          "title": "Language",
          "description": "Choose the language Groot uses with you."
        },
        "plan": {
          "title": "Plan",
          "description": "See the features available to this Solo business."
        },
        "memory": {
          "title": "Groot memory",
          "description": "See, edit or delete what Groot remembers from your chats."
        }
      }
    },
    "errors": {
      "permission": "You do not have permission to change this Solo business.",
      "soloPlanRequired": "This action is available only for a Solo business.",
      "countryRequired": "Choose a business country to continue.",
      "countryUnsupported": "Solo launch setup currently supports Malaysia and Singapore.",
      "countryLocked": "This business already has financial or tax records, so its country cannot be changed. Create a new Solo business for a different country.",
      "profileMismatch": "That profile does not match this business country or industry. Choose another profile.",
      "categoryInput": "Enter a clear category name and try again.",
      "categoryNameTaken": "A category with that name already exists. Choose a different name.",
      "categoryMapping": "Groot could not find a safe bookkeeping destination for that category. Review your settings before continuing.",
      "categoryLimit": "You have reached the category limit. Hide an unused category or contact Groot support.",
      "policyInput": "Check the percentage, date, and reason, then try again.",
      "policyOverlap": "A home-workspace policy already covers that date. Choose a different effective date.",
      "allocationInput": "This expense cannot use the selected treatment. Review the receipt details.",
      "allocationProtected": "This recorded expense is protected and cannot be reallocated.",
      "allocationAccounts": "Groot cannot safely balance this allocation yet because a required account is not set up. Please contact Groot support.",
      "policyReviewRequired": "The official policy needs review before Groot can show this tax figure.",
      "eligibilityIncomplete": "Add the missing eligibility details before choosing this method.",
      "methodUnavailable": "This method is not available for the selected activity or circumstances.",
      "guidanceUnavailable": "No tax figure is shown until a current official policy is verified.",
      "contributionInput": "Check the contribution date, amount, scheme, and currency, then try again.",
      "contributionDateYear": "Relief is claimed the year after you pay, so the contribution date must fall in the year before the tax year shown. Change the date, or switch the tax year above.",
      "contributionLocked": "This contribution is part of a saved tax calculation. Create a correction or void instead of changing the original.",
      "iSaraanVoluntaryOnly": "i-Saraan relief applies only to your own voluntary contribution, not a compulsory one.",
      "governmentIncentiveExcluded": "Confirm this is your own contribution. Government incentives and employer matches are excluded from this relief.",
      "reliefYearMismatch": "The contribution date does not match the relief year for this scheme. Check the date and try again.",
      "staleData": "This information changed elsewhere. Refresh and review the latest details before trying again.",
      "confirmationRequired": "Review and explicitly confirm this change before it can be applied.",
      "confirmationExpired": "This confirmation expired. Prepare and review the change again.",
      "confirmationInvalid": "The business or details no longer match this confirmation. Prepare it again.",
      "confirmationAlreadyUsed": "This confirmation was already used. Nothing was applied twice.",
      "generic": "Something went wrong and no change was made. Please try again."
    },
    "workspace": {
      "navigation": "Solo workspace",
      "assistant": "Assistant",
      "books": "Money in & out",
      "settings": "Settings",
      "brand": "Groot Solo",
      "openBooks": "Open Money in & out",
      "openSettings": "Open Settings",
      "closePanel": "Close panel",
      "closeBooks": "Close Money in & out",
      "closeSettings": "Close Settings",
      "booksPanelLabel": "Money in & out panel",
      "settingsPanelLabel": "Solo Settings panel",
      "returnToAssistant": "Return focus to Assistant",
      "loadingPanel": "Loading panel"
    }
  },
  "soloSettings": {
    "eyebrow": "Solo workspace",
    "title": "Settings",
    "subtitle": "Only the details Groot needs to keep your books correctly.",
    "loading": "Loading settings",
    "saving": "Saving...",
    "save": "Save changes",
    "saved": "Settings saved.",
    "saveFailed": "Could not save settings. Please try again.",
    "business": {
      "title": "Business and currency",
      "description": "These details control reporting, document reading and accounting rules.",
      "name": "Business name",
      "country": "Country",
      "chooseCountry": "Choose a country",
      "currency": "Operational currency",
      "chooseCurrency": "Choose a currency",
      "currencyHint": "Country and currency are separate choices. Groot will not guess one from the other."
    },
    "categories": {
      "title": "Work profile and categories",
      "description": "Start with a short chart that fits your work, then customize it when needed."
    },
    "workProfile": {
      "eyebrow": "Your books",
      "title": "What kind of work do you do?",
      "description": "Groot uses your Work Profile to recommend a compact chart of accounts. These are real general-ledger accounts, so your history carries forward if you later upgrade.",
      "loading": "Loading your Work Profile",
      "choose": "Choose the closest match",
      "chooseHint": "Pick the main way you earn money. You can still add or edit categories below.",
      "apply": "Use this profile",
      "saving": "Updating...",
      "saved": "Work Profile updated. {count} new account(s) added.",
      "saveFailed": "Could not update the Work Profile. Please try again.",
      "changeSafety": "Changing profile only adds useful accounts. Groot never deletes or rewrites accounts that already have history.",
      "profiles": {
        "services": {
          "title": "Professional & financial services",
          "description": "Advisers, insurance agents, consultants and freelancers"
        },
        "fnb": {
          "title": "Food & drink",
          "description": "Home cafes, baking, stalls and catering"
        },
        "retail": {
          "title": "Retail & reselling",
          "description": "Online shops, marketplaces and second-hand goods"
        },
        "gig": {
          "title": "Gig & delivery",
          "description": "Ride-hailing, delivery and platform work"
        },
        "manufacturing": {
          "title": "Making products",
          "description": "Products you make, assemble or package"
        },
        "other": {
          "title": "Other solo work",
          "description": "A simple general-purpose starting point"
        }
      },
      "recommended": {
        "title": "Your recommended chart",
        "description": "{count} focused accounts cover the usual money in, costs, cash and owner activity for this profile.",
        "count": "{count} accounts"
      },
      "groups": {
        "income": "Money in",
        "costs": "Costs & expenses",
        "money": "Cash & owner"
      }
    },
    "language": {
      "title": "Language",
      "description": "Choose the language used by Groot and the app."
    },
    "upgrade": {
      "title": "Need invoices or team features?",
      "description": "Contact us. Solo pricing and self-serve checkout are not available yet."
    }
  },
  "agentMode": {
    "placeholder": "Type your request...",
    "shortcut": "⌘K to toggle",
    "workspace": "Autopilot workspace",
    "prompt": "What would you like done?",
    "followUp": "Follow up...",
    "jumpToLatest": "Jump to the latest",
    "composerLabel": "Agent input",
    "composerFootnote": "Groot is AI and can make mistakes, so check important figures. It does not give tax or legal advice.",
    "suggestionChips": {
      "label": "Suggested questions"
    },
    "inputLabel": "Type your request to the agent",
    "submit": "Send",
    "micDisabled": "Voice input (coming soon)",
    "hero": {
      "start": "What would you like Groot to handle?",
      "subhead": "Start with a task or ask a question about your business.",
      "placeholder": "Describe a task, or ask about your business…",
      "connecting": "Connecting securely…",
      "starting": "Starting your request…",
      "greetingTime": "Good {part}, {name}",
      "help": "What can I help with?",
      "go": "Let's get started.",
      "morning": "morning",
      "afternoon": "afternoon",
      "evening": "evening"
    },
    "soloHero": {
      "start": "What happened in your business today?",
      "greetingTime": "Good {part}, {name}",
      "help": "What should I record today?",
      "go": "Ask me how your month is going.",
      "morning": "morning",
      "afternoon": "afternoon",
      "evening": "evening",
      "status": "Your bookkeeping assistant",
      "subhead": "Record money in, add a receipt, upload a statement, or ask a question about your books.",
      "placeholder": "Tell me what happened, or ask about your books…",
      "connecting": "Connecting securely to your books…",
      "starting": "Starting your request…"
    },
    "soloHeader": {
      "navigation": "Solo workspace",
      "assistant": "Assistant",
      "books": "Money in & out",
      "settings": "Settings",
      "brand": "Groot Solo"
    },
    "businessHeader": {
      "brand": "Groot Autopilot"
    },
    "sidebar": {
      "label": "Past tasks",
      "open": "Open conversation history",
      "close": "Close past tasks",
      "newRun": "New task",
      "search": "Search tasks…",
      "recent": "Recent",
      "loading": "Loading tasks…",
      "empty": "No tasks yet",
      "noMatches": "No matching tasks",
      "rename": "Rename",
      "renameLabel": "Rename task",
      "delete": "Delete forever",
      "confirmDelete": "Confirm delete",
      "cancelDelete": "Cancel",
      "status": {
        "waiting": "Waiting for you",
        "running": "Running",
        "done": "Done",
        "error": "Failed"
      },
      "alerts": "Alerts",
      "alertsUnread": "{count} unread",
      "alertsUnreadCapped": "20+",
      "pastChats": "Past chats"
    },
    "alertsView": {
      "title": "Alerts",
      "intro": "What Groot has flagged for you, newest first.",
      "back": "Back to Groot"
    },
    "pastChat": {
      "note": "An earlier chat. You can read it here, but not reply to it.",
      "ask": "Ask Groot about this",
      "askPrompt": "I want to follow up on an earlier chat called \"{title}\". ",
      "untitled": "Untitled chat",
      "back": "Back to Groot",
      "loading": "Loading this chat",
      "error": "We could not load this chat. Please try again in a moment.",
      "askFailed": "We could not start a new task. Please try again."
    },
    "recipe": {
      "submitExpenses": "Submit my expenses",
      "reconcile": "Reconcile last month",
      "quarterReport": "Draft the Q report",
      "approveClaims": "Approve pending claims",
      "recordIncome": "Record income",
      "addReceipt": "Add a receipt",
      "addStatement": "Upload a statement",
      "monthSummary": "How is my month looking?",
      "recentSpending": "What have I spent recently?",
      "comingSoon": "Soon"
    },
    "recipeHint": {
      "submitExpenses": "Upload receipts and prepare a report",
      "reconcile": "Review activity against a bank account",
      "quarterReport": "Review this quarter, with the board PDF attached",
      "approveClaims": "Review the queue before any approval",
      "recordIncome": "Enter a commission or payment",
      "addReceipt": "Photograph a business expense",
      "addStatement": "Bank, Grab, or platform file",
      "monthSummary": "See what you earned and kept"
    },
    "soloSummary": {
      "eyebrow": "From your ledger",
      "title": "This month so far",
      "summary": "You earned {earned}, spent {spent}, and kept {kept}.",
      "empty": "There is no income or expense recorded for this month yet.",
      "earned": "Money in (income)",
      "spent": "Money out (expenses)",
      "kept": "Kept (profit)",
      "openBooks": "See the details in Money in & out",
      "loading": "Loading this month",
      "close": "Close month summary"
    },
    "recipePrompt": {
      "reconcile": "Show me bank reconciliation status for last month and help me reconcile the right bank account. Ask me which bank account before running reconciliation.",
      "quarterReport": "Review this quarter to date: profit and loss, month by month, receivables and payables, cash and the biggest expenses, and attach the board report PDF.",
      "approveClaims": "Show the expense claims waiting for my approval and help me review them. Do not approve anything until I explicitly confirm a specific expense report.",
      "monthSummary": "How is my month looking? Show my profit and loss for this month and explain what I earned, spent, and kept in plain language.",
      "recentSpending": "Show what I spent this month, broken down by category."
    },
    "incomeCapture": {
      "transcriptPrompt": "Record income",
      "timelineReady": "Income details ready",
      "eyebrow": "Money in",
      "readyBadge": "Ready",
      "reviewNotice": "Nothing is recorded until you confirm.",
      "recordedBadge": "Recorded",
      "recordedTitle": "Income recorded",
      "recordedDescription": "{amount} was added to your books for {date}."
    },
    "timeline": {
      "label": "Task progress",
      "error": "Something went wrong",
      "reference": "Reference for support:",
      "fold": {
        "title": "Worked on your request",
        "steps": "{count, plural, one {# step} other {# steps}}",
        "seconds": "{seconds} s",
        "minutes": "{minutes} min {seconds} s",
        "show": "Show the steps",
        "waiting": "Needs your input",
        "hide": "Hide the steps"
      }
    },
    "notes": {
      "eyebrow": "On reading your request..."
    },
    "tools": {
      "prepare_payment_reminder_change": "Prepare payment reminder change",
      "get_payment_reminder_policy": "Read payment reminder settings",
      "create_expense_from_receipt": "Create expense from receipt",
      "confirm_proposal": "Confirm proposal",
      "list_expense_submissions": "List expense submissions",
      "get_my_expense_claims": "Get my expense claims",
      "submit_expense_submission": "Submit expense submission",
      "approve_expense_submission": "Approve expense submission",
      "reject_expense_submission": "Reject expense submission",
      "get_employee_expenses": "Get employee expenses",
      "get_late_approvals": "Get late approvals",
      "reimburse_expense": "Reimburse expense",
      "list_departments": "List departments",
      "list_projects": "List projects",
      "get_sales_invoices": "Get sales invoices",
      "get_ar_summary": "Get receivables summary",
      "get_transactions": "Get transactions",
      "get_expense_submission": "Get expense submission",
      "explain_routing": "Explain approval routing",
      "list_approval_policies": "List approval policies",
      "update_expense_claim_fields": "Update expense claim fields",
      "update_expense_submission": "Update expense submission",
      "get_invoices": "Get vendor invoices",
      "get_ap_aging": "Get payables aging",
      "get_vendors": "Get vendors",
      "analyze_vendor_risk": "Analyze vendor risk",
      "analyze_price_trends": "Analyze price trends",
      "get_business_transactions": "Get business transactions",
      "run_bank_reconciliation": "Run bank reconciliation",
      "show_recon_status": "Show reconciliation status",
      "accept_recon_match": "Accept reconciliation match",
      "generate_pnl": "Generate profit and loss",
      "get_profit_loss_monthly": "Get monthly profit and loss",
      "generate_balance_sheet": "Generate balance sheet",
      "generate_trial_balance": "Generate trial balance",
      "generate_cash_flow": "Generate cash flow statement",
      "generate_report_pdf": "Generate report PDF",
      "forecast_cash_flow": "Forecast cash flow",
      "analyze_trends": "Analyze trends",
      "detect_anomalies": "Detect anomalies",
      "check_budget_status": "Check budget status",
      "set_budget": "Set budget",
      "compare_to_industry": "Compare to industry",
      "get_action_center_insight": "Get Action Center insight",
      "send_email_report": "Send email report",
      "get_team_summary": "Get team summary",
      "compare_team_spending": "Compare team spending",
      "analyze_team_spending": "Analyze team spending",
      "get_leave_balances": "Get leave balances",
      "get_leave_requests": "Get leave requests",
      "get_leave_types": "Get leave types",
      "get_leave_report": "Get leave report",
      "get_my_attendance": "Get my attendance",
      "get_team_calendar": "Get team calendar",
      "get_public_holidays": "Get public holidays",
      "get_team_attendance": "Get team attendance",
      "search_regulatory_knowledge_base": "Search regulatory knowledge base",
      "schedule_report": "Schedule report",
      "create_leave_request": "Create leave request",
      "clock_in": "Clock in",
      "clock_out": "Clock out",
      "cancel_proposal": "Cancel proposal",
      "check_customer_einvoice_readiness": "Check customer e-invoice readiness",
      "send_debtor_onboarding_form": "Send debtor onboarding form",
      "ingest_grab_statement": "Import Grab statement",
      "get_marketplace_settlement_status": "Get marketplace settlement status",
      "submit_optimization": "Submit optimization",
      "migrate_to_approval_policies": "Migrate to approval policies",
      "create_proposal": "Create proposal",
      "memory_store": "Store memory",
      "memory_search": "Search memory",
      "memory_recall": "Recall memory",
      "memory_forget": "Forget memory",
      "search_sales_invoice_context": "Search sales invoice context",
      "save_sales_invoice_workspace": "Save sales invoice workspace",
      "preview_sales_invoice_workspace": "Preview sales invoice workspace",
      "get_official_receipt": "Read Official Receipts",
      "send_official_receipt": "Prepare receipt email",
      "issue_and_record_paid": "Issue & record as paid",
      "refund_invoice": "Prepare invoice refund",
      "record_customer_payment": "Prepare customer payment",
      "prepare_invoice_command": "Prepare invoice command",
      "get_accounting_correction_options": "Get accounting correction options",
      "get_accounting_change_history": "Get accounting change history",
      "prepare_accounting_correction": "Prepare accounting correction",
      "manage_operational_orders": "Manage operational orders",
      "prepare_solo_profile_or_category_change": "Prepare profile or category change",
      "confirm_solo_profile_or_category_change": "Confirm profile or category change",
      "preview_solo_expense_treatment": "Preview expense treatment",
      "prepare_solo_home_workspace_policy": "Prepare home workspace policy",
      "confirm_solo_home_workspace_policy": "Confirm home workspace policy",
      "get_solo_finance_overview": "Get finance overview",
      "prepare_solo_tax_change": "Prepare tax change",
      "confirm_solo_tax_change": "Confirm tax change",
      "recurring_schedule_list": "List recurring schedules",
      "recurring_schedule_get": "Get recurring schedule",
      "recurring_schedule_create": "Create recurring schedule",
      "recurring_schedule_set_active": "Set recurring schedule active",
      "recurring_schedule_remove": "Remove recurring schedule",
      "recurring_schedule_update": "Update recurring schedule",
      "approve_leave_request": "Approve leave request",
      "reject_leave_request": "Reject leave request",
      "reverse_customer_payment": "Reverse customer payment",
      "reverse_supplier_payment_run": "Reverse supplier payment run",
      "create_department": "Create department",
      "create_project": "Create project",
      "assign_member_department": "Assign member to department",
      "create_approval_policy": "Create approval policy",
      "update_approval_policy": "Update approval policy",
      "deactivate_approval_policy": "Deactivate approval policy",
      "toggle_benchmarking": "Toggle benchmarking",
      "set_claim_department_or_project": "Set claim department or project",
      "get_sales_by_agent": "Get sales by agent",
      "inspect_bank_statement_upload": "Inspect bank statement upload",
      "prepare_bank_statement_import": "Prepare bank statement import",
      "list_bank_statement_review": "List bank statement review",
      "list_payables_by_meaning": "List payables by meaning",
      "inspect_cash_item": "Inspect bank line",
      "find_cash_source_candidates": "Find source records for a bank line",
      "get_cash_movement_options": "Get bank line options",
      "get_cash_correction_route": "Get bank line correction route",
      "prepare_cash_match": "Prepare bank line match",
      "list_cash_offset_accounts": "List bank interest and charge accounts",
      "prepare_cash_movement": "Prepare cash movement",
      "list_cash_book": "List Cash Book",
      "list_advance_deposit_reviews": "List advance and deposit reviews",
      "list_bank_recon_rules": "List bank statement line rules",
      "get_bank_closing_proof": "Check statement closing balance",
      "prepare_cash_reversal": "Prepare cash reversal",
      "prepare_transfer_arrival": "Prepare transfer arrival",
      "get_fx_gain_loss": "Get FX gain and loss",
      "get_supplier_statement": "Get supplier statement",
      "get_party_balance": "Get customer or supplier balance",
      "check_order_stock_availability": "Check stock for an order",
      "list_sales_orders": "List sales orders",
      "get_my_sales": "Get my sales",
      "get_customer_invoice_status": "Get customer invoice status",
      "get_unrealised_fx_exposure": "Get unrealised FX exposure",
      "get_stock_value_and_dish_costs": "Get stock value and dish costs",
      "capture_grab_orders": "Capture Grab orders",
      "get_items_sold_batch": "Get items sold batch",
      "post_items_sold_batch": "Post items sold batch",
      "classify_bank_transaction": "Classify bank transaction",
      "add_project": "Add project",
      "get_year_end_status": "Check year-end status",
      "close_financial_year": "Close financial year",
      "generate_statement_of_changes_in_equity": "Generate statement of changes in equity",
      "list_delivered_not_invoiced": "List deliveries not yet invoiced"
    },
    "lifecycle": {
      "understanding": "Reading your request…",
      "planning": "{summary}",
      "calling": "Calling {tool}…",
      "retrying": "Retrying…",
      "waiting_decision": "Waiting for your decision",
      "confirm_action": "Please confirm this action",
      "all_done": "All done",
      "done_unverified": "Done, but one result could not be confirmed",
      "done_refused": "That request was not carried out",
      "done_question": "Waiting for your answer",
      "timed_out": "Timed out. Please try again with a simpler request",
      "tool_budget_exhausted": "This request needed too many steps. Please try a narrower request.",
      "unmet_deps": "Unable to proceed: some tasks have unmet dependencies",
      "error_generic": "A step in the plan failed. Please try again.",
      "error_unexpected": "Something went wrong while processing your request. Please try again.",
      "needs_receipt": "Please attach a receipt to file an expense.",
      "autopilot_only": "I can only handle expense filing in Autopilot mode right now. Try Chat mode for other requests.",
      "dispatching": "Asking the {domain} specialist…",
      "verifying": "Checking the result…",
      "remediating": "Fixing a failed step…",
      "resuming": "Picking up where we left off…",
      "write_gate": "This step changes your data, so it paused here for a person to confirm.",
      "planner_declined": "I can't do that with the tools I have.",
      "restricted_role": "That action is for a higher role.",
      "restricted_plan": "That isn't part of your plan.",
      "restricted_addon": "That is an add-on that is not switched on.",
      "planner_unavailable": "Autopilot is temporarily unavailable. Please try again.",
      "still_waiting": "Still waiting for your confirmation",
      "retry_specialist": "Retrying with the specialist…",
      "confirmed_executing": "Confirmed, now executing…",
      "confirm_stale": "That confirmation is no longer pending.",
      "memory_noted": "Noted, I'll remember that.",
      "memory_offered": "Want me to remember that?",
      "refining_preview": "Updating the preview with your choice…",
      "confirm_superseded": "That card is out of date. Use the latest one.",
      "refine_not_applied": "I could not apply that choice. The earlier preview is still waiting.",
      "pick_employee": "Choose an employee to continue",
      "reading_receipts": "Reading {count, plural, one {# receipt} other {# receipts}}…",
      "read_receipts_progress": "Read {completed} of {total, plural, one {# receipt} other {# receipts}}",
      "reading_attachments": "Reading {count, plural, one {# attachment} other {# attachments}}…",
      "read_attachments_progress": "Read {completed} of {total, plural, one {# attachment} other {# attachments}}",
      "customer_order_read": "Customer order read",
      "attachments_checked": "Attachments checked",
      "restricted_switch": "That is turned off for you."
    },
    "task": {
      "extract": "Create expense from receipt",
      "confirm": "Confirm expense proposal",
      "dedupe": "Check for duplicates",
      "submit": "Submit for approval",
      "route": "Route to approver"
    },
    "voice": {
      "start": "Start voice input",
      "stop": "Stop recording",
      "listening": "Listening…",
      "transcribing": "Transcribing…",
      "permissionDenied": "Microphone access is blocked. Enable it in your browser or device settings.",
      "noSpeech": "No speech detected. Please try again.",
      "unavailable": "Voice input is temporarily unavailable. Please type instead.",
      "limitReached": "Reached the 60-second limit.",
      "network": "Couldn't reach the transcription service. Check your connection.",
      "error": "Something went wrong with voice input."
    },
    "confirmCard": {
      "title": "Confirm this step",
      "fallbackMessage": "This step is waiting for your confirmation.",
      "checking": "Checking status…",
      "confirmButton": "Confirm",
      "cancelButton": "Cancel",
      "processing": "Working on it…",
      "confirmedBadge": "Confirmed",
      "cancelledBadge": "Cancelled",
      "confirmedMessage": "Confirmed. The step was executed.",
      "cancelledMessage": "Cancelled. Nothing was executed.",
      "staleMessage": "This confirmation is no longer pending.",
      "sendFailedMessage": "That did not go through. Please try again.",
      "supersededMessage": "This preview was replaced by a newer one.",
      "historicalHint": "This confirmation belonged to an earlier run.",
      "openAutopilotHint": "Open the Autopilot workspace to confirm this step.",
      "transcriptConfirm": "Confirmed. Go ahead.",
      "transcriptCancel": "Cancel that step."
    },
    "bankPicker": {
      "transcript": "Pay from {account}.",
      "transcriptWithDate": "Pay from {account} on {date}.",
      "updating": "Updating the preview…",
      "failed": "That choice could not be applied, so nothing changed. Please try again."
    },
    "proposalSettled": {
      "confirmed": "You confirmed this action.",
      "cancelled": "You cancelled this action.",
      "failed": "The action was confirmed, but the run status could not be updated."
    },
    "confirmHint": "Press the button on the card above to go ahead; typing yes does not confirm it.",
    "receiptCommand": {
      "refundInvoice": "Refund invoice",
      "reason": "Reason",
      "tax": "Tax returned",
      "receiptValid": "The Official Receipt stays valid.",
      "sendNote": "Send refund note",
      "noteSent": "Refund note email sent.",
      "issueAndPaid": "Issue & record as paid",
      "fee": "Per-order fee",
      "net": "Net received",
      "title": "Confirm payment or receipt",
      "recorded": "Payment recorded.",
      "recordPayment": "Record customer payment",
      "sendReceipt": "Send receipt",
      "receiptNumber": "Official Receipt",
      "recipient": "Recipient",
      "method": "Method",
      "date": "Payment date",
      "reference": "Reference",
      "willIssue": "Your confirmation will record this payment and issue an Official Receipt.",
      "settingOff": "Records the payment without an Official Receipt because Official Receipts are off.",
      "pendingClearance": "The Official Receipt will be issued when the cheque is confirmed cleared.",
      "externalReceipt": "External receipt of record: {system}, {reference}. No Groot Official Receipt will be issued.",
      "recordedReceipt": "Payment recorded. Official Receipt {number}.",
      "sent": "Receipt email sent.",
      "void": "This receipt is void and cannot be sent.",
      "prepareSendError": "Could not prepare sending. Check that the receipt is still issued and the payer has an email address.",
      "resendNotice": "The receipt email was not confirmed as sent. Press Confirm to send it again.",
      "methods": {
        "cash": "Cash",
        "bank_transfer": "Bank transfer",
        "cheque": "Cheque",
        "card": "Card",
        "other": "Other"
      },
      "fx": {
        "homeAmount": "Amount received",
        "rate": "Rate",
        "carried": "Carried in the books",
        "gain": "Expected realised gain",
        "loss": "Expected realised loss",
        "none": "Expected exchange difference",
        "noneValue": "None",
        "sourceBnm": "Bank Negara buying rate",
        "sourceManual": "Your saved rate",
        "note": "Groot priced this receipt; the agent cannot state the amount received. To enter the exact bank amount, record the receipt on the Receive payment page."
      }
    },
    "invoiceCommand": {
      "title": "Confirm invoice action",
      "effectPromote": "Create invoice draft",
      "effectIssue": "Issue invoice",
      "customerLabel": "Customer",
      "amountLabel": "Total",
      "linesLabel": "Line items",
      "invoiceNumberLabel": "Invoice number",
      "lhdnBadge": "e-Invoice applies",
      "expiresLabel": "Expires",
      "reviewNotice": "Review the exact effect below before you confirm.",
      "confirmButton": "Confirm",
      "confirming": "Confirming…",
      "confirmedBadge": "Confirmed",
      "confirmedMessage": "Confirmed. The invoice action was completed.",
      "confirmedInvoice": "Confirmed. Invoice {number} is ready.",
      "staleNotice": "This invoice changed since it was shown.",
      "reprepareHint": "Ask me to prepare it again.",
      "unauthorizedNotice": "You do not have permission to confirm this action.",
      "errorNotice": "We could not complete that invoice action. Please try again.",
      "lhdnAgentSubmitNotAvailable": "Submitting to LHDN from chat is not available yet, and nothing was submitted.",
      "expiredNotice": "This confirmation is no longer available. Prepare it again.",
      "cancelledNotice": "This invoice card was cancelled. Ask again to prepare a new one.",
      "supersededNotice": "A newer version of this card replaced it.",
      "historicalNotice": "This confirmation belonged to an earlier step.",
      "saleTypeLabel": "Sale type",
      "saleTypeCash": "Cash sale (no receivable)",
      "receivedIntoLabel": "Received into",
      "bankCreditLabel": "Bank credit",
      "bankCreditValue": "{date} · {description} · {amount}",
      "officialReceiptIssues": "Posting will issue an Official Receipt.",
      "officialReceiptNone": "Posts without an Official Receipt: {reason}.",
      "effectSubmitLhdn": "Submit e-invoice to LHDN",
      "buyerLabel": "Buyer",
      "buyerTinLabel": "Buyer TIN",
      "buyerTinMissing": "Not on file",
      "submitLhdnNotice": "Confirming starts this invoice's submission to LHDN (MyInvois).",
      "submitLhdnBuyerEmail": "If LHDN validates it, the e-invoice and its status updates may be emailed to the buyer at {email}.",
      "submitLhdnInitiated": "Submission to LHDN initiated. Status: Pending. Open the invoice to follow it.",
      "submitLhdnInitiatedNoStatus": "Submission to LHDN initiated. Open the invoice to follow it.",
      "fxIssue": {
        "homeAmount": "Posts to the books as",
        "sourceTyped": "Rate typed on the invoice"
      }
    },
    "invoiceWorkspace": {
      "customerMatch": {
        "title": "Customer match",
        "none": "No matching customer found.",
        "use": "Use",
        "useMessage": "Use customer {name} for this invoice."
      },
      "catalogResolution": {
        "title": "Item match",
        "none": "No matching item found.",
        "use": "Use",
        "useMessage": "Use item {name} on this invoice."
      },
      "commercialSummary": {
        "title": "Invoice summary",
        "customer": "Customer",
        "subtotal": "Subtotal",
        "discount": "Discount",
        "tax": "Tax",
        "total": "Total",
        "lines": "Line items",
        "lhdn": "e-Invoice applies"
      },
      "missingData": {
        "title": "Needs your input",
        "allResolved": "Everything needed is filled in.",
        "resolve": "Resolve",
        "resolveMessage": "Help me resolve: {item}"
      },
      "controls": {
        "title": "What you can do",
        "none": "No actions available yet.",
        "choose": "Choose",
        "required": "Required",
        "selectCustomer": {
          "label": "Choose customer",
          "message": "Help me choose the customer for this invoice."
        },
        "selectCatalogItem": {
          "label": "Add a saved item",
          "message": "Add a saved catalog item to this invoice."
        },
        "addOneOffLine": {
          "label": "Add a one-off line",
          "message": "Add a one-off line item to this invoice."
        },
        "saveAsService": {
          "label": "Save line as a service",
          "message": "Save this line as a reusable service."
        },
        "saveAsProduct": {
          "label": "Save line as a product",
          "message": "Save this line as a product item."
        },
        "selectPriceTier": {
          "label": "Choose a price tier",
          "message": "Apply a price tier to this invoice."
        },
        "selectStockSource": {
          "label": "Choose stock location",
          "message": "Choose which stock location to fulfil from."
        },
        "reviewInventoryImpact": {
          "label": "Review stock impact",
          "message": "Show the stock impact of issuing this invoice."
        },
        "acknowledgeNegativeStock": {
          "label": "Acknowledge stock shortfall",
          "message": "Acknowledge the negative-stock impact before issuing."
        },
        "reviewLhdnReadiness": {
          "label": "Check e-Invoice readiness",
          "message": "Check LHDN e-Invoice readiness for this invoice."
        },
        "setupCatalogItem": {
          "label": "Create a catalog item",
          "message": "Create a catalog item so I can reuse it."
        }
      },
      "surface": {
        "title": "Invoice workspace",
        "controlsHeading": "What you can do",
        "previewHeading": "Invoice preview",
        "openInEditor": "Open in editor",
        "reviewAndConfirm": "Review and confirm",
        "prepareMessage": "Prepare this invoice for me to confirm.",
        "empty": "Start by telling me who to bill and what for.",
        "status": {
          "idle": "Ready",
          "saving": "Saving",
          "saved": "Saved",
          "conflict": "Updated elsewhere, review the latest",
          "error": "Could not save, retry"
        }
      }
    },
    "runFeedback": {
      "prompt": "Did this get the job done?",
      "retry": "That didn't save - try again?",
      "helpful": "Yes, this worked",
      "notHelpful": "No, this missed",
      "thanksPositive": "Thanks - noted.",
      "thanksNegative": "Thanks - we'll learn from this.",
      "error": "Could not save your feedback. Please try again."
    },
    "workRecord": {
      "title": "Work record",
      "show": "Show the work record",
      "hide": "Hide the work record",
      "summaryCount": "{count, plural, one {# item} other {# items}}",
      "attentionHeading": "Needs your input",
      "trailHeading": "What I did",
      "supersededBadge": "Updated",
      "error": "Couldn't load the work record. Please try again.",
      "provenance": {
        "verified": "Verified",
        "computed": "Calculated",
        "policy": "From your settings",
        "inferred": "Interpreted",
        "missing": "Needs your input"
      },
      "status": {
        "started": "In progress",
        "completed": "Done",
        "blocked": "Needs your input",
        "failed": "Failed",
        "skipped": "Skipped"
      },
      "nextAction": {
        "confirm": "Confirm to continue",
        "supply_input": "Add the missing detail",
        "retry": "Send your request again to retry",
        "resume": "Reply or confirm to continue",
        "open_record": "Open the record"
      },
      "evidence": {
        "title": "Evidence",
        "close": "Close",
        "empty": "No evidence attached.",
        "button": "View evidence ({count})",
        "openAria": "View evidence for {label}",
        "version": "Version {version}",
        "observedAt": "As of {at}",
        "kind": {
          "record": "Record",
          "calculation": "Calculation",
          "policy": "Policy",
          "user_input": "Your input"
        }
      },
      "customerMatched": "Matched one customer",
      "customerMatchedDetail": "Found a single matching customer.",
      "customerAmbiguous": "Multiple customers match",
      "customerAmbiguousDetail": "More than one customer matches. Pick the right one.",
      "customerMissing": "Customer needed",
      "customerMissingDetail": "No customer is selected yet.",
      "catalogMatched": "Matched a catalog item",
      "catalogMatchedDetail": "Resolved a catalog item.",
      "catalogAmbiguous": "Multiple items match",
      "catalogAmbiguousDetail": "More than one catalog item matches.",
      "catalogMissing": "Item details needed",
      "catalogMissingDetail": "This line has no resolved catalog item.",
      "lineTotalComputed": "Line total calculated",
      "lineTotalComputedDetail": "Calculated from {quantity} × {unitPrice}.",
      "invoiceTotalComputed": "Invoice total calculated",
      "invoiceTotalComputedDetail": "Totalled {lineCount} line item(s).",
      "paymentTermsApplied": "Payment terms applied",
      "paymentTermsAppliedDetail": "Applied payment terms from your settings.",
      "dueDateApplied": "Due date set",
      "dueDateAppliedDetail": "Set the due date from the invoice details.",
      "taxApplied": "Tax applied",
      "taxAppliedDetail": "Applied the configured tax rate.",
      "priceTierApplied": "Price tier applied",
      "priceTierAppliedDetail": "Applied the configured price tier.",
      "wordingInferred": "Interpreted your wording",
      "wordingInferredDetail": "This wording may mean {interpretation}. Please confirm.",
      "recipientMissing": "Recipient email needed",
      "recipientMissingDetail": "A recipient email is required to deliver this invoice.",
      "lhdnReadinessMissing": "e-Invoice details needed",
      "lhdnReadinessMissingDetail": "Some LHDN e-Invoice details are missing.",
      "artifactReady": "Prepared a view",
      "artifactReadyDetail": "A supporting view is ready to open.",
      "workspaceSaved": "Draft saved",
      "workspaceSavedDetail": "Your invoice draft is saved and can be resumed.",
      "previewReady": "Preview ready for review",
      "previewReadyDetail": "The invoice preview is ready. Review it before confirming.",
      "runStarted": "Started working",
      "runBlocked": "Needs your input",
      "runBlockedDetail": "Stopped and saved progress; one action is needed to continue.",
      "runFailed": "Could not complete",
      "runFailedDetail": "Something went wrong. Nothing was changed; you can retry.",
      "runCompleted": "Done",
      "runCompletedDetail": "Finished the requested work."
    },
    "workingLabel": "Working on it…",
    "receiptTray": {
      "heading": "Receipts to claim",
      "status": {
        "uploading": "Uploading",
        "checking": "Checking",
        "failed": "Upload failed",
        "receipt": "Receipt",
        "paidInvoice": "Paid invoice",
        "unpaidInvoice": "Unpaid invoice",
        "unreadable": "Hard to read",
        "rejected": "Not a receipt",
        "unsupported": "Can't be claimed",
        "ready": "Ready",
        "includedAnyway": "Included anyway",
        "matching": "Looking for earlier claims",
        "claimed": "Already claimed",
        "repeated": "Same receipt twice",
        "inDraft": "Already in a draft"
      },
      "detail": {
        "unpaidInvoice": "No payment shown",
        "failed": "Remove it to continue",
        "unsupported": "Only photos and PDFs can be claimed"
      },
      "summary": {
        "total": "{count, plural, one {# file} other {# files}}",
        "uploading": "{count} uploading",
        "checking": "{count} checking",
        "ready": "{count} ready",
        "unpaidInvoice": "{count, plural, one {# unpaid invoice} other {# unpaid invoices}}",
        "unreadable": "{count} hard to read",
        "rejected": "{count} not a receipt",
        "includedAnyway": "{count} included anyway",
        "failed": "{count} failed to upload",
        "unsupported": "{count} can't be claimed",
        "matching": "{count} looking for earlier claims",
        "alreadyClaimed": "{count} already claimed",
        "repeated": "{count} repeated",
        "inDraft": "{count} already in a draft",
        "possible": "{count} possibly claimed already",
        "notChecked": "{count} not checked for earlier claims"
      },
      "useAnyway": "Use anyway",
      "remove": "Remove {name}",
      "createClaim": "Create claim ({count})",
      "creating": "Creating claim",
      "createFailed": "We couldn't create the claim. Please try again.",
      "createNotVerified": "We couldn't confirm one of these files. Remove it, add it again, then try once more.",
      "note": {
        "claimed": "Already claimed in {where}",
        "claimedBare": "Already claimed on an earlier claim",
        "inDraft": "Already in your draft {where}",
        "inDraftBare": "Already in one of your drafts",
        "possible": "Possibly also in {where}",
        "possibleWithDifferences": "Possibly also in {where}. {differences}",
        "possibleBare": "Possibly claimed already",
        "more": "and {count} more",
        "repeated": "Same receipt as {name} above",
        "notChecked": "Not checked for earlier claims",
        "open": "Open",
        "openReport": "Open {where}"
      },
      "leftOutHint": "{count, plural, one {# receipt left out as already claimed or repeated. Tap Use anyway to include it.} other {# receipts left out as already claimed or repeated. Tap Use anyway to include one.}}",
      "allClaimed": "All of these are already claimed. Tap Use anyway to include one.",
      "leftOutToast": "{created, plural, one {# claim created.} other {# claims created.}} {left, plural, one {# receipt left out because it is already claimed.} other {# receipts left out because they are already claimed.}}"
    },
    "replyChips": {
      "label": "Ask next",
      "receivablesOverdue": "Which invoices are overdue?",
      "receivablesByCustomer": "Show receivables by customer",
      "receivablesAging": "How old are the unpaid invoices?",
      "payablesOverdue": "Which supplier bills are overdue?",
      "payablesBySupplier": "Show payables by supplier",
      "payablesDueSoon": "What is due to suppliers this week?",
      "pnlBiggestExpenses": "What were the biggest expenses?",
      "pnlComparePrevious": "How does that compare with the previous month?",
      "pnlByMonth": "Show it month by month",
      "monthlyBestMonth": "Which month had the highest revenue?",
      "monthlyExpenses": "Show the expenses month by month",
      "balanceSheetLiabilities": "What are the biggest liabilities?",
      "balanceSheetCash": "How much cash do we hold?"
    },
    "cardTitles": {
      "charts": {
        "monthly_revenue": "Monthly revenue and profit",
        "projected_balance": "Projected cash balance"
      },
      "get_ar_summary": "Receivables summary",
      "get_ap_aging": "Payables aging",
      "get_sales_invoices": "Sales invoices",
      "list_sales_orders": "Sales orders",
      "get_vendors": "Vendors",
      "get_business_transactions": "Business transactions",
      "get_transactions": "Transactions",
      "list_expense_submissions": "Expense submissions",
      "get_my_expense_claims": "My expense claims",
      "get_employee_expenses": "Employee expenses",
      "get_late_approvals": "Late approvals",
      "list_departments": "Departments",
      "list_projects": "Projects",
      "list_approval_policies": "Approval policies",
      "show_recon_status": "Reconciliation status",
      "generate_pnl": "Profit and loss",
      "get_profit_loss_monthly": "Monthly profit and loss",
      "generate_balance_sheet": "Balance sheet",
      "generate_trial_balance": "Trial balance",
      "generate_cash_flow": "Cash flow statement",
      "forecast_cash_flow": "Cash flow forecast",
      "analyze_trends": "Trends",
      "analyze_vendor_risk": "Vendor risk",
      "analyze_price_trends": "Price trends",
      "detect_anomalies": "Anomalies",
      "check_budget_status": "Budget status",
      "compare_to_industry": "Industry comparison",
      "get_team_summary": "Team summary",
      "compare_team_spending": "Team spending comparison",
      "analyze_team_spending": "Team spending",
      "get_leave_balances": "Leave balances",
      "get_leave_requests": "Leave requests",
      "get_leave_types": "Leave types",
      "get_leave_report": "Leave report",
      "get_my_attendance": "My attendance",
      "get_team_calendar": "Team calendar",
      "get_public_holidays": "Public holidays",
      "get_team_attendance": "Team attendance",
      "get_marketplace_settlement_status": "Marketplace settlement status",
      "recurring_schedule_list": "Recurring schedules",
      "get_sales_by_agent": "Sales by agent",
      "list_cash_book": "Cash Book",
      "get_fx_gain_loss": "FX gain and loss",
      "get_supplier_statement": "Supplier statement",
      "get_party_balance": "Customer or supplier balance",
      "get_unrealised_fx_exposure": "Unrealised FX exposure",
      "get_stock_value_and_dish_costs": "Stock value and dish costs",
      "check_order_stock_availability": "Stock check",
      "get_solo_finance_overview": "Finance overview",
      "get_official_receipt": "Official receipts",
      "get_accounting_change_history": "Change history",
      "generate_statement_of_changes_in_equity": "Statement of changes in equity",
      "list_delivered_not_invoiced": "Delivered, not invoiced"
    },
    "quarterReview": {
      "cards": {
        "pnlToDate": "Profit and loss, quarter to date",
        "pnlWhole": "Profit and loss, quarter",
        "monthlyToDate": "Month by month, quarter to date",
        "monthlyWhole": "Month by month, quarter",
        "topExpensesToDate": "Top expenses, quarter to date",
        "topExpensesWhole": "Top expenses, quarter",
        "category": "Category",
        "amount": "Amount",
        "operatingExpenses": "Operating expenses",
        "monthlyTrailing": "Last 4 months"
      },
      "attachment": {
        "download": "Download",
        "supportingDocument": "Supporting document",
        "preparing": "Preparing the PDF",
        "periodRange": "{from} to {to}",
        "defaultName": "Board report"
      }
    }
  },
  "dunning": {
    "unsubscribes": {
      "title": "Payment reminder unsubscribes",
      "subtitle": "Customers who have opted out of your payment reminder emails",
      "emailLabel": "Customer email",
      "emailPlaceholder": "customer@example.com",
      "add": "Add",
      "addSuccess": "Added to the unsubscribe list",
      "addError": "Could not add to the unsubscribe list",
      "invalidEmail": "Enter a valid email address",
      "remove": "Remove",
      "removeSuccess": "Removed from the unsubscribe list",
      "removeError": "Could not remove this entry",
      "loading": "Loading unsubscribes...",
      "emptyTitle": "No unsubscribes yet",
      "emptyDescription": "Customers who unsubscribe from a reminder email appear here.",
      "sourceManual": "Added manually",
      "sourceLink": "Unsubscribed via email",
      "note": "A customer on this list will not receive any payment reminders from your business. This is separate from a hard bounce, which is handled automatically."
    },
    "title": "Payment Reminders",
    "subtitle": "Automatically send escalating reminders for overdue invoices",
    "enabled": "Enabled",
    "disabled": "Disabled",
    "stepsLabel": "Reminder Schedule",
    "stepsDescription": "Configure when reminders are sent after an invoice's due date",
    "daysAfterDue": "Days after due",
    "tone": "Tone",
    "toneGentle": "Gentle reminder",
    "toneFirm": "Firm reminder",
    "toneFinal": "Final notice",
    "addStep": "Add Step",
    "note": "Reminders are sent daily. If an invoice is paid before the next step, no further reminders are sent.",
    "saving": "Saving...",
    "save": "Save Reminder Settings",
    "saveSuccess": "Payment reminder settings saved",
    "saveError": "Failed to save reminder settings",
    "timeline": {
      "title": "Payment reminders ({count})",
      "stepLabel": "{tone} · day {days}",
      "statusSent": "Sent",
      "statusPending": "Sending…",
      "statusFailed": "Failed",
      "statusSkipped": "Skipped",
      "deliveryFailed": "Delivery failed - reminder not sent",
      "skipBalanceZero": "Skipped - invoice already paid",
      "skipNoEmail": "Skipped - no customer email on file",
      "skipOther": "Skipped",
      "sentTo": "to {email}",
      "toneGentle": "Gentle reminder",
      "toneFirm": "Firm reminder",
      "toneFinal": "Final notice"
    }
  },
  "genUI": {
    "figure": {
      "asOf": "as of {date}",
      "sourceUnavailable": "Source unavailable",
      "openSourceAria": "Open {source}",
      "viewSource": "View source"
    },
    "table": {
      "showingNofM": "Showing {shown} of {total}",
      "empty": "No rows to display",
      "total": "Total",
      "yes": "Yes",
      "no": "No",
      "sectionsLabel": "Lists in this result"
    },
    "chart": {
      "view": {
        "label": "Chart or table",
        "chart": "Chart",
        "table": "Table"
      },
      "series": {
        "netSales": "Net sales",
        "grossProfit": "Gross profit",
        "netProfit": "Net profit",
        "projectedBalance": "Projected balance",
        "income": "Income",
        "expenses": "Expenses",
        "balance": "Balance",
        "amount": "Amount"
      },
      "summary": {
        "lowest": "Lowest point",
        "end": "End of period",
        "expectedIn": "Expected in",
        "expectedOut": "Expected out"
      },
      "aria": {
        "summary": "{series} from {from} to {to}: highest {highPoint} at {highValue}, lowest {lowPoint} at {lowValue}.",
        "more": "Also shown: {others}.",
        "belowZero": "Below zero at {count} of {total} points.",
        "rank": "{count} ranked bars, largest first: {name}, {amount}. Remaining names are in the table.",
        "aging": "Aging columns from newest to oldest. {buckets}",
        "comparison": "Paired columns: {from}, {before}; {to}, {after}. Earlier period grey, later period blue.",
        "waterfall": "Profit bridge, with signed increases, decreases and totals: {steps}",
        "diverging": "Signed columns from zero. Positive values above, negative values below. Loss periods: {losses}.",
        "composition": "One bar represents 100%. Parts: {parts}"
      },
      "belowZero": {
        "days": "Below zero for {count, plural, one {# day} other {# days}}",
        "months": "Below zero for {count, plural, one {# month} other {# months}}",
        "points": "Below zero at {count, plural, one {# point} other {# points}}"
      },
      "period": "Period",
      "tableLabel": "Values behind the chart"
    },
    "choice": {
      "selectOne": "Choose an option",
      "answered": "You chose: {option}",
      "superseded": "This choice is no longer needed"
    },
    "status": {
      "overdue": "Overdue",
      "failed": "Failed",
      "rejected": "Rejected",
      "void": "Void",
      "high": "High",
      "critical": "Critical",
      "draft": "Draft",
      "pending": "Pending",
      "submitted": "Submitted",
      "accepted": "Accepted",
      "converted": "Converted",
      "declined": "Declined",
      "expired": "Expired",
      "due": "Due",
      "medium": "Medium",
      "paid": "Paid",
      "approved": "Approved",
      "posted": "Posted",
      "completed": "Completed",
      "active": "Active",
      "on_track": "On track",
      "low": "Low",
      "sent": "Sent",
      "open": "Open",
      "closed": "Closed",
      "cancelled": "Cancelled",
      "partially_paid": "Partly paid",
      "unpaid": "Unpaid",
      "inactive": "Inactive",
      "reimbursed": "Reimbursed",
      "in_stock": "In stock",
      "short": "Short",
      "cannot_check": "Cannot check",
      "not_deliverable": "Cannot deliver",
      "no_location": "No stock location",
      "blocked": "Blocked",
      "sku_ambiguous": "Several items",
      "not_tracked": "Not tracked",
      "not_found": "Not found",
      "not_authorized": "Not allowed",
      "entitlement_off": "Not switched on",
      "correction_audit_first": "Audit-first correction",
      "correction_adjustment": "Adjustment",
      "correction_official_reversal": "Official reversal",
      "correction_refused": "Correction unavailable",
      "origin_ui": "Screen",
      "origin_agent": "Groot agent",
      "origin_system": "System",
      "origin_import": "Import",
      "basis_eligible_open": "Open and eligible",
      "basis_period_locked": "Period locked",
      "basis_paid_or_settled": "Paid or settled",
      "basis_reconciled": "Bank reconciled",
      "basis_inventory_dependency": "Stock dependency",
      "basis_externally_finalized": "Final elsewhere",
      "basis_payroll_finalized": "Payroll final",
      "basis_active_correction_document": "Correction exists",
      "basis_source_owned": "Source record",
      "basis_stale_version": "Record had changed",
      "basis_unbalanced": "Unbalanced",
      "basis_invalid_account": "Invalid account",
      "basis_unsupported_dependency": "Linked record",
      "basis_source_attribute_not_allowed": "Field not allowed",
      "basis_unknown_finality": "Not confirmed",
      "basis_metadata_field_not_allowed": "Field not allowed"
    }
  },
  "soloPnl": {
    "header": {
      "subtitle": "Your income, expenses, and tax at a glance"
    },
    "hero": {
      "summary": "This period you earned {earned}, spent {spent}, and kept {kept}.",
      "earned": "Money in (income)",
      "spent": "Money out (expenses)",
      "kept": "Kept (profit)",
      "taxReviewRequiredTitle": "No tax figure yet",
      "taxReviewRequiredBody": "Your income and expense figures are ready. Groot shows a tax figure only after the official Malaysian rules for it have been reviewed.",
      "openTaxSettings": "Review tax settings"
    },
    "actions": {
      "addIncome": "Add income",
      "addIncomeHint": "Enter money you received",
      "uploadStatement": "Upload statement",
      "uploadStatementHint": "Bank, Grab, or platform file",
      "addExpense": "Add expense",
      "addExpenseHint": "Snap a receipt (petrol, repairs…)",
      "reading": "Reading…"
    },
    "manualIncome": {
      "title": "Record income",
      "description": "Add a commission, client payment, or other money you received. It goes straight into your books.",
      "amount": "Amount received",
      "amountPlaceholder": "0.00",
      "incomeFrom": "What was this income from?",
      "descriptionPlaceholder": "e.g. August insurance commission",
      "category": "Income category",
      "date": "Date received",
      "cancel": "Cancel",
      "save": "Record income",
      "saving": "Recording…",
      "loading": "Loading income accounts",
      "noAccounts": "No income account is ready for posting. Please contact Groot support.",
      "invalidAmount": "Enter an amount greater than zero.",
      "recorded": "Income recorded in your books.",
      "failed": "Could not record this income. Check the details and try again."
    },
    "tabs": {
      "income": "Income",
      "expenses": "Expenses"
    },
    "income": {
      "title": "Money in",
      "total": "Total in",
      "empty": "No income recorded for this period yet."
    },
    "expenses": {
      "title": "Money out",
      "total": "Total out",
      "empty": "No expenses recorded for this period yet.",
      "receiptsNote": "Add a receipt to record petrol, repairs and other costs."
    },
    "categories": {
      "grab_fare": "Fares",
      "grab_surge": "Surge earnings",
      "grab_incentive": "Incentives",
      "grab_tip": "Tips",
      "grab_commission": "Platform commission",
      "petrol": "Petrol",
      "maintenance": "Maintenance & repairs",
      "phone": "Phone & data",
      "road_tax_insurance": "Road tax & insurance",
      "tolls_parking": "Tolls & parking",
      "other": "Other"
    },
    "history": {
      "heading": "Recent uploads",
      "receiptsHeading": "Recent receipts",
      "receiptsEmpty": "No receipts recorded for this period yet.",
      "unknownVendor": "Unknown vendor",
      "viewDetails": "View details",
      "recorded": "Recorded",
      "empty": "No statements uploaded yet."
    },
    "banner": {
      "recorded": "Recorded. Showing {from} to {to}.",
      "dismiss": "Dismiss"
    },
    "reconcile": {
      "message": "This statement doesn't quite add up. It is off by {amount} (income minus commission should equal the payout). Double-check the PDF, or record it anyway.",
      "cancel": "Cancel",
      "recordAnyway": "Record anyway"
    },
    "receipt": {
      "comingSoon": "Receipt capture is coming soon."
    },
    "empty": {
      "title": "No income yet for this period",
      "description": "Record money you received, upload a statement, or add a receipt. Your books update from the same accounting ledger.",
      "upload": "Upload statement",
      "assistant": "or upload it in your assistant"
    },
    "states": {
      "selectBusiness": "Select a business to see your P&L.",
      "currencyRequired": "Set your business currency first",
      "currencyRequiredHint": "Your books need an explicit functional currency before a statement can be recorded.",
      "openSettings": "Open settings"
    },
    "errors": {
      "parse": "Could not read the statement. Please try again.",
      "upload": "Something went wrong uploading the statement. Please try again.",
      "ingest": "Could not record the statement. Please try again.",
      "currencyMismatch": "This statement uses {detected}, but your books use {currency}. Nothing was recorded.",
      "unknownCurrency": "an unknown currency"
    },
    "upgrade": {
      "title": "Growing your business?",
      "body": "When you need a balance sheet, fixed assets, or customer invoices, upgrade to the full business plan. Your Solo data comes with you.",
      "cta": "See plans"
    },
    "info": {
      "trigger": "How it works",
      "title": "How My P&L works",
      "description": "Your income, expenses, and tax from your platform statements, in plain language.",
      "stepsHeading": "3 simple steps",
      "step1Title": "Upload your statement",
      "step1Desc": "Add the weekly PDF from your driver or seller app. We read it automatically, so there is no typing.",
      "step2Title": "Add your receipts",
      "step2Desc": "Snap petrol, repair and other receipts so every cost is counted.",
      "step3Title": "See your profit",
      "step3Desc": "We total your income minus costs to show what you kept.",
      "tipsHeading": "Good to know",
      "tipReconcile": "We only record a statement once its numbers add up, so your profit is always trustworthy.",
      "tipHistory": "Every upload shows in the history under each tab, so nothing ever goes missing."
    },
    "unconfirmed": {
      "banner": "{count, plural, one {1 receipt is waiting for you to confirm} other {# receipts are waiting for you to confirm}}",
      "review": "Review",
      "more": "and {count, plural, one {# more} other {# more}}"
    }
  },
  "soloReceipt": {
    "title": "Add an expense",
    "description": "Snap a receipt (petrol, servicing, tolls). We read it and add it to your P&L automatically.",
    "useCamera": "Use camera",
    "hint": "JPG, PNG or PDF, up to 10MB.",
    "reading": "Reading your receipt…",
    "recording": "Recording the expense…",
    "review": {
      "title": "Check what we read",
      "description": "Confirm or correct these details before the expense is recorded.",
      "vendor": "Vendor",
      "amount": "Amount",
      "date": "Receipt date",
      "category": "Category",
      "chooseCategory": "Choose a category",
      "cancel": "Cancel",
      "confirm": "Record expense"
    },
    "recorded": "Expense recorded.",
    "needsAmount": "Saved your receipt, but we couldn't read an amount. Open it in Expenses to add one.",
    "errors": {
      "upload": "We couldn't upload that receipt. Please try again.",
      "ocr": "We couldn't read that receipt. Please try a clearer photo.",
      "submit": "We couldn't record that expense. Please try again.",
      "review": "Check the vendor, amount, date, and category before recording."
    },
    "alreadyHandled": "This receipt was already recorded."
  },
  "approvalPolicyForm": {
    "title": "Multi-level approval policies",
    "description": "Create named approval chains that route expense claims through up to three approvers, with optional conditions on amount, category, or department.",
    "restrictedTitle": "Restricted",
    "restricted": "Only the business owner or a finance admin can manage approval policies.",
    "managerStep": "The submitter's manager",
    "unknownApprover": "Unassigned approver",
    "levelLabel": "Level {level}",
    "badges": {
      "default": "Default",
      "active": "Active",
      "inactive": "Inactive"
    },
    "conditions": {
      "label": "Applies to",
      "allClaims": "All claims (catch-all)",
      "minAmountValue": "Over {amount}",
      "minAmountAtLeastValue": "{amount} and above",
      "categoryValue": "Category: {category}",
      "departmentValue": "Department: {department}"
    },
    "empty": {
      "title": "No approval policies yet",
      "description": "Claims currently follow the default manager chain. Create a policy to route approvals your way."
    },
    "actions": {
      "create": "Create policy",
      "edit": "Edit policy",
      "deactivate": "Deactivate",
      "save": "Save policy",
      "cancel": "Cancel",
      "addStep": "Add approval level",
      "removeStep": "Remove level"
    },
    "form": {
      "createTitle": "Create approval policy",
      "editTitle": "Edit approval policy",
      "subtitle": "Set the approval chain and the claims it applies to. Changes take effect on new submissions; claims already in flight are unaffected.",
      "nameLabel": "Policy name",
      "namePlaceholder": "e.g. Travel over 1,000",
      "descriptionLabel": "Description (optional)",
      "descriptionPlaceholder": "What this policy is for",
      "stepsLabel": "Approval chain",
      "stepsHint": "Add up to three levels, in order. Each level is either the submitter’s manager or a specific team member.",
      "stepsCount": "{count} of {max, plural, one {# level} other {# levels}}",
      "stepApproverLabel": "Level {level} approver",
      "stepPlaceholder": "Choose an approver",
      "isDefaultLabel": "Default policy (catch-all)",
      "isDefaultHint": "The default handles any claim that matches no other policy. It can have no conditions, and there is exactly one per business.",
      "conditionsLabel": "Conditions",
      "conditionsHint": "An override policy needs at least one condition. A claim uses the most specific policy it matches.",
      "minAmountLabel": "Minimum amount ({currency})",
      "minAmountPlaceholder": "e.g. 1000",
      "categoryLabel": "Category",
      "categoryPlaceholder": "Any category",
      "departmentLabel": "Department",
      "departmentPlaceholder": "Any department",
      "anyOption": "Any",
      "ruleTypeLabel": "What kind of rule is this?",
      "ruleTypeStandard": "Standard route",
      "ruleTypeStandardHint": "The approvers EVERY expense goes through when no special rule applies. You need exactly one of these.",
      "ruleTypeSpecial": "Special rule",
      "ruleTypeSpecialHint": "Extra approvers for only certain expenses, based on amount, category, or department.",
      "needStandardFirst": "Create your standard route first (the approvers every expense goes through). A special rule needs it as a fallback for anything it doesn’t cover.",
      "amountConditionLabel": "Apply when the amount is…",
      "amountComparatorLabel": "How to compare the amount",
      "comparatorAtLeast": "at least",
      "comparatorMoreThan": "more than",
      "amountHelpAtLeast": "A claim of {amount} or more uses this rule. Anything smaller uses your standard route.",
      "amountHelpMoreThan": "A claim of more than {amount} uses this rule (exactly {amount} does not). Smaller claims use your standard route.",
      "autoStandardRouteName": "Standard route",
      "willCreateStandardRoute": "You don’t have a standard route yet. We’ll create one automatically (every expense goes to the submitter’s manager) so this special rule has a fallback. You can edit it any time."
    },
    "errors": {
      "nameRequired": "Enter a policy name.",
      "stepRequired": "Add at least one approval level.",
      "tooManySteps": "A policy can have at most three approval levels.",
      "memberRequired": "Choose a team member for each specific-approver level.",
      "conditionRequired": "An override policy needs at least one condition (amount, category, or department).",
      "invalidAmount": "Enter a valid amount of zero or more.",
      "saveFailed": "Could not save the policy. Please try again.",
      "deactivateFailed": "Could not deactivate the policy. Please try again.",
      "ineligibleApprover": "One or more approvers can no longer approve. Choose an active owner, finance admin, or manager for each level.",
      "invalidCondition": "A condition points at a category, department, or amount that is no longer valid. Choose them again.",
      "defaultHasConditions": "The standard route covers every claim, so it cannot carry conditions. Remove them, or make this a special rule.",
      "duplicateName": "An active policy named \"{name}\" already exists. Two active policies with the same name compete for the same claims, so pick a different name, or edit the existing policy instead.",
      "approverNameUnresolved": "We could not match that approver to one active team member. Choose the person from the team list instead."
    },
    "toast": {
      "successTitle": "Success",
      "errorTitle": "Something went wrong",
      "created": "Approval policy created.",
      "updated": "Approval policy updated.",
      "deactivated": "Approval policy deactivated.",
      "createdWithStandard": "Special rule created. We also set up your standard route."
    },
    "deactivateDialog": {
      "title": "Deactivate policy?",
      "message": "Deactivate “{name}”? It stops routing new claims but is kept for your records and can be recreated later."
    },
    "howItWorks": {
      "title": "How approval policies work",
      "intro": "A policy routes an expense claim through a named chain of up to three approvers. When any policy is active, each claim follows the most specific one it matches.",
      "stepsHeading": "Setting one up",
      "step1": "Give the policy a clear name.",
      "step2": "Build the chain by picking the submitter’s manager or a specific team member for each level (up to three).",
      "step3": "Choose whether it is the default catch-all or an override with conditions.",
      "step4": "Save. New submissions use it immediately; claims already in flight are unaffected.",
      "defaultHeading": "The default policy",
      "defaultDesc": "Exactly one default per business. It has no conditions and catches every claim no override matches, so approvals can always be routed.",
      "overrideHeading": "Override policies",
      "overrideDesc": "An override needs at least one condition: a minimum amount, a category, or a department. A claim uses the most specific override it matches, otherwise the default.",
      "tipsHeading": "Good to know",
      "tip": "Amounts are in your business home currency. You can also set these up by asking Groot in chat."
    },
    "autoApproveSkip": {
      "exact": "Auto-approve skips {levels, plural, =1 {the only level} other {all # levels}} for claims at or below {amount}.",
      "some": "Auto-approve can skip {levels, plural, =1 {the only level} other {all # levels}} for small claims in some categories. Set the amounts under Spend control."
    }
  },
  "approvalPolicyEditor": {
    "title": "Approval Policies",
    "noPolicies": "No approval policies yet. Build one below.",
    "untitledPolicy": "Untitled policy",
    "defaultBadge": "Default",
    "active": "Active",
    "inactive": "Inactive",
    "editAction": "Edit",
    "noSteps": "No approval steps",
    "stepChainItem": "Level {level}: {approver}",
    "stepManager": "Manager",
    "stepPersonUnnamed": "A specific person",
    "conditionsLabel": "Applies when",
    "noConditions": "Any expense (default route)",
    "conditionAmount": "amount over {amount}",
    "conditionAmountAtLeast": "amount {amount} and above",
    "conditionCategory": "category is {category}",
    "conditionDepartment": "department is {department}",
    "buildTitle": "Build a new policy",
    "editTitle": "Edit this policy",
    "newPolicy": "New policy",
    "nameLabel": "Policy name",
    "namePlaceholder": "e.g. Travel over 5,000",
    "stepsLabel": "Approval steps (up to 3)",
    "stepNumber": "Level {level}",
    "stepTypeLabel": "Approver type for level {level}",
    "stepManagerOption": "Manager (auto)",
    "stepPersonOption": "A specific person",
    "personNameLabel": "Approver name for level {level}",
    "personNamePlaceholder": "Name of the approver",
    "addStep": "Add step",
    "removeStep": "Remove step",
    "conditionOptional": "Condition (optional)",
    "minAmountLabel": "Minimum amount",
    "minAmountPlaceholder": "Min amount",
    "categoryLabel": "Category",
    "categoryPlaceholder": "Category",
    "departmentLabel": "Department",
    "departmentPlaceholder": "Department",
    "defaultToggle": "Make this the default policy",
    "save": "Save policy",
    "sentForConfirmation": "Sent to Groot. Please confirm the change in chat.",
    "historicalHint": "This editor is from an earlier message and is read-only."
  },
  "compliance": {
    "taxId": {
      "tin": "Tax ID (TIN)",
      "sst": "SST Registration No.",
      "gst": "GST Registration No.",
      "guiTax": "Business Tax ID"
    },
    "identity": {
      "companyLegalName": "Company (Legal) Name",
      "companyLegalNameHint": "Registered name (SSM / ACRA) for invoices and e-invoice",
      "tradingName": "Trading Name",
      "tradingNameHint": "Brand / trading-as name shown in the app",
      "regNumberSoftHint": "This does not look like a valid {label}, so please double-check",
      "peppolParticipantId": "Peppol Participant ID"
    },
    "lhdnParty": {
      "stateRequired": "Select a Malaysian state. LHDN requires one on every e-Invoice.",
      "phoneRequired": "Enter a contact number of at least {min} characters. LHDN requires one on every e-Invoice.",
      "cityRequired": "Enter the city. A merchant e-invoice form will not accept a request without it.",
      "postcodeRequired": "Enter the postcode. A merchant e-invoice form will not accept a request without it.",
      "hint": "LHDN requires a Malaysian state and a contact number of at least {min} characters before an e-Invoice can be submitted.",
      "businessAddressHint": "Before an e-Invoice can be requested, we need your city, postcode, Malaysian state and a contact number of at least {min} characters.",
      "fixInBusinessSettings": "Add the missing detail in Settings, under Business Profile.",
      "fixOnCustomer": "Add the missing detail on this customer's record.",
      "fixOnVendor": "Add the missing detail on this vendor's record.",
      "submitBlockedTitle": "This e-Invoice needs one more detail",
      "openBusinessSettings": "Open Business Profile",
      "openCustomers": "Open Customers",
      "openVendors": "Open Vendors"
    },
    "lhdnErrors": {
      "configIncomplete": "Your LHDN details aren't complete yet. Add your tax identification number, business registration number and MSIC code under Settings → Business → e-Invoice, then submit again.",
      "issuerNotMy": "LHDN e-invoicing is only available to businesses registered in Malaysia. Check the country on your business profile.",
      "notSubmittable": "This invoice has already been sent to LHDN. Refresh the page to see its current status.",
      "windowExpired": "The 72-hour LHDN cancellation window has closed, so this e-invoice can no longer be cancelled. Issue a credit note instead.",
      "notCancellable": "LHDN has not validated this e-invoice yet, so there is nothing to cancel. Refresh the page to see its current status.",
      "reasonRequired": "Enter a reason for the cancellation before you continue.",
      "submitFailed": "We couldn't send this invoice to LHDN. Nothing was submitted. Please try again in a moment.",
      "cancelFailed": "We couldn't cancel this e-invoice. Nothing was changed. Please try again in a moment.",
      "noteNotIssued": "Issue this note before filing it with LHDN.",
      "noteVoid": "This note has been voided, so it cannot be filed with LHDN.",
      "noteTypeUnknown": "This note is not marked as a credit or debit note, so it cannot be filed with LHDN. Contact support.",
      "noteOriginalMissing": "The invoice this note adjusts could not be found, so the note cannot be filed with LHDN.",
      "noteOriginalNotValidated": "File the original invoice with LHDN and wait until it is validated. A credit or debit note can only reference a validated invoice.",
      "noteFilesAsNote": "This is a credit or debit note. File it from the note itself, which files it as a note against its original invoice.",
      "submissionUnconfirmed": "LHDN may already have this invoice, but it did not confirm it. The invoice stays Pending and cannot be submitted again. Groot is checking with LHDN and will update the status by itself, which can take up to an hour. If it is still Pending after a day, contact support.",
      "resultNotRecorded": "LHDN has answered, but we could not save the result. Do not submit this invoice again. Groot will check with LHDN and record the result by itself, which can take up to an hour. If it is still Pending after a day, contact support.",
      "exchangeRateMissing": "This invoice is in a foreign currency and has no exchange rate to Malaysian ringgit, which LHDN requires. Check the rate under Accounting → Chart of Accounts / Exchange rates, add that rate to the invoice, then submit again.",
      "cancelStateNotAllowed": "LHDN no longer allows this e-invoice to be cancelled. It may already be cancelled, rejected or marked invalid. Refresh the page to see its current status.",
      "cancelHasReferencingDocuments": "A credit or debit note refers to this e-invoice, so LHDN will not cancel it. Cancel that note first, then cancel this e-invoice.",
      "cancelNotPermitted": "LHDN did not allow Groot to cancel this e-invoice for your business. Nothing was changed.",
      "cancelRefused": "LHDN did not accept the cancellation. Nothing was changed.",
      "cancelUnconfirmed": "We could not confirm with LHDN whether this e-invoice was cancelled. Its status here has not changed. Check it again in a few minutes before trying again.",
      "cancelNotRecorded": "LHDN has cancelled this e-invoice, but we could not save that here. Do not cancel it again. Contact support so the status can be updated.",
      "reasonTooLong": "Keep the cancellation reason to 300 characters or fewer.",
      "taxTypeUnclassified": "LHDN requires every taxed line to say whether its tax is sales tax or service tax, and this invoice does not record that. It has not been sent to LHDN. Contact support.",
      "taxTypeInvalid": "A tax setting on this invoice cannot be sent to LHDN as it stands: a tax type that does not match the tax charged, or an exemption without a valid reason. It has not been sent to LHDN. Contact support."
    }
  },
  "autoCountImport": {
    "title": "Import from AutoCount",
    "subtitle": "Bring your AutoCount chart of accounts, customers, suppliers, stock items, tax codes and payment terms into Groot. Your existing codes are kept exactly as AutoCount stores them. Groot does not import your past invoices or payments.",
    "scopePackage": "the package",
    "aliasResult": "Supplier item aliases: {created} added, {updated} refreshed, {skippedConfirmed} human-confirmed matches preserved.",
    "aliasPrivacy": "Supplier item aliases suggest matches between invoice lines and your catalog. A person must still confirm the match before stock posting. Only supplier codes and item codes/names are imported from the alias extract; bills, dates, quantities, prices, tax and account entries stay in AutoCount.",
    "packageUpload": {
      "title": "Support tools",
      "body": "Replay a prepared import file. Groot support uses this to reproduce an import without moving a backup again; you do not need it.",
      "choose": "Choose file",
      "noFile": "No file chosen",
      "assurance": "Groot imports existing AutoCount codes for matching and will not create new records in AutoCount."
    },
    "families": {
      "legend": "What to import",
      "help": "Everything listed here is imported by default. Clear a box to leave that group out. Groot refuses an import whose rows point at codes it was not given, so leaving a group out is the only way past that.",
      "chart-of-accounts": "Chart of accounts",
      "debtors": "Customers",
      "creditors": "Suppliers",
      "stock-items": "Stock items",
      "item-groups": "Item groups",
      "units-of-measure": "Units of measure",
      "vendor-item-aliases": "Supplier item aliases",
      "tax-codes": "Tax codes",
      "currencies": "Currencies",
      "payment-terms": "Payment terms",
      "projects": "Projects",
      "purchase-history": "Purchase history",
      "unsupportedLegend": "Not included in this export",
      "reason": {
        "noTransactions": "(this export carries no transactions)",
        "noTransactionsButFileHasThem": "(your file has {count, plural, one {# transaction} other {# transactions}}, which Groot does not import from this export)",
        "unproven": "(not yet proven against real data)",
        "unprovenWithRows": "(your file has {count, plural, one {# project} other {# projects}}, which Groot is not importing yet)",
        "noDestination": "(Groot has nowhere to use these yet)"
      }
    },
    "actions": {
      "preview": "Preview import",
      "apply": "Import"
    },
    "applied": "Imported {accounts} accounts, {customers} customers and {suppliers} suppliers.",
    "appliedNotice": "The import finished. Everything below is what landed.",
    "truncated": "This business has more accounts than we read in one pass, so the replacement list above may be incomplete.",
    "writeBudget": "This import writes {count} rows. One import can carry up to {budget}.",
    "table": {
      "family": "Group",
      "received": "In file",
      "creating": "New",
      "updating": "Updated",
      "preserved": "Kept as is",
      "noted": "Not imported",
      "excluded": "left out",
      "noDestination": "no place in Groot yet"
    },
    "faults": {
      "title": "This import was refused",
      "help": "Nothing has changed. Fix the package in AutoCount and export it again, or clear the box for the group involved.",
      "detail": "{count} affected, in {scope}. For example: {samples}"
    },
    "faultCodes": {
      "PACKAGE_FORMAT_UNKNOWN": "This file is not an AutoCount package",
      "PACKAGE_VERSION_UNSUPPORTED": "This package was made by a newer extractor",
      "PROVIDER_ID_MISSING": "The package does not say which system it came from",
      "PROVIDER_ID_UNKNOWN": "The package names a system Groot cannot read",
      "COLLECTION_MALFORMED": "Part of the package is not in the expected shape",
      "MISSING_CODE": "A row has no code",
      "MISSING_NAME": "A row has a code but no name",
      "DUPLICATE_CODE": "The same code appears twice",
      "CROSS_FAMILY_CODE_COLLISION": "One code is used as both a customer and a supplier",
      "DANGLING_REFERENCE": "A row points at a code the package does not contain",
      "AMBIGUOUS_HISTORY_KEY": "The same supplier and description point at two different items",
      "SUB_ACCOUNT_SHAPED_CODE": "A code that would turn a Groot account into a heading",
      "FAMILY_TOO_LARGE": "Too many rows in one group",
      "ATOMIC_WRITE_BUDGET_EXCEEDED": "Too many rows for a single import",
      "COLLECTION_ABSENT": "The package leaves out a table instead of saying it is empty",
      "EXCLUSION_NOT_DEPENDENCY_CLOSED": "Something you kept depends on something you left out",
      "EXCLUDED_FAMILY_UNKNOWN": "A group you asked to leave out is not a group we know",
      "HIERARCHY_CYCLE": "Accounts point at each other in a loop",
      "AMBIGUOUS_PARTY_LABEL": "Two different codes share one name",
      "TENANT_CASE_VARIANT_EXISTS": "Groot already has this code with different capitalisation",
      "SNAPSHOT_TRUNCATED": "This business has more rows than the preview can read safely",
      "AMBIGUOUS_LABEL_HAS_LIVE_MAPPING": "Two codes share a name that Groot already maps to one of them",
      "PARTY_NAME_ONLY_CONFLICT": "A customer or supplier with this name already exists, with no AutoCount code"
    },
    "notes": {
      "title": "Rows that were not imported",
      "detail": "{count} in {scope}",
      "detailWithSamples": "{count} in {scope}. For example: {samples}"
    },
    "noteCodes": {
      "HISTORY_LINE_HAS_NO_ITEM_CODE": "Purchase lines posted straight to an account, with no stock item",
      "HISTORY_LINE_HAS_NO_DESCRIPTION": "Purchase lines with no description to match on",
      "HISTORY_LINES_COLLAPSED": "Repeated purchase lines merged into one",
      "ACCOUNT_IS_PARTY_SUBLEDGER": "Accounts that are really a customer or supplier, imported as those instead",
      "FAMILY_EXCLUDED_BY_CALLER": "Left out at your request",
      "FAMILY_HAS_NO_DESTINATION": "Groot has no place for these yet",
      "AMBIGUOUS_PARTY_LABEL_MAPPING_WITHHELD": "Two codes share one name, so both were created but neither was mapped for export",
      "UNCLASSIFIED_ACCOUNT_TYPE_SKIPPED": "Accounts whose AutoCount account type Groot does not recognise. Everything else imported. Tell us what these types mean and we will add them"
    },
    "superseded": {
      "title": "Sample accounts this chart does not restate",
      "body": "Groot created these when the business was set up and your AutoCount chart does not include them. Ones that are not in use are archived after the import. Any still in use stay, and the result says how many."
    },
    "errors": {
      "tooLarge": "That package is too large to import in one go, and trying again will not change that. Upload the AutoCount backup (.A06) above instead, or contact support.",
      "unreadable": "We could not read that file. Try choosing it again.",
      "previewFailed": "We could not check that package. Try again, and contact support if it keeps happening.",
      "aliasIdentityMaintenance": "Your existing AutoCount item records need a one-time update before aliases can be imported. Contact Groot support, then preview this package again after the update.",
      "aliasIdentityConflict": "An AutoCount item code points to conflicting catalog records. Ask Groot support to resolve the duplicate or mismatched item links, then preview this package again.",
      "applyFailed": "The import did not run and nothing changed. Try again, and contact support if it keeps happening.",
      "planStale": "Nothing was imported because what you approved has changed. Preview it again and check the numbers.",
      "acxPicked": "That is an .acx file. AutoCount encrypts it, so only another AutoCount installation can read it. In AutoCount, go to Tools > Backup and upload the .A06 file it saves.",
      "xmlPicked": "That is an AutoCount XML export. Depending on how it was saved, it can arrive with most of your chart of accounts and all of your stock items missing, and nothing in the file says which kind it is. In AutoCount, go to Tools > Backup and upload the .A06 file it saves.",
      "backupEmpty": "That file is empty. If AutoCount is still writing the backup, wait for it to finish and choose the file again.",
      "backupTooLarge": "That backup is larger than Groot can import. Contact support and we will import it for you.",
      "uploadStartFailed": "We could not start the upload. Check your connection and try again.",
      "uploadPartFailed": "The upload stopped part way. Nothing already uploaded is lost, so choose the same file again to carry on.",
      "uploadCompleteFailed": "We could not finish the upload. Choose the same file again to carry on from where it stopped.",
      "uploadFileChanged": "That is a different file from the one this upload started with. Choose the original backup to carry on, or start a new upload.",
      "uploadAborted": "Upload cancelled.",
      "uploadIncomplete": "The upload did not finish, so there is nothing to import yet. Choose the same file again to carry on.",
      "uploadCorrupt": "The backup did not arrive intact. Please upload it again.",
      "containerUnknown": "Groot does not yet support the compression setting this backup was saved with. Nothing is wrong with your file. Contact support and we will add it.",
      "decoderFailed": "We could not open this backup. If AutoCount is still writing it, wait for it to finish and upload it again.",
      "manifestMismatch": "This backup file appears to be damaged. Please make a fresh backup in AutoCount and upload that one.",
      "manifestMissing": "This does not look like an AutoCount backup. In AutoCount, go to Tools > Backup and upload the .A06 file it saves.",
      "notASqlBackup": "This file is not an AutoCount backup. In AutoCount, go to Tools > Backup and upload the .A06 file it saves.",
      "dbVersionTooNew": "This backup was made by a newer version of AutoCount than Groot can read yet. Nothing is wrong with your file: we need to update Groot. Contact support and we will let you know when it is ready.",
      "restoreFailed": "We could not read this backup. Please make a fresh backup in AutoCount and upload that one.",
      "backupSetIncomplete": "This backup is incomplete, most likely because AutoCount had not finished writing it. Please make a fresh backup and upload that one.",
      "restoreOutOfDisk": "This backup is too large for us to open right now. Contact support and we will import it for you.",
      "schemaUnrecognised": "Your AutoCount stores something in a way Groot does not recognise yet. Nothing is wrong with your data. Contact support and we will add it.",
      "extractionFailed": "We could not read your data out of this backup. Contact support and we will look into it.",
      "taskKilled": "The import stopped before it finished, on our side. Nothing was changed. Please try again.",
      "callbackLost": "We lost track of your import. It may have finished. Contact support and we will check before you try again.",
      "planOverCeiling": "This import is larger than Groot can bring in at once. Contact support and we will import it for you.",
      "chunkBudgetExceeded": "The import stopped part way through. Continue it to bring in the rest.",
      "planDigestMismatch": "This import no longer matches the one already in progress. Continue the original import, or undo it and start again.",
      "finalizationIntegrityFailed": "Groot received inconsistent import results and stopped safely. Contact support before starting again.",
      "applyInterrupted": "The import stopped part way. Continue it to bring in the rest, or undo it to put the business back as it was.",
      "applyRejected": "Some rows could not be imported. Continue the import and we will show you which ones.",
      "unauthorized": "You do not have permission to import into this business.",
      "unclassified": "Something went wrong with the import and nothing was changed. Contact support and we will look into it."
    },
    "backupUpload": {
      "title": "Upload your AutoCount backup",
      "body": "Groot reads your chart of accounts, customers, suppliers, stock items, tax codes and payment terms from an AutoCount backup file. This is the only AutoCount export that contains all of it.",
      "clickPath": "In AutoCount, go to Tools > Backup and save the backup file. It ends in .A06.",
      "link": "How to back up in AutoCount",
      "notAcx": "Not an .acx file. That one is for moving data between two AutoCount installations, and AutoCount encrypts it so nothing else can read it.",
      "notXml": "Not an XML export. What one of those carries depends on the settings it was saved with, and the file does not say which were used, so an import could look finished with most of your chart of accounts and all of your stock items missing. A backup always carries everything.",
      "assurance": "Groot reads this once and never writes back to AutoCount.",
      "dataTransitConsent": "I understand this whole backup is securely uploaded so Groot can extract master data. The raw backup is deleted after processing; historical transactions and AutoCount users are not imported.",
      "choose": "Choose backup file",
      "cancel": "Cancel upload",
      "noFile": "No file chosen",
      "uploadProgressLabel": "AutoCount backup upload progress",
      "progress": "{pct}% uploaded, part {done} of {total}",
      "handedOff": "Upload finished. Groot is reading your backup now; you can close this page and come back to it.",
      "background": {
        "title": "Import running in the background",
        "body": "You can leave this page. Groot will keep working and show the result here when it finishes."
      },
      "history": {
        "title": "Recent imports",
        "empty": "No earlier imports yet.",
        "started": "Started {time}",
        "rows": "{applied} of {total} rows",
        "status": {
          "partially_applied": "Stopped part way: needs attention",
          "succeeded": "Completed",
          "needs_review": "Completed: review needed",
          "failed": "Failed",
          "aborted": "Cancelled"
        }
      },
      "resumeTitle": "You have an unfinished upload of {name}.",
      "resumeBody": "Choose the same file again to carry on from where it stopped. Nothing already uploaded needs to be sent again. If you choose a different file, Groot will ask you to start over rather than mix the two.",
      "resumeAction": "Continue upload",
      "startOverAction": "Discard and start over",
      "jobSucceeded": "Your AutoCount data is imported.",
      "jobPartialTitle": "Partly imported: {applied} of {total} rows.",
      "jobPartialStoppedAt": "It stopped at {code}.",
      "jobPartialHelp": "Nothing is lost. Continue the import to bring in the rest, or undo it to put the business back as it was. Continuing twice is safe.",
      "jobRetryable": "You can try this again.",
      "jobNotRetryable": "Trying again will not help. Contact support and we will take it from here.",
      "report": {
        "title": "View import report",
        "finishedWithReview": "Import finished, with source data to review",
        "unavailable": "The import finished, but its detailed report is unavailable. Contact support before relying on it as a complete first import.",
        "applied": "Applied to Groot",
        "retained": "Read from backup, not applied",
        "excluded": "Not imported, by design",
        "redacted": "Values kept private",
        "redactedValues": "{count, plural, one {# local or sensitive value was not imported} other {# local or sensitive values were not imported}}",
        "unmapped": "Not mapped yet",
        "none": "None",
        "appliedCounts": "{appliedRows} applicable · {created} new · {updated} updated · {preserved} unchanged",
        "itemUomCounts": "{sourceRows} item/UOM assignments read · {created} UOM code(s) added",
        "retainedCounts": "{count} source row(s) retained",
        "rows": "{count, plural, one {# row} other {# rows}}",
        "rawDeleted": "Raw backup deleted after extraction.",
        "rawDeletionUnconfirmed": "Raw backup deletion has not been confirmed. Groot support has been notified.",
        "families": {
          "itemTypes": "Item types",
          "locations": "Locations",
          "paymentMethods": "Payment methods",
          "salesAgents": "Sales agents",
          "purchaseAgents": "Purchase agents",
          "fiscalYears": "Fiscal years",
          "priceTiers": "Price tiers"
        },
        "reasons": {
          "historicalTransactions": "historical transactions stay authoritative in AutoCount",
          "derivedStockState": "derived stock state becomes stale and is not master identity",
          "securityAdministration": "security-sensitive AutoCount administration data",
          "operationalLogs": "AutoCount operational history is not needed in Groot",
          "localConfiguration": "AutoCount-local configuration has no Groot business meaning",
          "binaryAssets": "binary assets need a separate product and privacy decision",
          "unrelatedOperations": "not relevant to Groot accounting integration",
          "other": "no supported Groot destination"
        }
      },
      "stages": {
        "uploading": "Uploading your backup…",
        "uploaded": "Upload received.",
        "inspecting": "Checking the backup file…",
        "decoding": "Opening the backup…",
        "preflight": "Checking which AutoCount version made this backup…",
        "restoring": "Restoring your backup so Groot can read it…",
        "extracting": "Reading your accounts, customers, suppliers and items…",
        "planning": "Working out what will change…",
        "applying": "Importing into Groot…",
        "verifying_receipts": "Checking that every imported row arrived…",
        "reconciling_accounts": "Finishing your account hierarchy…",
        "applied": "Import finished."
      }
    }
  },
  "onboardingChartSource": {
    "heading": "Where should your chart of accounts come from?",
    "subheading": "Pick one. Groot will not create a chart you did not ask for.",
    "suggested": {
      "title": "Use Groot's suggested chart",
      "body": "A ready-made chart of {count} accounts, matched to your country. You can edit it any time.",
      "bodyNoCount": "Matched to your country, and editable any time."
    },
    "import": {
      "title": "Import the chart I already use",
      "body": "Bring your existing account codes across from {providers}, a spreadsheet, or a pasted list.",
      "next": "We will take you to the import screen right after your business is created. Nothing is created until you have seen exactly what will change.",
      "provider": {
        "title": "Import from {provider}",
        "body": "Bring your chart of accounts across from {provider}."
      },
      "file": {
        "title": "Upload a spreadsheet",
        "body": "A CSV or Excel export of your chart of accounts."
      },
      "paste": {
        "title": "Paste a list",
        "body": "Paste account codes and names straight from anywhere."
      },
      "bodyNoProviders": "Bring your existing account codes across.",
      "unavailable": "Chart import is available on the Groot web app."
    },
    "preview": {
      "heading": "The {count} accounts Groot would create",
      "more": "and {count} more"
    },
    "actions": {
      "back": "Back",
      "next": "Continue"
    }
  },
  "chartSetup": {
    "title": "Set up your chart of accounts",
    "description": "Choose a source, check the preview, then apply. Nothing is written until you apply.",
    "entryCta": "Set up or replace chart",
    "upload": "Upload CSV or Excel",
    "pastePlaceholder": "Or paste your account codes and names here",
    "parsed": "{count} accounts read from your file",
    "unclassifiedTypes": "{count} accounts use an account type Groot does not recognise, so they are not included. Tell us what these types mean and we will add them.",
    "applied": "Chart updated: {created} added, {updated} updated, {adopted} now yours, {archived} archived",
    "starterApplied": "Added {created} accounts from Groot's suggested chart",
    "sources": {
      "starter": {
        "title": "Groot's suggested chart",
        "body": "Start from a ready-made chart of accounts."
      },
      "provider": {
        "body": "Read the chart of accounts export from {provider}."
      },
      "generic": {
        "title": "Spreadsheet or pasted list",
        "body": "Any CSV, Excel file or pasted grid of codes and names."
      },
      "groupLabel": "Where your chart of accounts comes from"
    },
    "preview": {
      "heading": "What will happen",
      "create": "Added",
      "update": "Updated",
      "archive": "Archived",
      "conflict": "Needs fixing",
      "preservedHeading": "Kept as they are",
      "conflictHeading": "These rows need fixing before you can import",
      "adopt": "Now yours",
      "createHeading": "Accounts to add",
      "updateHeading": "Accounts to update",
      "reactivateHeading": "Accounts to bring back",
      "archiveHeading": "Accounts to archive",
      "adoptHeading": "Accounts becoming yours"
    },
    "replace": {
      "label": "Also archive {count} unused starter accounts this import replaces",
      "hint": "Only accounts still exactly as Groot created them, with no transactions and no role in automated posting. Nothing is deleted."
    },
    "reasons": {
      "not_starter": "you or your team added this",
      "edited": "you edited this",
      "referenced": "in use by your books",
      "catalog_item_gl": "used by a product or service",
      "category_mapping": "mapped to an active category"
    },
    "conflicts": {
      "BLANK_CODE": "This row has no account code.",
      "BLANK_NAME": "This account has no name.",
      "DUPLICATE_CODE": "This code appears more than once in your file (also as {collidesWith}).",
      "CASE_COLLISION": "You already have {collidesWith}, which differs only in capitalisation.",
      "SUB_ACCOUNT_CODE": "This is a sub-account. Import the parent on its own, then add this one from the Chart of Accounts screen.",
      "INVALID_TYPE": "Groot does not recognise the account type \"{suppliedType}\".",
      "TYPE_CODE_MISMATCH": "This code belongs to {derivedType}, but the file says {suppliedType}.",
      "UNRESOLVED_TYPE": "This row has no account type, and Groot cannot work it out from the code.",
      "CURATED_ACCOUNT_NOT_WRITABLE": "You already have {accountCode} as \"{existingName}\". Groot will not overwrite an account you set up. Rename or remove this row in your file.",
      "EDITED_ACCOUNT_NOT_WRITABLE": "You edited {accountCode} (\"{existingName}\"), so Groot will not overwrite it. Rename or remove this row in your file.",
      "REFERENCED_ACCOUNT_NOT_WRITABLE": "{accountCode} (\"{existingName}\") is {referenceReason}, so Groot will not change it."
    },
    "errors": {
      "noRows": "No accounts were found in that file.",
      "parseFailed": "That file could not be read. Try a CSV or Excel export of your chart of accounts.",
      "previewFailed": "The preview could not be prepared. Please try again.",
      "applyFailed": "The chart could not be imported. Nothing was changed.",
      "starterFailed": "The suggested chart could not be added. Please try again.",
      "previewStale": "Your chart changed since you previewed. Please preview again."
    },
    "actions": {
      "cancel": "Cancel",
      "preview": "Preview changes",
      "apply": "Apply",
      "useStarter": "Use Groot's chart"
    },
    "downloadTemplate": "Download template",
    "diagnose": {
      "noRows": "We could not read any accounts from that file. Check that it has a row per account, with a code and a name.",
      "noTypeColumn": "That file has no Type column, or it is empty on every row. Every account needs a type (Asset, Liability, Equity, Income or Expense) because a code like 90A-S200 cannot tell us on its own. Download the template, copy your accounts in, and fill the Type column.",
      "someRowsMissingType": "{missing} of {rowCount} rows have no type. Those rows will be skipped. Fill in the Type column for them (Asset, Liability, Equity, Income or Expense).",
      "reservedCodeShape": "Codes like {codes} use a format reserved for Groot’s own accounts and will be refused. Use your own numbering instead, for example 5100 rather than 5100-0001.",
      "duplicateCodes": "The same code appears more than once ({codes}). This usually means the wrong column was read as the account code. Check the file against the template."
    },
    "fixWithTemplate": "Download the template"
  },
  "payroll": {
    "posting": {
      "title": "Post to the ledger",
      "description": "Record {period} payroll in your accounts so it shows up in your profit and loss.",
      "postCta": "Post to ledger",
      "postTitle": "Post {period} payroll",
      "postDialogDesc": "Check the entry below, then post it. You can reverse it later if something is wrong.",
      "salariesPaidLabel": "Salaries already paid",
      "salariesPaidHint": "Net pay leaves your bank on the date below.",
      "salariesAccruedHint": "Net pay is recorded as owed to your staff until you pay it.",
      "paymentDate": "Payment date",
      "bankDescriptionPost": "The bank or cash account the salaries left. Used for the ledger and bank reconciliation.",
      "bankDescriptionSettle": "The bank or cash account the salaries left. Used for the ledger and bank reconciliation.",
      "previewHeading": "What will be recorded",
      "previewLineGross": "Gross wages",
      "previewLineEmployerScheme": "Employer {scheme}",
      "previewLineNetPaid": "Net salaries paid",
      "previewLineNetAccrued": "Net salaries payable",
      "previewLineStatutory": "{scheme} payable",
      "previewLineTax": "PCB / MTD payable",
      "previewExpense": "Employee benefits expense",
      "previewNetPay": "Net to staff",
      "previewStatutory": "Held for statutory bodies",
      "cancel": "Cancel",
      "confirmPost": "Post to ledger",
      "postedToast": "Payroll posted as {entryNumber}.",
      "postFailed": "We could not post this payroll. Nothing was recorded, so please try again.",
      "postedTitle": "Posted as {entryNumber}",
      "postedDesc": "{amount} recorded on {date}.",
      "awaitingPayment": "{amount} is recorded as owed to your staff. Record the payment once it leaves your bank.",
      "settledOn": "Salaries paid on {date}, recorded as {entryNumber}.",
      "recordPayment": "Record salary payment",
      "reverse": "Reverse",
      "viewEntry": "View the journal entry",
      "colAccount": "Account",
      "colDebit": "Debit",
      "colCredit": "Credit",
      "openLedger": "Open in the ledger",
      "settleTitle": "Record the salary payment",
      "settleDesc": "This clears the {amount} you owe your staff and takes it out of your bank.",
      "confirmSettle": "Record payment",
      "settledToast": "Salary payment recorded as {entryNumber}.",
      "settleFailed": "We could not record this payment. Nothing was changed, so please try again.",
      "reverseTitle": "Reverse this payroll entry",
      "reverseDesc": "Nothing is deleted. We add an opposite entry and keep both, so your audit trail stays complete.",
      "reverseReasonPlaceholder": "Why are you reversing this?",
      "confirmReverse": "Reverse entry",
      "reversedToast": "Payroll entry reversed.",
      "reverseFailed": "We could not reverse this entry. Nothing was changed, so please try again.",
      "payThisLabel": "Transfer this to your staff",
      "payThisCaption": "{gross} gross, less {statutory} EPF, SOCSO, EIS and PCB that you hold and remit later.",
      "amountTransferredLabel": "Amount you transferred",
      "amountTransferredHint": "We calculated {net}. Change it if a different amount left your bank.",
      "grossRefusal": "That is the gross amount. {actual} was transferred but only {net} was due to your employees. {statutory} of it is EPF, SOCSO, EIS and PCB you still owe. Your employees have been overpaid by {overpaid} and the statutory remittance is now unfunded.",
      "varianceRefusal": "{actual} was transferred but {net} was due. Tell us why before we record it.",
      "payFromNotChosenRefusal": "Choose which account this money was paid from before we record it. No default bank account is set up, so there is nothing to fall back to. Pick an account above, or set a default on Accounting → Chart of Accounts.",
      "payFromUnusableRefusal": "The account you chose can no longer take this payment. It may have been archived or given sub-accounts since this page loaded. Reload the page and pick an account again.",
      "varianceQuestion": "Why is this different from {net}?",
      "varianceReasonPlaceholder": "Choose a reason",
      "varianceShortfall": "{amount} stays recorded as owed to your staff.",
      "varianceOverpaid": "{amount} is recorded as recoverable from your staff.",
      "varianceReason": {
        "extra_payment": "A bonus or allowance went out in the same transfer",
        "advance_recovered": "A staff advance or loan was deducted",
        "partial_payment": "Only part of the salaries went out",
        "other": "Something else"
      },
      "previewLineNetStillPayable": "Net salaries still payable",
      "previewLineNetOverpaid": "Salary overpayment recoverable",
      "statutoryOutstanding": "{amount} of EPF, SOCSO, EIS and PCB is still held for the boards. Remit it by the 15th of next month.",
      "recordRemittance": "Record statutory remittance",
      "remitTitle": "Record the statutory remittance",
      "remitDesc": "This clears the {amount} you hold for EPF, SOCSO, EIS and PCB and takes it out of your bank.",
      "confirmRemit": "Record remittance",
      "remittedToast": "Statutory remittance recorded as {entryNumber}.",
      "remittedOn": "EPF, SOCSO, EIS and PCB remitted on {date}, recorded as {entryNumber}.",
      "remitFailed": "We could not record this remittance. Nothing was changed, so please try again.",
      "bankDescriptionRemit": "The bank or cash account the remittance left. Used for the ledger and bank reconciliation.",
      "blocked": {
        "not_ready": "Clear the items above first. Payroll has to be right before it reaches your accounts.",
        "nothing_to_post": "There is nothing to post for this period yet.",
        "uncomputed_employees": "At least one employee could not be calculated. Posting now would leave their salary out of your accounts, so fix their setup first.",
        "already_posted": "This period is already in your accounts.",
        "expense_account_missing": "Choose the expense account you keep employee-benefit costs in, under Accounting → Chart of Accounts → Posting accounts. Payroll needs somewhere to go.",
        "liability_account_missing": "Choose the liability account you keep statutory withholdings in, under Accounting → Chart of Accounts → Posting accounts. That is where EPF, SOCSO, EIS and PCB sit until you remit them.",
        "statutory_expense_account_missing": "Payroll records the employer's own statutory contributions on a separate line per scheme, and one of those accounts is missing from your chart of accounts. Add the statutory contribution accounts for your country on Accounting → Chart of Accounts.",
        "no_bank_account": "Add a bank or cash account on Accounting → Chart of Accounts before posting payroll."
      },
      "hrdfAccountRefusal": "Choose an active expense account for HRDF employer expense under Accounting > Chart of Accounts > Payment & posting, then try again.",
      "hrdfAccountWillBeCreated": "The HRDF employer expense account will be created when you post this run.",
      "previewTotal": "Total",
      "previewTotalsDiffer": "Debits and credits differ by {amount}. Do not post until this is resolved."
    },
    "citations": {
      "viewOfficialSource": "View official source",
      "unpaid_leave_deduction": {
        "explanation": "Unpaid leave is deducted using the statutory formula for an incomplete month: monthly wages divided by the days in the wage period, times the days you were eligible to be paid."
      },
      "ordinary_rate_of_pay": {
        "explanation": "The ordinary rate of pay divides monthly wages by 26. It applies to overtime and rest-day or holiday work, not to unpaid leave."
      },
      "epf": {
        "explanation": "EPF is taken from the Third Schedule wage bands, not a flat percentage, and the rate depends on age and citizenship. Totals are rounded up to the next ringgit."
      },
      "epf_voluntary_excess": {
        "explanation": "An employer may elect to contribute above the statutory rate. Contributions are deductible for the employer up to 19% of the employee's remuneration."
      },
      "socso": {
        "explanation": "SOCSO is taken from wage bands with a RM6,000 monthly ceiling. Since 1 June 2026 both categories are paid by the employer and the employee, and both cover non-employment injury. First Category covers invalidity, employment injury and non-employment injury. Second Category, for employees aged 60 and above, covers employment injury and non-employment injury."
      },
      "skbbk": {
        "explanation": "SKBBK, also called LINDUNG 24 Jam, is the Non-Employment Injury Security Scheme. PERKESO makes it voluntary for local employees and mandatory for foreign workers from 8 July 2026, and the contribution is borne entirely by the employee, so Groot charges it only where you have recorded that the employee joined or is a foreign worker. The rate rises in three stages under the Third Schedule that Act A1788 substituted, in force since 1 June 2026: at the RM6,000 wage ceiling it is RM44.65 a month until 31 May 2028, then RM59.50 until 31 May 2031, then RM74.40."
      },
      "eis": {
        "explanation": "EIS is taken from wage bands with a RM6,000 monthly ceiling. The employer and employee contribute the same amount."
      },
      "pcb": {
        "explanation": "Monthly tax deduction (PCB) is entered manually and is not calculated here. Use LHDN's official PCB calculator or your tax agent's figure."
      },
      "sg_cpf": {
        "explanation": "CPF applies a percentage to the actual total wages, not to a wage band's upper limit, and the rate depends on age and on whether the employee is a Singapore Citizen or Permanent Resident. The total is rounded to the nearest dollar, the employee share is rounded down, and the employer pays the remainder."
      },
      "sg_cpf_ow_ceiling": {
        "explanation": "Ordinary Wages are the wages for the month that are payable by the 14th of the following month. CPF is charged on them only up to the Ordinary Wage ceiling of $8,000 a month; any Ordinary Wages above that are disregarded."
      },
      "sg_cpf_aw_ceiling": {
        "explanation": "Additional Wages are wages that are not Ordinary Wages, such as an annual bonus. The amount of them that attracts CPF in a calendar year is $102,000 less the Ordinary Wages already subject to CPF that year, counted per employer."
      },
      "sg_sdl": {
        "explanation": "The Skills Development Levy is 0.25% of the monthly wages up to $4,500, with a minimum of $2 and a maximum of $11.25 per employee. It is payable for all employees working in Singapore, including foreign employees, it is borne entirely by the employer, and it is never deducted from wages. The total for all employees is rounded down to the nearest dollar."
      },
      "sg_shg_cdac": {
        "explanation": "CDAC contributions are a flat amount per monthly wage band, deducted from the wages of employees of the Chinese community who are Singapore Citizens or Permanent Residents. An employee may opt out, or contribute more than the band amount."
      },
      "sg_shg_ecf": {
        "explanation": "ECF contributions are a flat amount per monthly wage band, deducted from the wages of employees of the Eurasian community who are Singapore Citizens or Permanent Residents. An employee may opt out, or contribute more than the band amount."
      },
      "sg_shg_mbmf": {
        "explanation": "MBMF contributions are a flat amount per monthly wage band, deducted from the wages of Muslim employees who are Singapore Citizens, Permanent Residents or foreign employees. An employee who does not wish to contribute applies to Muis for a certificate and notifies the employer."
      },
      "sg_shg_sinda": {
        "explanation": "SINDA contributions are a flat amount per monthly wage band, deducted from the wages of employees of Indian descent who are Singapore Citizens, Permanent Residents or Employment Pass holders. An employee may opt out, or contribute more than the band amount."
      },
      "sg_incomplete_month": {
        "explanation": "For an incomplete month, the Employment Act divides your monthly gross rate of pay by the days you are required to work that month, then multiplies by the days you actually worked. Working days come from your contract, so a 31 day month is usually 21, 23.5 or 26 days."
      },
      "sg_foreign_worker_levy": {
        "explanation": "The foreign worker levy is a cost the employer pays to the Ministry of Manpower for each Work Permit or S Pass holder. It is not a payroll deduction and is not calculated here: deducting it from an employee's salary is an offence carrying a financial penalty."
      },
      "hrdf": {
        "explanation": "Basic wage basis: the owner-selected 1% or 0.5% of basic salary less unpaid leave, rounded to sen. HRD Corp also includes fixed allowances, which Groot does not model yet. Bonus, commission, overtime, travel and variable pay are excluded. Only explicitly eligible Malaysian citizens in full-time employment are charged; foreign workers and domestic servants are excluded. Employer-only, never a salary deduction."
      },
      "hrdf_coverage": {
        "explanation": "Covered employers register compulsorily with 10 or more Malaysian employees at 1%, or optionally with 5 to 9 at 0.5%. Coverage and rate are owner decisions, not inferred from headcount or industry."
      }
    },
    "readiness": {
      "readyTitle": "Ready to run payroll",
      "readyDesc": "All employees have the data needed to compute pay for this period.",
      "notReadyTitle": "Not ready to run payroll",
      "notReadyDesc": "{count, plural, one {# employee needs attention before payroll can be computed.} other {# employees need attention before payroll can be computed.}}",
      "notReadyBusinessDesc": "Something needs attention before payroll can be computed.",
      "warningsTitle": "Review before running payroll",
      "warningsDesc": "Nothing is blocking, but these are worth a look first.",
      "runPayroll": "Go to posting",
      "codes": {
        "no_salary_configured": "No salary configured",
        "net_pay_missing": "Net pay is blank or zero",
        "net_pay_negative": "Deductions exceed pay (negative net pay)",
        "no_bank_account": "No bank account on file",
        "missing_statutory_id": "Missing EPF, SOCSO or tax identification",
        "employee_terminated": "Former employee, excluded from this pay run",
        "holiday_calendar_unseeded": "No public holiday calendar configured for this period",
        "variance_exceeds_threshold": "Pay changed sharply from last period",
        "no_pay_no_hours": "In the roster with nothing to pay",
        "duplicate_bank_account": "Bank account shared with another employee",
        "missing_statutory_classification": "Statutory classification incomplete (contribution rate cannot be selected)"
      },
      "noRosterTitle": "No employees to pay for this period",
      "noRosterDesc": "Once employees and their leave records are in place for this period, their payroll readiness appears here."
    },
    "tab": {
      "title": "Payroll",
      "description": "Compute statutory deductions and net pay from this period's leave and attendance records.",
      "loading": "Loading payroll",
      "noAccessTitle": "Payroll is not available for your role",
      "noAccessDesc": "Payroll shows salary information, so it is limited to the business owner and finance admins.",
      "setupRequiredTitle": "Payroll setup not complete",
      "setupRequiredDesc": "Employee salary and statutory details are not configured yet, so pay cannot be computed. Once they are set up, this is where the calculation appears.",
      "descriptionWithPeriod": "Statutory deductions and net pay for {period}, calculated under {jurisdiction}.",
      "refresh": "Refresh",
      "retry": "Try again",
      "loadErrorTitle": "Payroll could not be calculated",
      "loadErrorDesc": "Something went wrong while calculating this period. Nothing has been changed. Try again, and contact support if it keeps happening.",
      "unsupportedTitle": "Payroll is not available for this business yet",
      "unsupportedCountryDesc": "Payroll applies each country's own statutory rates and incomplete-month formula, so it only runs for the countries it has been built for. Your business country is not one of them yet.",
      "unsupportedCountryMissingDesc": "Set your business country in Business Settings first. Payroll applies statutory rules by country, so it will not guess one for you.",
      "currencyNotSet": "No home currency is set for this business, so the currency shown on these figures may not be the one you pay in. Set it in Business Settings before relying on them.",
      "subtabSetup": "Employee setup",
      "subtabCalculate": "Calculation",
      "profileSaved": "Payroll details saved",
      "profileSaveFailed": "Could not save payroll details. Nothing was changed.",
      "profileRemoved": "Payroll details removed",
      "profileRemoveFailed": "Could not remove payroll details. Nothing was changed.",
      "viewPayslips": "Payslips",
      "viewTable": "Table",
      "divisorNote": "Incomplete months are calculated over {days} days, the days in {period}.",
      "workingDayDivisorNote": "Incomplete months are calculated over {days} working days from the employment contract, not the days in {period}.",
      "periodSelectorLabel": "Pay period month",
      "periodYearSelectorLabel": "Pay period year",
      "periodCoversNote": "This pay period covers {start} to {end} ({days} days).",
      "cycleTitle": "Pay cycle",
      "cycleDesc": "The day each pay period starts. Most businesses pay by calendar month. If your cut-off is mid-month, set it here and payroll and timesheets will both use it.",
      "cycleStartDayLabel": "Pay period starts on",
      "cycleCalendarMonthOption": "The 1st (calendar month)",
      "cycleDayOption": "Day {day} of the previous month",
      "cycleSave": "Save pay cycle",
      "cycleSaved": "Pay cycle updated",
      "cycleSaveFailed": "Could not update the pay cycle. Please try again.",
      "cycleTimesheetNote": "This also sets the period used for monthly timesheets, so the two always cover the same days.",
      "month_1": "January",
      "month_2": "February",
      "month_3": "March",
      "month_4": "April",
      "month_5": "May",
      "month_6": "June",
      "month_7": "July",
      "month_8": "August",
      "month_9": "September",
      "month_10": "October",
      "month_11": "November",
      "month_12": "December",
      "hrdfSaved": "HRDF settings saved"
    },
    "calc": {
      "emptyTitle": "No employees to pay for this period",
      "emptyDesc": "Once employees are on the roster for this period, their pay calculation appears here.",
      "divisorHint": "Wages for an incomplete month are calculated over {days} days, the number of days in {period}, as required by section 18A of the Employment Act 1955.",
      "workingDayDivisorHint": "Wages for an incomplete month are the monthly gross rate of pay divided by {days} working days in {period}, times the days actually worked, as required by section 20A of the Employment Act 1968. Working days come from the employment contract, so they are fewer than the days in the month.",
      "cpfWageBasisNote": "CPF is calculated on total wages: Ordinary Wages for the month up to the {ceiling} Ordinary Wage ceiling, plus any Additional Wages such as a bonus.",
      "unreliableBanner": "No public holiday calendar was found for this period, so unpaid days may be overstated and pay understated. Public holidays are paid days. Set up the holiday calendar before paying.",
      "excludedBanner": "{count, plural, one {# employee could not be calculated and is excluded from the totals. Their row shows the reason.} other {# employees could not be calculated and are excluded from the totals. Their rows show the reason.}}",
      "groupEmployeeDeductions": "Deducted from the employee",
      "groupEmployerContributions": "Paid by the employer",
      "colEmployee": "Employee",
      "colMonthlyWage": "Monthly wage",
      "colUnpaidAbatement": "Unpaid leave",
      "colGrossPay": "Gross pay",
      "colEpf": "EPF",
      "colSocso": "SOCSO",
      "colEis": "EIS",
      "colTax": "PCB (tax)",
      "colNetPay": "Net pay",
      "colEmployerEpf": "EPF (employer)",
      "colEmployerTotal": "Employer total",
      "colCpf": "CPF",
      "colEmployerCpf": "CPF (employer)",
      "colEmployerSdl": "SDL (employer)",
      "colShg": "Community fund",
      "aboutAbatement": "About the unpaid leave calculation",
      "aboutEpf": "About EPF",
      "aboutSocso": "About SOCSO",
      "aboutEis": "About EIS",
      "aboutTax": "About monthly tax deduction",
      "aboutCpf": "About CPF",
      "aboutSdl": "About the Skills Development Levy",
      "aboutShg": "About community fund contributions",
      "unpaidDaysChip": "{days, plural, one {# unpaid day} other {# unpaid days}}",
      "totalsOfEmployees": "{total, plural, one {{shown} of # employee} other {{shown} of # employees}}",
      "totalsIncomplete": "These totals cover only the employees that could be calculated, and exclude any figure shown as unavailable.",
      "totalCostLabel": "Total cost to the business:",
      "colTaxWithheld": "Tax withheld",
      "reasons": {
        "no_profile": "No payroll details set up",
        "calculation_failed": "Cannot be calculated. Check this employee's payroll details."
      },
      "notApplicable": "Not applicable",
      "colLindung": "LINDUNG 24 Jam",
      "aboutLindung": "About LINDUNG 24 Jam",
      "colWageExcludingOvertime": "Wage",
      "colOvertime": "Overtime",
      "noOvertimeInPeriod": "No overtime this period",
      "colHrdf": "HRDF (basic wage basis)",
      "aboutHrdf": "About employer HRDF"
    },
    "setup": {
      "hint": "Enter each employee's wage and statutory details, then save the row.",
      "configuredCount": "{total, plural, one {{configured} of # employee set up} other {{configured} of # employees set up}}",
      "emptyTitle": "No employees to set up",
      "emptyDesc": "Once people are active members of this business, they appear here for payroll setup.",
      "colEmployee": "Employee",
      "colMonthlyWage": "Monthly wage ({currency})",
      "colEpfPart": "EPF category",
      "colSocso": "SOCSO category",
      "colEis": "EIS",
      "colHireDate": "Hire date",
      "colTax": "PCB ({currency})",
      "save": "Save",
      "saved": "Saved",
      "wagePlaceholder": "3000.00",
      "wageEcho": "= {currency} {amount}",
      "taxPlaceholder": "0.00",
      "hireDateHint": "Used to pro-rate a mid-month joiner",
      "missingStatutoryId": "Add an EPF number before running payroll",
      "missingBankAccount": "No bank account on file",
      "aboutEpfPart": "About EPF categories",
      "aboutSocso": "About SOCSO categories",
      "aboutEis": "About EIS",
      "aboutTax": "About monthly tax deduction",
      "wageAriaLabel": "Monthly wage for {name}",
      "epfPartAriaLabel": "EPF category for {name}",
      "socsoAriaLabel": "SOCSO category for {name}",
      "eisAriaLabel": "EIS applies to {name}",
      "hireDateAriaLabel": "Hire date for {name}",
      "taxAriaLabel": "Monthly tax deduction for {name}",
      "removeAriaLabel": "Remove payroll details for {name}",
      "epfParts": {
        "part_a": "Under 60, Malaysian or PR",
        "part_b": "Retired category B",
        "part_c": "Aged 60 and above",
        "part_d": "Retired category D",
        "part_e": "Malaysian aged 60+, employer only",
        "part_f": "Non-Malaysian, flat 2%",
        "custom": "Custom rate"
      },
      "socsoCategories": {
        "category_1": "First Category (under 60)",
        "category_2": "Second Category (60 and above)",
        "none": "Not applicable"
      },
      "errors": {
        "not_a_number": "Enter an amount using digits only, for example 3000.00",
        "negative": "An amount cannot be negative",
        "too_many_decimals": "Use at most two decimal places",
        "implausibly_large": "That amount looks too large. Check for a typo.",
        "retired_epf_part": "This EPF category no longer applies. Choose a current one.",
        "termination_before_hire": "The last day cannot fall before the hire date",
        "save_failed": "Could not save. Your changes are still here.",
        "remove_failed": "Could not remove these details.",
        "invalid_bank_account": "A bank account number must be 5 to 20 digits",
        "invalid_epf_rate": "Enter a rate between 0 and 100, for example 19",
        "epf_rate_required": "Enter a rate for both the employer and the employee",
        "epf_employer_below_statutory": "The employer rate cannot fall below the statutory {percent}%. Paying less is an offence under the EPF Act 1991.",
        "epf_employee_below_statutory": "The employee rate cannot fall below the statutory {percent}%.",
        "wage_required": "Enter a monthly wage. This row cannot be saved without one.",
        "invalid_working_days": "Working days a week must be between 0.5 and 7, in half day steps",
        "shg_reveal_failed": "Could not show the community fund. Try again."
      },
      "colBank": "Bank",
      "colBankAccount": "Account number",
      "bankOther": "Other",
      "bankNamePlaceholder": "Maybank",
      "bankAccountPlaceholder": "Account number",
      "bankAccountReplacePlaceholder": "New account number",
      "bankOnFile": "On file: ****{last4}. Type a new number to replace it.",
      "bankRecordHint": "Recorded for your payroll and accounting records. Groot does not send payments.",
      "bankNameAriaLabel": "Bank name for {name}",
      "bankAccountAriaLabel": "Bank account number for {name}",
      "missingCount": "{count, plural, one {# employee still needs setting up} other {# employees still need setting up}}",
      "statusConfigured": "Set up",
      "statusMissing": "Not set up",
      "wageNotSet": "No wage yet",
      "wageOnFile": "{currency} {amount}",
      "eisApplies": "EIS applies",
      "remove": "Remove",
      "colTerminationDate": "Last day",
      "terminationDateHint": "Only if they have left. Leave blank while they are employed.",
      "terminationDateAriaLabel": "Last day for {name}",
      "epfCustom": {
        "employerLabel": "Employer rate (%)",
        "employeeLabel": "Employee rate (%)",
        "employerPlaceholder": "19",
        "employeePlaceholder": "11",
        "employerAriaLabel": "Employer EPF rate for {name}",
        "employeeAriaLabel": "Employee EPF rate for {name}",
        "employerEffect": "RM {amount} a month, RM {difference} above the required RM {statutory}.",
        "employeeEffect": "RM {amount} a month, RM {difference} above the required RM {statutory}.",
        "employerEffectSame": "RM {amount} a month, exactly the required rate.",
        "employeeEffectSame": "RM {amount} a month, exactly the required rate."
      },
      "colEpfNumber": "EPF number",
      "epfNumberPlaceholder": "Member number",
      "epfNumberAriaLabel": "EPF member number for {name}",
      "colSocsoNumber": "SOCSO number",
      "socsoNumberPlaceholder": "Member number",
      "socsoNumberAriaLabel": "SOCSO number for {name}",
      "missingSocsoNumber": "Add a SOCSO number before running payroll",
      "missingStatutoryIdBoth": "Add an EPF number and a SOCSO number before running payroll",
      "colSgResidency": "Residency status",
      "colSgWorkPassType": "Work pass",
      "colSgSprStartDate": "PR status started",
      "colSgSprRateElection": "CPF rate election",
      "colSgDateOfBirth": "Date of birth",
      "colSgShgFund": "Community fund",
      "colSgShgOverride": "Fund override ({currency})",
      "colSgWorkingDays": "Working days a week",
      "aboutSgResidency": "About CPF residency",
      "aboutSgWorkPassType": "About the work pass",
      "aboutSgSprStartDate": "About the PR start date",
      "aboutSgSprRateElection": "About CPF rate elections",
      "aboutSgDateOfBirth": "About CPF age bands",
      "aboutSgShgOverride": "About fund overrides",
      "aboutSgWorkingDays": "About incomplete months",
      "sgResidencyOptions": {
        "sc": "Citizen",
        "spr": "Permanent resident",
        "foreign_pass": "Work pass holder"
      },
      "sgWorkPassTypeOptions": {
        "employment_pass": "Employment Pass",
        "s_pass": "S Pass",
        "work_permit": "Work Permit",
        "other_work_pass": "Another work pass"
      },
      "sgSprRateElectionOptions": {
        "graduated": "Graduated rates",
        "full_employer": "Full employer rate",
        "full_both": "Full rates both sides"
      },
      "sgShgFunds": {
        "cdac": "CDAC",
        "ecf": "ECF",
        "mbmf": "MBMF",
        "sinda": "SINDA",
        "none": "None"
      },
      "sgResidencyPlaceholder": "Choose a status",
      "sgResidencyAriaLabel": "CPF residency status for {name}",
      "sgWorkPassTypePlaceholder": "Choose a pass",
      "sgWorkPassTypeAriaLabel": "Work pass for {name}",
      "sgWorkPassTypeHint": "SINDA covers Employment Pass holders, so the pass decides whether that fund applies. CPF is not payable on any work pass.",
      "sgSprStartDateAriaLabel": "Date permanent residence started for {name}",
      "sgSprStartDateHint": "The CPF rate changes after each anniversary, so the date decides which rates apply.",
      "sgSprRateElectionPlaceholder": "Graduated rates",
      "sgSprRateElectionAriaLabel": "CPF rate election for {name}",
      "sgDateOfBirthAriaLabel": "Date of birth for {name}",
      "sgDateOfBirthHint": "Sets the CPF age band. Not needed for a work pass holder.",
      "sgShgFundPlaceholder": "Choose a fund",
      "sgShgFundAriaLabel": "Community fund for {name}",
      "sgShgOnFile": "On file",
      "sgShgReveal": "Show",
      "sgShgRevealAriaLabel": "Show the community fund for {name}",
      "sgShgRevealNote": "Shown one person at a time, and every viewing is recorded.",
      "sgShgAuditNote": "Sensitive. Set it once and leave it hidden.",
      "sgShgScopeHint": "MBMF applies to any work pass holder and SINDA to Employment Pass holders. CDAC and ECF apply to citizens and permanent residents only.",
      "sgShgOverridePlaceholder": "0.00",
      "sgShgOverrideAriaLabel": "Community fund override for {name}",
      "sgShgOverrideHint": "Blank uses the standard table. Enter 0 to record a certified exemption.",
      "sgWorkingDaysPlaceholder": "5",
      "sgWorkingDaysAriaLabel": "Contracted working days a week for {name}",
      "sgWorkingDaysHint": "From the contract. Half days are allowed, for example 5.5.",
      "profileMissing": {
        "my_epf_schedule_part_missing": "Choose an EPF category before running payroll",
        "my_socso_category_missing": "Choose a SOCSO category before running payroll",
        "my_eis_applicable_missing": "Answer whether EIS applies before running payroll",
        "my_lindung_missing": "Answer LINDUNG 24 Jam before running payroll",
        "sg_residency_status_missing": "Set a residency status before running payroll",
        "sg_spr_start_date_missing": "Add the date permanent residence started before running payroll",
        "sg_work_pass_type_missing": "Choose which work pass this employee holds before running payroll",
        "sg_date_of_birth_missing": "Add a date of birth before running payroll",
        "sg_shg_fund_missing": "Set a community fund before running payroll",
        "sg_working_days_missing": "Add contracted working days a week before running payroll",
        "my_hrdf_eligibility_missing": "HRDF eligibility not set"
      },
      "colTaxWithheld": "Tax withheld ({currency})",
      "colLindung": "LINDUNG 24 Jam",
      "aboutLindung": "About LINDUNG 24 Jam",
      "lindungAriaLabel": "LINDUNG 24 Jam for {name}",
      "lindungEnrolmentHint": "PERKESO enrols local employees unless they opt out, so set this to match what the employee chose.",
      "lindungPlaceholder": "Not answered yet",
      "lindungOptions": {
        "local_not_contributing": "Not contributing (local employee)",
        "local_contributing": "Contributing (local employee)",
        "foreign_worker": "Mandatory (foreign worker)"
      },
      "colHrdfEligibility": "HRDF eligibility",
      "aboutHrdfEligibility": "About HRDF eligibility",
      "hrdfEligibilityAria": "HRDF eligibility for {name}",
      "hrdfEligibilityPlaceholder": "Choose HRDF eligibility",
      "hrdfEligibilityOptions": {
        "eligible": "Eligible Malaysian employee",
        "excluded": "Excluded from HRDF"
      },
      "hrdfEligibilityHint": "Eligible: Malaysian citizen in full-time employment, permanent or contract. Foreign workers and domestic servants are excluded. Required only when HRDF is enabled.",
      "teamUnassigned": "Unassigned",
      "teamFallback": "Team"
    },
    "payslip": {
      "monthlyWage": "Monthly wage",
      "unpaidLeaveDays": "Unpaid leave ({days}d)",
      "grossPay": "Gross pay",
      "deductionsHeading": "Deducted from pay",
      "epf": "EPF",
      "socso": "SOCSO",
      "eis": "EIS",
      "pcb": "PCB (tax)",
      "pcbNotEntered": "No monthly tax deduction entered",
      "taxWithheld": "Tax withheld",
      "cpf": "CPF",
      "sdl": "SDL",
      "shgCdac": "CDAC",
      "shgEcf": "ECF",
      "shgMbmf": "MBMF",
      "shgSinda": "SINDA",
      "netPay": "Net pay",
      "employerContributes": "Employer also pays",
      "employerNotDeducted": "Paid by the business on top of wages, not deducted from the employee.",
      "aboutAbatement": "About the unpaid leave calculation",
      "aboutEpf": "About EPF",
      "aboutSocso": "About SOCSO",
      "aboutEis": "About EIS",
      "aboutTax": "About monthly tax deduction",
      "aboutCpf": "About CPF",
      "aboutSdl": "About the Skills Development Levy",
      "aboutShg": "About community fund contributions",
      "reasonNoProfile": "No payroll details set up for this employee",
      "reasonCannotCompute": "Pay cannot be calculated for this employee",
      "reasonFixHint": "Open Employee setup to fix this, then refresh.",
      "dayCountUnreliableChip": "Check days",
      "dayCountUnreliableTitle": "No public holiday calendar for this period, so unpaid days may be overstated.",
      "lindung24": "LINDUNG 24 Jam",
      "aboutLindung": "About LINDUNG 24 Jam",
      "wageExcludingOvertime": "Wage",
      "overtime": "Overtime",
      "pcbIncludesOvertime": "Overtime is taxable income, so the monthly tax deduction you enter must include it. Groot does not calculate PCB.",
      "hrdf": "HRDF levy (paid by your employer)",
      "aboutHrdf": "About employer HRDF",
      "employerTotal": "Employer total ({items})",
      "teamUnassigned": "Unassigned",
      "teamFallback": "Team"
    },
    "summary": {
      "totalCostLabel": "Total payroll cost for {period}",
      "totalCostHint": "Gross wages plus the employer's own statutory contributions.",
      "netToStaffLabel": "Net to staff",
      "statutoryLabel": "Statutory remittance",
      "employeesLabel": "Employees",
      "employeesOfTotal": "{computed} of {total}",
      "excludedBanner": "{count, plural, one {# employee could not be calculated and is excluded from these totals. Their card shows the reason.} other {# employees could not be calculated and are excluded from these totals. Their cards show the reason.}}",
      "unreliableBanner": "No public holiday calendar was found for this period, so unpaid days may be overstated and pay understated. Public holidays are paid days. Set up the holiday calendar before paying.",
      "unpaidDaysNote": "{days, plural, one {# unpaid day deducted across the team this period.} other {# unpaid days deducted across the team this period.}}",
      "overtimeHeading": "Overtime",
      "overtimePricedNote": "{amount} paid to {count, plural, one {# employee} other {# employees}}, {hours} hours.",
      "overtimeUnfinalizedNote": "{count, plural, one {# timesheet is} other {# timesheets are}} not finalized for this period, so {hours} hours of overtime are not paid on this run.",
      "overtimeRefusedNote": "Overtime could not be priced for {count, plural, one {# employee} other {# employees}}. Their rows show the reason.",
      "overtimeUnsupportedNote": "Overtime hours were recorded, but Groot does not calculate overtime pay for this country yet.",
      "overtimeNonePricedNote": "Overtime pay is on, but no finalized timesheet in this period recorded any overtime."
    },
    "disclaimer": {
      "body": "These amounts are a convenience calculation, and Groot is not {authorities}. Check every figure with them before you pay or file; the filing stays your responsibility.",
      "authoritiesMy": "PERKESO, KWSP or LHDN",
      "authoritiesSg": "the CPF Board, IRAS or MOM"
    },
    "hrdf": {
      "title": "HRDF levy",
      "applies": "HRDF levy applies",
      "coverage": "For covered employers, registration is compulsory at 10 or more Malaysian employees (1%) and optional at 5 to 9 (0.5%). The owner decides coverage and rate; Groot does not infer either.",
      "aboutCoverage": "About HRDF coverage",
      "rate": "HRDF levy rate",
      "chooseRate": "Choose a rate",
      "mandatory": "1% compulsory category",
      "optional": "0.5% optional registered category",
      "basis": "Basic wage basis only: basic salary less unpaid leave. Fixed allowances are not modelled yet. Overtime, bonus, commission, travel and variable pay are excluded. The employer bears the levy; take-home pay is unchanged.",
      "ownerOnly": "Only the business owner can change HRDF coverage and rate.",
      "loading": "Loading HRDF settings. If this persists, refresh payroll.",
      "save": "Save HRDF settings",
      "saveFailed": "HRDF settings could not be saved. Please try again.",
      "loadFailed": "HRDF settings could not be loaded. Please refresh payroll.",
      "rateWhenOff": "HRDF is off, so no levy is charged. Rate when on: {rate}"
    },
    "payslips": {
      "heading": "Payslips",
      "subheading": "Taken when this pay run was posted. Later changes to profiles or leave do not alter them.",
      "mineSubheading": "Your payslips, newest first. Only you and your payroll administrators can see them.",
      "emptyPeriodTitle": "No payslips for this period",
      "emptyPeriodHint": "Payslips are created when the pay run is posted to the ledger.",
      "emptyMineTitle": "No payslips yet",
      "emptyMineHint": "Your payslips appear here once your employer posts a pay run.",
      "loadFailed": "We could not load payslips right now. Please refresh and try again.",
      "netPay": "Net pay",
      "downloadPdf": "PDF",
      "downloadFor": "Download the payslip of {name} for {period}",
      "withdrawn": "Withdrawn",
      "pdf": {
        "title": "Payslip",
        "employee": "Employee",
        "team": "Team",
        "period": "Pay period",
        "earnings": "Earnings",
        "withdrawn": "This payslip was withdrawn because the pay run was reversed.",
        "generated": "Generated {date}",
        "failed": "We could not create the payslip PDF. Please try again.",
        "withdrawnStamp": "WITHDRAWN"
      }
    }
  },
  "businessExpenseDocument": {
    "besideVoucherHint": "Check the voucher against the original. Printing prints the voucher sheet only, so file this bill with it.",
    "besideVoucherTitle": "The bill this voucher pays",
    "title": "Bill for this expense",
    "shelfPrimaryLabel": "Bill",
    "rowAriaLabel": "Open the bill for {vendor}",
    "subtitle": "The document {vendor} was recorded from.",
    "close": "Close",
    "enlarge": "Enlarge",
    "openInNewTab": "Open in a new tab",
    "download": "Download document",
    "imageAlt": "Bill from {vendor}",
    "pdfFrameTitle": "Bill from {vendor}",
    "absentTitle": "No stored document",
    "absentDescription": "This expense was entered by hand, or recorded before we began keeping the bill. Drop the bill on the upload area to record the next one with its document.",
    "errorTitle": "We couldn't show the document",
    "errorGeneric": "Please try again in a moment. Nothing about the expense has changed.",
    "errorSignedOut": "Your session expired. Sign in again to view this document.",
    "errorNotAvailable": "This document is no longer available.",
    "fieldsTitle": "Recorded from this document",
    "fieldsHint": "Check these against the bill. Anything wrong was corrected when it was saved.",
    "fieldVendor": "Paid to",
    "fieldDescription": "Description",
    "fieldDate": "Expense date",
    "fieldAmount": "Amount",
    "fieldAccount": "Expense account",
    "fieldStatus": "Status",
    "reviewTitle": "What OCR read",
    "reviewHint": "Read off this document before you saved it. Your corrections train the model.",
    "reviewNoneTitle": "No stored reading for this expense",
    "reviewNoneHint": "It was entered by hand, or recorded before we started keeping the reading.",
    "reviewAcceptedAll": "Every field was accepted exactly as read.",
    "reviewCorrectedCount": "{count, plural, one {You corrected # field.} other {You corrected # fields.}}",
    "reviewAccepted": "accepted",
    "reviewChanged": "you changed this",
    "reviewNotRead": "not read",
    "reviewSavedAs": "Saved as",
    "reviewConfidence": "Extractor confidence {percent}%",
    "reviewNeedsReview": "The extractor flagged this reading for checking.",
    "field": {
      "vendorName": "Paid to",
      "description": "Description",
      "expenseDate": "Expense date",
      "amount": "Amount"
    },
    "status": {
      "accrued": "Unpaid",
      "paidDirect": "Paid {date} from {account}",
      "settled": "Paid {date} from {account}",
      "prepaid": "Prepaid {date} from {account}"
    },
    "downloadErrorTitle": "We couldn't download the document",
    "downloadErrorNoDocument": "There is no stored document for this expense to download.",
    "lineItemsTitle": "What was on the bill ({count})",
    "lineItemQtyAtPrice": "{qty} at {price}",
    "lineItemQty": "Qty {qty}",
    "reReadHelp": "This bill was read before we captured itemised lines. Reading it again adds them. Your amount, account and journal entry are not changed.",
    "reReadAction": "Read this bill again",
    "reReadBusy": "Reading...",
    "reReadFailedTitle": "Could not read the bill again",
    "reReadFailedDescription": "Nothing was changed. Please try again in a moment."
  },
  "businessExpenses": {
    "detail": {
      "title": "Business expense",
      "subtitle": "Bill and payment voucher for {vendor}.",
      "tabBill": "Bill",
      "tabVoucher": "Payment voucher",
      "tabCreditNotes": "Credit notes",
      "loadingCreditNote": "Loading credit note",
      "creditNoteUnavailable": "This attached credit note is no longer available.",
      "copyLink": "Copy link",
      "linkCopied": "Link copied",
      "copyFailed": "Couldn't copy the link",
      "edit": "Edit",
      "editHint": "Reverses the postings and returns the bill so you can correct it",
      "salesAgent": "Sales agent",
      "oneOffPayee": "One-off - this payee was not added to your supplier list.",
      "autoRaised": "Raised automatically by a recurring bill schedule."
    },
    "page": {
      "title": "Other Expenses",
      "subtitle": "Bills you pay directly: utilities, rental, subscriptions, repairs."
    },
    "creditNote": {
      "action": "Credit note",
      "title": "Capture a credit note",
      "subtitle": "A credit from {vendor} against the {amount} bill. It reduces what you owe them.",
      "amount": "Credit amount ({currency})",
      "date": "Credit note date",
      "reason": "Why they issued it",
      "reasonPlaceholder": "Overbilled units, goods returned, goodwill…",
      "tooLarge": "That is more than the bill. The most you can credit is {amount}.",
      "willPost": "You will owe {vendor} {net} instead. When you pay, the credit comes off automatically.",
      "save": "Capture credit note",
      "successTitle": "Credit note recorded",
      "successDescription": "The {amount} credit from {vendor} was recorded and reduces what you owe.",
      "badge": "Credit note",
      "view": "Open credit note",
      "attachedTitle": "Credit notes ({count})",
      "appliedToBill": "Applied to this bill",
      "billAmount": "Bill amount",
      "appliedAmount": "Credit applied",
      "openLinked": "Open linked credit note: {date}"
    },
    "tier": {
      "memory": "Coded like last time",
      "rule": "Matched by rule",
      "fallback": "Uncategorised (check this)",
      "user": "You chose this"
    },
    "unpaid": {
      "title": "Accrued, not yet paid",
      "subtitle": "{count} expense(s) recognised and not yet paid."
    },
    "list": {
      "record": "Record expense",
      "recordPayment": "Record payment",
      "delete": "Delete expense",
      "cancelAndReverse": "Cancel & reverse",
      "cancelConfirmTitle": "Cancel this expense?",
      "cancelConfirmMessage": "Use this only to cancel the entire {vendor} expense. This creates a linked reversal; to amend an open expense, use Correct posting instead.",
      "cancelConfirmButton": "Cancel & reverse",
      "tabs": {
        "all": "All",
        "unpaid": "Unpaid",
        "paid": "Paid"
      },
      "columns": {
        "date": "Date",
        "vendor": "Payee",
        "account": "Account",
        "amount": "Amount",
        "status": "Status",
        "actions": "Actions",
        "glCode": "GL code",
        "voucher": "Voucher"
      },
      "status": {
        "accrued": "Accrued, not yet paid",
        "accruedShort": "Unpaid",
        "paidShort": "Paid",
        "prepaidShort": "Prepaid",
        "paidDirect": "Paid {date} from {account}",
        "settled": "Settled {date} from {account}",
        "prepaid": "Prepaid {date} from {account}"
      },
      "emptyTitle": "No business expenses yet",
      "emptyAll": "Record the bills you pay directly here, instead of filing them as purchase invoices.",
      "emptyUnpaid": "Nothing is accrued. Every expense you have recorded is paid.",
      "emptyPaid": "No expenses have been paid yet.",
      "deletedTitle": "Expense deleted",
      "deletedDescription": "The {vendor} expense was removed and its journal entries reversed.",
      "deleteFailedTitle": "Couldn't delete that expense",
      "deleteFailedDescription": "Nothing was changed. Please try again.",
      "cancelledTitle": "Expense cancelled",
      "cancelledDescription": "The {vendor} expense was cancelled and its journal entries reversed.",
      "cancellationFailedTitle": "Couldn't cancel that expense",
      "cancellationFailedDescription": "Nothing was changed. Please try again.",
      "sortBy": "Sort by {column}",
      "voucherColumnTooltipLabel": "About payment voucher numbers",
      "voucherColumnHint": "Every payment gets a voucher number at the moment the money leaves. The default number carries the year and the month, so PV2608001 is the first voucher of August 2026.",
      "voucherSettings": "Payment voucher settings",
      "voucherBlank": "No number",
      "voucherMissing": "Add voucher",
      "voucherVoid": "(void)",
      "reopen": {
        "action": "Reopen to edit",
        "confirmTitle": "Reopen this expense for editing?",
        "confirmMessagePaid": "This reverses the posted {vendor} expense and its payment, releases any reconciled bank transaction back to the reconciliation queue, and voids the payment voucher. The record is then removed so you can re-enter it with corrections.",
        "confirmMessageAccrual": "This reverses the posted accrual for the {vendor} expense. The record is then removed so you can re-enter it with corrections.",
        "confirmButton": "Reverse and reopen",
        "successTitle": "Expense reopened for editing",
        "successDescription": "The {vendor} expense was reversed. Re-enter it below with your corrections.",
        "bankReleasedNote": "{count, plural, one {# bank transaction was released for re-reconciliation.} other {# bank transactions were released for re-reconciliation.}}",
        "failedTitle": "Couldn't reopen that expense",
        "failedDescription": "Nothing was changed. Please try again.",
        "hint": "Reverses the postings and returns the bill so you can correct it"
      },
      "captureCreditNote": "Capture supplier credit note",
      "recurringSettings": "Recurring bills",
      "recurringBadge": "Recurring",
      "recurringBadgeTitle": "Raised automatically by a recurring bill schedule"
    },
    "form": {
      "title": "Record a business expense",
      "description": "A bill you pay directly: not stock for resale, and not a staff claim.",
      "vendor": "Payee",
      "vendorPlaceholder": "TNB, landlord, Maxis…",
      "payeeOnFile": "Already in your payee list, so this bill joins the same balance.",
      "descriptionLabel": "What was it for",
      "descriptionPlaceholder": "July electricity",
      "expenseDate": "Expense date",
      "expenseDateHint": "The period this expense belongs to.",
      "amount": "Amount ({currency})",
      "account": "Account",
      "accountPlaceholder": "Choose an account",
      "accountGroupExpense": "Expense accounts",
      "accountGroupFixedAsset": "Fixed assets (capitalised)",
      "suggestedFromMemory": "Suggested because this is how you coded {vendor} last time.",
      "suggestedFromRule": "Suggested from the vendor name. Change it if it belongs elsewhere.",
      "purchaseTypeLegend": "How was this bought?",
      "purchaseTypeCash": "Cash purchase",
      "purchaseTypeCashHint": "Paid at the time, in the period it belongs to. A one-off, with no creditor to keep track of.",
      "purchaseTypeCredit": "Credit purchase (creditor)",
      "purchaseTypeCreditHint": "You owe them. It is tracked against this payee until you pay, and shows in what you owe.",
      "paidFrom": "Paid from",
      "paidFromPlaceholder": "Choose an account",
      "paidDate": "Payment date",
      "paymentReference": "Cheque / reference number (optional)",
      "paymentReferencePlaceholder": "e.g. CHQ-100234 or TRF-20260803-01",
      "paymentReferenceHelp": "The cheque or transfer reference. It prints on the payment voucher, and it lets bank reconciliation match this payment automatically.",
      "noBankAccounts": "No bank or cash account is available to pay from. Pick where your bank accounts live under Accounting → Chart of Accounts → Posting accounts.",
      "willPostTitle": "This will post",
      "willPostDirect": "Debit {expense}, credit {bank}. One entry; no payable is created.",
      "willPostPaidLate": "Debit {expense} on the expense date, credit {accrual}, then debit {accrual}, credit {bank} on the payment date. Two entries, so each month shows the right figure.",
      "willPostPrepaid": "You are paying before this expense is incurred, so it is a prepayment. Debit {prepayment}, credit {bank} on the payment date, then debit {expense}, credit {prepayment} on the expense date. Two entries, so the cost lands in the month it belongs to.",
      "willPostAccrual": "Debit {expense}, credit {accrual}. You settle it when you pay.",
      "willPostCapitalised": "This is a capital purchase. {asset} sits on the balance sheet, so the cost does not reduce this month’s profit. It is written off over the asset’s life through depreciation.",
      "willPostRelatedParty": "This payee is a related party, so the unpaid balance is disclosed separately from other creditors. The account is set under Payment and posting.",
      "theAccrualAccount": "your accruals account",
      "thePrepaymentAccount": "your prepayments account",
      "alreadyPaidHintLocked": "Accruing needs your accruals account to be set first, so a bill can only be recorded as a cash purchase for now.",
      "accrualNotConfigured": "No accruals account is set for this business yet, so an expense cannot be accrued. Choose the account you keep accruals in under Accounting → Chart of Accounts → Posting accounts. Until then, record the expense as already paid.",
      "accrualNotConfiguredPaidLate": "A payment dated in a later month is recorded through your accruals account too, so this will be refused until that account is set. Set it, or use a payment date in the same month as the expense date.",
      "accrualSetUpLink": "Set the accruals account",
      "thisExpenseAccount": "the expense account",
      "theBankAccount": "the bank account",
      "cancel": "Cancel",
      "save": "Save expense",
      "successTitle": "Expense recorded",
      "successPaid": "The {vendor} expense was recorded and paid.",
      "successAccrued": "The {vendor} expense was accrued. Record the payment when it goes out.",
      "errors": {
        "vendorRequired": "Enter who was paid.",
        "dateRequired": "Choose a valid date.",
        "amountRequired": "Enter an amount greater than zero.",
        "lineItemsRequired": "Complete every line item before saving.",
        "accountRequired": "Choose an account.",
        "bankRequired": "Choose the account it was paid from.",
        "paidBeforeExpense": "The payment date is before the expense date. This expense is already recorded as owed, so it cannot be paid before the cost was incurred. Use a payment date on or after the expense date, or delete it and record it again as already paid (which files it as a prepayment).",
        "summary": "Check the highlighted fields before saving.",
        "generic": "That expense couldn't be saved. Nothing was posted.",
        "currencyMissing": "Your business currency isn't set yet. Add it in Business Settings before recording an expense."
      },
      "currencyLoading": "Loading your business currency…",
      "prefillTitle": "Filled in from your document",
      "prefillReview": "Some values were hard to read. Check every field before you save.",
      "prefillCurrencyMismatch": "The document is in {documentCurrency}, but this expense is recorded in {businessCurrency}. Enter the {businessCurrency} amount.",
      "reReadLineItemsHelp": "No line items were stored for this reading. Read the bill again to look for them.",
      "reReadLineItemsAction": "Read line items again",
      "reReadLineItemsBusy": "Reading line items…",
      "reReadLineItemsFailedTitle": "Couldn't read the line items",
      "reReadLineItemsFailedDescription": "Nothing changed. Please try again.",
      "lineItemsTitle": "Line items from the bill ({count})",
      "lineItemsHelp": "Review the rows OCR read. The amount below is calculated from these lines.",
      "lineDescription": "Description",
      "lineItemCode": "Item code",
      "lineQuantity": "Qty",
      "lineUnit": "Unit",
      "lineUnitPrice": "Unit price",
      "lineTaxRate": "Tax %",
      "lineTotal": "Total",
      "addLineItem": "Add line item",
      "removeLineItem": "Remove line item {row}",
      "lineSubtotal": "Subtotal",
      "lineTax": "Tax",
      "lineGrandTotal": "Total",
      "billTitle": "Uploaded bill",
      "oneOffPayee": "One-off - don't add to my supplier list",
      "salesAgentHelp": "Attribute this spend to an agent. It shows on the agent's P&L.",
      "oneOffPayeeHelp": "The name stays on this record. Use it for a parking receipt or a shop you will not deal with again.",
      "alreadyPaid": "Already paid",
      "alreadyPaidHint": "Paid in the period it belongs to. Untick to accrue it and record the payment later.",
      "fromBankLine": {
        "title": "Filled in from your bank statement line",
        "body": "Check the details and add who you paid. Nothing is posted from the statement; the expense is recorded when you save.",
        "back": "Back to the bank line"
      }
    },
    "payment": {
      "title": "Record payment",
      "description": "Settle the {amount} accrued for {vendor}.",
      "confirm": "Record payment",
      "willPost": "Debit {accrual}, credit {bank}. The accrual clears.",
      "successTitle": "Payment recorded",
      "successDescription": "The {vendor} accrual was cleared.",
      "errorGeneric": "That payment couldn't be recorded. Nothing was posted.",
      "credits": {
        "title": "Credit notes from this payee",
        "help": "Tick the ones to use on this bill. Nothing is applied unless you choose it.",
        "linked": "{amount} already comes off this bill from credit notes raised against it.",
        "untitled": "Credit note",
        "remaining": "{date} · {remaining} left of {amount}",
        "applyAmount": "Use",
        "netToPay": "Net to pay",
        "fullyCredited": "The credits cover this bill in full, so there is no payment to record. Use less of one of them.",
        "blocked": {
          "CURRENCY_MISMATCH": "In a different currency from this bill.",
          "LIABILITY_ACCOUNT_MISMATCH": "This credit reduced a different liability account from the one this payment clears. Check the accrual account under Accounting, Chart of Accounts, Posting accounts.",
          "NOTHING_REMAINING": "Already used up.",
          "AMOUNT_NOT_POSITIVE": "Enter how much of it to use.",
          "EXCEEDS_CREDIT_REMAINING": "More than this credit note has left.",
          "EXCEEDS_BILL_OUTSTANDING": "More than this bill still carries.",
          "UNKNOWN": "This credit note cannot be used on this bill."
        }
      }
    },
    "intake": {
      "title": "Drop a bill here",
      "description": "Utilities, rental, subscriptions, fees, commissions. We read the document and fill in the form for you. Staff receipts belong in Expense Claims, and supplier invoices in Purchase Invoices.",
      "errorTitle": "That document couldn't be uploaded",
      "errorFileType": "Use a JPG, PNG or PDF. Nothing was recorded.",
      "errorTooLarge": "That file is over 10MB. Try a smaller photo or the original PDF.",
      "errorGeneric": "Please try again. Nothing was recorded, so you can also enter it by hand.",
      "queuedTitle": "Uploaded. Reading it now",
      "queuedDescription": "Your bill is in Pending bills below. We'll open it as soon as it has been read.",
      "extractedTitle": "We read your document",
      "extractedDescription": "Check the details, pick the expense account, then save.",
      "rejectedTitle": "That does not look like a bill",
      "rejectedDescription": "Upload a utility bill, rental invoice, or fee note. Nothing was recorded.",
      "unreadableTitle": "We could not read that document",
      "unreadableDescription": "Enter the details by hand below, or try a clearer photo or the original PDF."
    },
    "voucher": {
      "title": "Payment Voucher",
      "payTo": "Pay to",
      "payeeFromLedger": "Name taken from the ledger; the original bill is no longer on file",
      "voucherNumber": "Voucher No.",
      "voucherNumberBlank": "Voucher number cleared; write it in by hand",
      "paymentDate": "Date",
      "paymentReference": "Cheque / Ref No.",
      "paymentReferenceBlank": "No cheque or reference number; write it in by hand",
      "correctionBoundary": "Voucher-number edits change reference metadata only. To correct the amount, cash date, payment method, or bank reference, correct the source payment instead; Groot will unmatch it from bank reconciliation and record an official reversal before a replacement is posted.",
      "payeeVendorLinked": "Vendor record:",
      "payeeVendorUnlinked": "No vendor record matches “{name}”, so the payee is filed under the name on the bill.",
      "payTheSumOf": "Pay the sum of",
      "nativeAmount": "Paid as {amount}",
      "paymentIssued": "Payment issued",
      "paidFor": "Paid for",
      "preparedBy": "Prepared by",
      "approvedBy": "Approved by",
      "receivedBy": "Received by",
      "glReference": "Journal entry {entryNumber}",
      "registrationNumber": "Reg. No. {value}",
      "voidBadge": "Void",
      "voidReasonPaymentReversed": "The payment behind this voucher was reversed",
      "voidReasonManual": "Voided manually",
      "modalFor": "Payment to {vendor}",
      "modalGeneric": "Payment voucher for this bill",
      "numberSavedTitle": "Voucher number saved",
      "numberSaveFailedTitle": "Could not save the voucher number",
      "actionFailedGeneric": "Something went wrong on our side. Please try again.",
      "printNotLoggedTitle": "Printed, but we could not record it in the audit trail",
      "voidedTitle": "Voucher voided",
      "voidFailedTitle": "Could not void this voucher",
      "numberPlaceholder": "e.g. PV2608001",
      "numberHint": "Leave it empty to print a blank line and write the number in by hand.",
      "saveNumber": "Save",
      "editNumber": "Edit number",
      "void": "Void voucher",
      "print": "Print",
      "pcvTitle": "Petty Cash Voucher",
      "pcvPaymentReference": "Ref No.",
      "sheetUnavailable": "Voucher sheet unavailable. It may still be loading, or you may not have access.",
      "apRealisedLoss": "Exchange loss on this payment: {amount}",
      "apRealisedGain": "Exchange gain on this payment: {amount}",
      "apEstimated": "The {currency} amount is an estimate until it is checked against the bank statement.",
      "apSettles": "Settles",
      "apCreditNote": "Credit note"
    },
    "voucherSettings": {
      "page": {
        "title": "Payment Voucher Settings",
        "subtitle": "How payment voucher numbers are made"
      },
      "header": {
        "back": "Back to business expenses",
        "title": "Payment voucher numbering",
        "subtitle": "The number printed on every voucher, and whether vouchers are created at all",
        "save": "Save",
        "saving": "Saving",
        "saved": "Saved"
      },
      "enabled": {
        "title": "Create payment vouchers",
        "label": "Create a voucher for every payment",
        "help": "A voucher is created automatically when you record a payment, taking the next number below. Nothing to switch on per bill.",
        "offWarning": "While this is off, payments you record will have no voucher to print. Vouchers already created stay exactly as they are."
      },
      "numbering": {
        "title": "Number format",
        "prefixLabel": "Prefix",
        "prefixHelp": "Up to 10 characters, printed at the start of every voucher number.",
        "formatLabel": "Format",
        "aboutFormat": "About the number format",
        "formatTooltip": "A change applies to vouchers created from now on. Vouchers already printed keep the numbers they were given.",
        "formatOptions": {
          "prefix_year_seq": "{prefix} plus year plus running number",
          "prefix_year_month_seq": "{prefix} plus year plus month plus running number",
          "custom": "Custom"
        },
        "formatHelp": {
          "prefix_year_seq": "One sequence per year; the running number restarts each January.",
          "prefix_year_month_seq": "One sequence per month, so the voucher number itself tells you which month's file to pull.",
          "custom": "Pick the exact shape below: a two or four digit year, with or without the month, with or without a separator."
        },
        "custom": {
          "formatColumn": "Format",
          "sampleColumn": "Example",
          "monthNote": "A shape that includes the month restarts the running number every month."
        },
        "tooLong": "That prefix makes the voucher number longer than {max} characters. Please shorten it."
      },
      "preview": {
        "title": "Preview",
        "nextNumber": "Next voucher number",
        "formatShape": "Format: {shape}",
        "sequence": "The next three",
        "resetMonthly": "The running number restarts at 1 each month.",
        "resetYearly": "The running number restarts at 1 each year.",
        "counterLabel": "Running number",
        "counterReadOnly": "This counter moves forward on its own and cannot be edited. Winding it back would give two payments the same voucher number, and two paper files that both claim to be it."
      },
      "toast": {
        "savedTitle": "Voucher settings saved",
        "saveFailedTitle": "Could not save voucher settings",
        "saveFailedGeneric": "Something went wrong on our side. Please try again."
      },
      "familyTitles": {
        "PV": "Payment voucher numbering",
        "PCV": "Petty cash voucher numbering",
        "JV": "Journal voucher numbering",
        "RV": "Receipt voucher numbering"
      },
      "familySubtitles": {
        "PV": "The number printed on every voucher, and whether vouchers are created at all",
        "PCV": "The number printed on every petty cash voucher for payments made in cash",
        "JV": "The number printed on every journal voucher for approvals and manual journal entries",
        "RV": "The number printed on every internal receipt voucher for money received directly, such as bank interest. It is never a customer Official Receipt."
      },
      "documentsTab": {
        "intro": "One numbering standard for the documents this business issues. Each family keeps its own prefix and running sequence; numbers already issued never change.",
        "salesInvoiceTitle": "Sales invoice numbering",
        "salesInvoiceDescription": "Configured on the sales invoice settings page, together with e-invoice rules",
        "officialReceiptTitle": "Official Receipts",
        "officialReceiptDescription": "Numbered receipts for every customer payment you record as received, with optional automatic email. Turned on or off on the sales invoice settings page."
      },
      "refusals": {
        "prefixReserved": "A receipt voucher prefix cannot start with OR or RCT. Those belong to customer receipts.",
        "prefixInUse": "Another voucher type already uses this prefix. Choose a different prefix."
      }
    },
    "pending": {
      "title": "Pending bills ({count})",
      "description": "Uploaded, not yet on the books. Review one to record it, or discard it.",
      "capped": "Showing the 50 most recent uploads. Clear some to see the rest.",
      "review": "Review and record",
      "status": {
        "uploading": "Uploading",
        "processing": "Reading",
        "ready": "Ready to record",
        "unreadable": "Could not read",
        "rejected": "Not a bill",
        "failed": "Failed",
        "stalled": "Stopped"
      },
      "hint": {
        "uploading": "Sending the file",
        "processing": "Reading the document",
        "ready": "Check the details, then record it",
        "unreadable": "Enter the details by hand, or try a clearer photo",
        "rejected": "Staff receipts belong in Expense Claims, supplier invoices in Purchase Invoices",
        "failed": "Something went wrong on our side. Try again",
        "stalled": "This is taking too long. Try again",
        "creditNoteRecognised": "This looks like a credit note, not a bill"
      },
      "discard": {
        "action": "Discard",
        "confirmTitle": "Discard this upload?",
        "confirmMessage": "{fileName} will be deleted. Nothing has been recorded, so no accounting entry is affected.",
        "confirmButton": "Discard",
        "doneTitle": "Upload discarded",
        "failedTitle": "Could not discard that upload",
        "failedDescription": "Please try again."
      },
      "retry": {
        "action": "Try again",
        "failedTitle": "Could not read it again",
        "failedDescription": "Please try again, or record the details by hand."
      },
      "reopened": "Reopened to correct",
      "captureCreditNote": "Capture as supplier credit note"
    },
    "recurring": {
      "page": {
        "title": "Recurring Bills",
        "subtitle": "Bills that raise themselves ahead of their due date"
      },
      "header": {
        "back": "Back to business expenses",
        "newSchedule": "New recurring bill"
      },
      "status": {
        "active": "Active",
        "paused": "Paused"
      },
      "frequency": {
        "monthly": "Monthly",
        "quarterly": "Quarterly"
      },
      "amountType": {
        "fixed": "Fixed amount",
        "expected_variable": "Variable (estimated)"
      },
      "list": {
        "emptyTitle": "No recurring bills yet",
        "emptyDescription": "Set up rent, subscriptions, or loan instalments to raise themselves ahead of their due date.",
        "nextDue": "Next due",
        "lastRaised": "Last raised",
        "instalments": "{raised} of {total} instalments",
        "remainingBalance": "Remaining balance",
        "edit": "Edit",
        "pause": "Pause",
        "resume": "Resume",
        "remove": "Remove",
        "removeConfirmTitle": "Remove this recurring bill?",
        "removeConfirmMessage": "Bills already raised from it are not affected.",
        "removeConfirmButton": "Remove",
        "estimatedNote": "Estimated: update this amount as the real bill changes."
      },
      "form": {
        "titleCreate": "New recurring bill",
        "titleEdit": "Edit recurring bill",
        "vendorName": "Vendor",
        "description": "Description (optional)",
        "amountType": "Amount type",
        "fixedAmount": "Amount",
        "expectedAmount": "Estimated amount",
        "currency": "Currency",
        "defaultAccountCode": "Expense account (optional)",
        "defaultAccountCodeHelp": "Leave blank to let Groot classify it automatically, like a normal bill.",
        "frequency": "Frequency",
        "payDayOfMonth": "Pay day of month",
        "payDayOfMonthHelp": "1-31. Falls back to the last day of shorter months (e.g. 31 → Feb 28/29).",
        "reminderLeadDays": "Remind me (days before due date)",
        "reminderLeadDaysHelp": "How many days ahead of the due date this bill should appear for review.",
        "totalInstallments": "Number of instalments (optional)",
        "totalInstallmentsHelp": "Leave blank for an open-ended bill (rent, subscriptions).",
        "save": "Save",
        "saving": "Saving",
        "cancel": "Cancel"
      },
      "errors": {
        "title": "Couldn't save"
      }
    }
  },
  "addonTrial": {
    "title": "{addon} trial ends in {days, plural, one {# day} other {# days}}",
    "body": "It ends on {date}. After that {addon} switches off. Your data is kept and nothing is deleted. Contact us to keep it.",
    "dismiss": "Dismiss",
    "names": {
      "inventory": "Stock management",
      "fx": "Multi-currency"
    }
  },
  "writeErrors": {
    "permission": "You don't have permission to make this change. Ask an owner or finance admin to do it, or to give you access.",
    "notAMember": "You no longer have access to this business. Switch to another workspace, or ask an owner to invite you again.",
    "signedOut": "Your session has ended. Sign in again and we'll bring you back to this page.",
    "planLocked": "This isn't included in your current plan. Upgrade in Settings to turn it on.",
    "addonNotEnabled": "This is part of an add-on that is not switched on for this business. Contact us to switch it on.",
    "addonNotEnabledFx": "Foreign-currency documents are part of the Multi-currency add-on, which is not switched on for this business. Use your home currency, or contact us to switch it on.",
    "planCheckFailed": "We couldn't confirm what your plan includes just now. Wait a moment and try again.",
    "viewOnly": "You're viewing this account in read-only support mode, so changes can't be saved. End the support session first.",
    "businessNotFound": "We couldn't find this business. It may have been switched or removed. Refresh the page and try again.",
    "staffOnly": "This action is only available to Groot staff with the right role.",
    "outOfScope": "This account isn't in the set you're assigned to, so it can't be changed from here.",
    "network": "We couldn't reach the server, so nothing was changed. Check your connection and try again.",
    "generic": "We couldn't save that change. Nothing was changed. Please try again.",
    "notFound": "We could not find that record. It may have been deleted or renamed. Refresh the page and try again.",
    "validation": "Some of the details entered aren’t valid. Check the highlighted fields and try again.",
    "beforeConversionDate": "This date is before your opening-balance go-live date. Use a date on or after go-live, or review the opening balance in Accounting → Opening balance.",
    "uploadRetired": "This upload has expired. Upload the file again before saving.",
    "invoicePostingReview": "The invoice's accounting entry is missing or no longer valid. Review the invoice before recording or reversing its payment.",
    "documentVoided": "This document has been voided, so it can no longer be changed. If it was voided by mistake, enter it again as a new document.",
    "invoiceIsDraft": "This invoice is still a draft. Post it to put it in your books, or delete it. A draft cannot be voided or paid.",
    "deliverySourceVoided": "The sale behind this delivery order was voided, deleted or cancelled, so no stock can move against it. Cancel or void the delivery order instead.",
    "lhdnFilingNotAvailable": "E-invoicing to LHDN is not enabled for this business yet. Nothing was submitted.",
    "deliveryOrderInvoiced": "This delivery order is billed by an invoice. Void or credit the invoice first, then void the delivery order.",
    "deliveryInvoiceLinesLocked": "The lines of an invoice made from delivery orders are what was delivered, so their quantity, unit and item cannot be changed. Delete this draft and raise the delivery again to bill something else.",
    "orderBilledOnDelivery": "This order is invoiced delivery by delivery, so it cannot be converted whole. Invoice its delivery orders instead.",
    "deliverySourceAlreadyDelivered": "This invoice bills goods that were already delivered, so no delivery order can be raised from it.",
    "salesAccessOff": "Sales access is turned off for you, so nothing was changed. Ask the business owner or a finance admin to turn it back on."
  },
  "exchangeRates": {
    "title": "Exchange rates",
    "subtitle": "Foreign-currency documents are converted to {homeCurrency} at the market rate the form fetches when someone files them, and the person filing can type a different rate on the document itself. A rate recorded here is your preferred rate for that pair, and it wins over the fetched rate.",
    "subtitleNoHome": "Foreign-currency documents are converted to your books currency at the market rate the form fetches when someone files them, and the person filing can type a different rate on the document itself. A rate recorded here is your preferred rate for that pair, and it wins over the fetched rate.",
    "howItWorks": "A document uses the rate recorded for its own transaction date, or the most recent earlier one as long as it is at most {days} days old. When no rate here covers the date, the form uses the rate it fetched from a free public service; if that service cannot be reached, the person filing types the rate instead. Postings with no form behind them, such as a foreign bank transaction, are refused until a recorded rate covers their date.",
    "loading": "Loading exchange rates",
    "formTitle": "Add or correct a rate",
    "fromCurrency": "From",
    "toCurrency": "To",
    "rate": "Rate",
    "ratePlaceholder": "e.g. 4.7250",
    "ratePreview": "1 {from} = {rate} {to}",
    "effectiveDate": "Effective date",
    "effectiveDateHint": "Applies from this date, for up to {days} days.",
    "source": "Source",
    "sourcePlaceholder": "Bank statement, central bank, contract",
    "reason": "Note",
    "reasonPlaceholder": "Why this rate",
    "optional": "Optional",
    "save": "Save rate",
    "saving": "Saving",
    "created": "Rate saved.",
    "updated": "Rate updated.",
    "updatedCollapsed": "Rate updated, and {count} duplicate rows for the same date were removed.",
    "saveError": "That rate could not be saved. Check the values and try again.",
    "listTitle": "Rates on file",
    "empty": "No rates recorded, which is the normal state: foreign-currency documents use the rate their form fetched. Add one only when you want a specific rate used for a currency pair.",
    "colPair": "Pair",
    "colRate": "Rate",
    "colEffectiveDate": "Effective from",
    "colSource": "Source",
    "colActions": "Actions",
    "delete": "Delete",
    "deleteLabel": "Delete the {pair} rate effective {date}",
    "deleted": "Rate deleted.",
    "deleteError": "That rate could not be deleted. Try again.",
    "truncated": "Showing the {count} most recently entered rates. Older rates still apply when documents post.",
    "errors": {
      "invalidCurrency": "Pick a currency from the list.",
      "invalidRate": "Enter a rate greater than zero.",
      "invalidDate": "Enter the effective date as YYYY-MM-DD.",
      "samePair": "Pick two different currencies. An amount is already in its own currency.",
      "notFound": "That rate is no longer on file. Reload the page and try again.",
      "tooLong": "That note is too long. Shorten it and try again."
    }
  },
  "paymentVoucherRetro": {
    "issuableTitle": "No voucher was raised for this payment",
    "issuableBody": "The money left the business, but no payment voucher was created at the time. That is normal for payments recorded before vouchers were switched on.",
    "issuableNumberNote": "The new voucher takes its number from the current month, because voucher numbers are only ever issued in order. The payment date printed on it stays the real one.",
    "issueButton": "Issue voucher",
    "replaceButton": "Issue a replacement",
    "issuedTitle": "Payment voucher {voucherNumber} issued",
    "numberingOffTitle": "Voucher numbering is switched off",
    "numberingOffBody": "This business is not numbering payment vouchers, so none was created for this payment. Switch numbering on and you can issue one.",
    "numberingOffAction": "Open voucher settings",
    "noPaymentTitle": "This bill has not been paid yet",
    "noPaymentBody": "A payment voucher is evidence that money left the business, so there is nothing to vouch for yet. Record the payment and a voucher is created with it.",
    "reversedTitle": "This payment was reversed",
    "reversedBody": "The journal entry behind this payment has been reversed, so a voucher cannot say the money left. Record the payment again if it really was made.",
    "alreadyIssuedTitle": "A voucher already exists",
    "alreadyIssuedBody": "A payment voucher has already been raised for this payment. Close this bill and open it again to see it.",
    "unavailableTitle": "No voucher for this payment",
    "unavailableBody": "We cannot raise a voucher for this bill. Please refresh the page, and contact support if it stays this way.",
    "issueFailedTitle": "Could not issue the voucher",
    "errorGeneric": "Something went wrong on our side. Please try again.",
    "errorNoPayment": "This bill has not been paid yet, so there is no payment to vouch for.",
    "errorReversed": "The payment behind this bill was reversed, so a voucher cannot be issued for it.",
    "errorAlreadyIssued": "A payment voucher already exists for this payment.",
    "errorNumberingOff": "Voucher numbering is switched off for this business. Switch it on in voucher settings, then try again.",
    "errorPermission": "You do not have permission to issue payment vouchers.",
    "errorSignedOut": "Please sign in again.",
    "errorNotFound": "That bill no longer exists."
  },
  "businessExpensesHowItWorks": {
    "triggerAriaLabel": "How business expenses work",
    "title": "How business expenses work",
    "description": "This page records the bills your business pays directly: utilities, rental, subscriptions, repairs and professional fees.",
    "stepsHeading": "Recording a bill",
    "step1Title": "Drop the bill on the upload area",
    "step1Body": "We read the document and open the form with the vendor, the date and the amount already filled in. Check every field before you save, because a photo can be misread.",
    "step2Title": "Or enter it by hand with Record expense",
    "step2Body": "A bank charge or a fee with no document still has to be recordable. It is the same form the upload fills in.",
    "step3Title": "Say whether it is already paid",
    "step3Body": "A bill marked as already paid posts one entry, taking the money out of the account you paid from. A bill left unpaid accrues the cost to your payables account, and that accrual clears when you record the payment. Either way the cost lands in the month it belongs to.",
    "step4Title": "Check the GL code and the note beside it",
    "step4Body": "Every row shows the account the expense posted to, with a short note saying how that account was chosen: Matched by rule, Coded like last time, You chose this, or Uncategorised (check this). Correcting the account teaches us how you code this vendor, so the next bill from them arrives already right.",
    "step5Title": "A voucher is created when the money leaves",
    "step5Body": "Recording a payment creates a payment voucher and gives it the next number. Print it, sign it, and file it behind the supplier bill.",
    "step6Title": "Open a row to see the bill",
    "step6Body": "Clicking a row opens the document the expense was recorded from, with every saved field shown next to what OCR read. That is where you check a saved value against the paper.",
    "voucherHeading": "What the Voucher column tells you",
    "voucherNumberLabel": "A number",
    "voucherNumberDesc": "A voucher exists for this payment. Click the number to print the sheet or to change it.",
    "voucherNoNumberLabel": "No number",
    "voucherNoNumberDesc": "The voucher exists, but its number was cleared on purpose. The sheet prints a blank line so you can write your own number by hand.",
    "voucherVoidLabel": "A number crossed out, marked (void)",
    "voucherVoidDesc": "The payment behind the voucher was reversed, or someone voided it. The number stays used and the sheet still prints, marked void. A signed document that disappears is worse than one marked void.",
    "voucherMissingLabel": "Add voucher",
    "voucherMissingDesc": "The bill is paid, but it has no voucher. This is usually a payment recorded before vouchers were switched on. Click it to issue one now.",
    "voucherEmptyLabel": "Nothing at all",
    "voucherEmptyDesc": "The bill is not paid yet. An empty cell here is correct and not a missing voucher: a voucher is evidence that money left the business, and no money has left.",
    "tipsHeading": "Worth knowing",
    "tip1": "A voucher says that money left the business. That is why an unpaid bill has no voucher, and why a reversed payment leaves its voucher marked void instead of deleting it.",
    "tip2": "A voucher issued after the fact takes its number from the current month, not from the month of the payment. Numbers are only ever issued in order, because numbers out of order are what an auditor asks about. The payment date printed on the sheet is still the real one.",
    "tip3": "Staff receipts belong in Expense Claims, and supplier invoices for stock belong in Purchase Invoices. This page is for the bills that are neither.",
    "tip4": "If you pay before the cost is incurred, the bill is filed as a prepayment, so the cost still lands in the month it belongs to.",
    "tip5": "Deleting an expense reverses the journal entries it posted, so nothing is left half recorded.",
    "settingsHeading": "Voucher numbering",
    "settingsBody": "The prefix, the shape of the number, and whether vouchers are created at all.",
    "settingsLink": "Open payment voucher settings"
  },
  "partyLedgerAccount": {
    "label": "Ledger account",
    "settingLink": "Open Payment & posting",
    "chartLink": "Open the chart of accounts",
    "customer": {
      "posted": "This customer's invoices post to its own account, inside {control}.",
      "awaiting": "A dedicated account is created under this control the first time this customer is invoiced.",
      "shared": "Every customer's invoices post to this shared control account.",
      "unusable": "The account this customer was linked to no longer sits under {control}, so it is ignored. The next invoice files it in the right place.",
      "absent": "Receivables are set to post to {code}, which this chart does not have.",
      "archived": "This receivables control account is archived, so invoices have nowhere to post."
    },
    "vendor": {
      "posted": "This supplier's bills post to its own account, inside {control}.",
      "awaiting": "A dedicated account is created under this control the first time this supplier is billed.",
      "shared": "Every supplier's bills post to this shared control account.",
      "unusable": "The account this supplier was linked to no longer sits under {control}, so it is ignored. The next bill files it in the right place.",
      "absent": "Payables are set to post to {code}, which this chart does not have.",
      "archived": "This payables control account is archived, so bills have nowhere to post."
    }
  },
  "onboardingInterview": {
    "questions": {
      "ownerKind": {
        "prompt": "Which best describes your business?",
        "help": "First we’ll understand how the business is set up. Your line of work also matters, especially if you sell or hold stock."
      },
      "industry": {
        "individual": {
          "prompt": "What kind of work do you do?",
          "help": "Pick the closest one. It decides which accounts we create for you."
        },
        "company": {
          "prompt": "What does the business do?",
          "help": "Pick the closest one. It decides which accounts we create for you."
        }
      },
      "industryDisambiguation": {
        "individual": {
          "prompt": "Which of these is your main work?",
          "help": "Your answer could fit more than one. Choose the one you earn most from."
        },
        "company": {
          "prompt": "Which of these is the main business?",
          "help": "Your answer could fit more than one. Choose the one it earns most from."
        }
      },
      "countryCode": {
        "individual": {
          "prompt": "Which country do you work in?",
          "help": "This sets your currency and the tax accounts you need."
        },
        "company": {
          "prompt": "Which country does the business operate in?",
          "help": "This sets your currency and the tax accounts you need."
        }
      },
      "businessName": {
        "individual": {
          "prompt": "What name should we put on your invoices?",
          "help": "Many sole traders use their own name. This appears on every document you send."
        },
        "company": {
          "prompt": "What is the business's name?",
          "help": "This appears on every invoice and receipt you send, so use the registered name."
        }
      },
      "booksOrigin": {
        "individual": {
          "prompt": "Do you already keep your books somewhere?",
          "help": "If you do, we will import your accounts instead of creating new ones."
        },
        "company": {
          "prompt": "Does the business already keep its books somewhere?",
          "help": "If it does, we will import those accounts instead of creating new ones."
        }
      }
    },
    "options": {
      "ownerKind": {
        "individual": "I’m self-employed or a sole proprietor",
        "company": "I run a registered company or employ people"
      },
      "booksOrigin": {
        "existing": "Yes, I have accounts to bring over",
        "fresh": "No, start me fresh"
      }
    },
    "recommendation": {
      "reason": {
        "worksForSelf": "You work for yourself, so there is one set of books and nobody to pay. This plan is priced for that.",
        "worksForSelfService": "You work for yourself in a service or platform business, so Solo keeps your books simple.",
        "ownerOperatedBusiness": "You run this business yourself, but it sells, makes, or holds goods, like a home kitchen or retailer. Starter gives you tools to track stock and costs.",
        "invoicesOrEmploys": "You invoice customers or employ people, so Pro gives you full invoicing, supplier bills and team workflows.",
        "invoicesOrEmploysPlatformWork": "You pay people, but your income arrives on platform statements rather than invoices you raise, so the lighter plan fits."
      },
      "title": "The plan that matches your answers",
      "matchLabel": "A good match",
      "nextStepHint": "I’ll use this setup to get your workspace ready.",
      "reasonLabel": "Why this one",
      "accept": "Continue with {plan}",
      "change": "Choose a different plan",
      "pickTitle": "Pick your plan",
      "trialNote": "You start on a free trial today and pay nothing now. When the trial ends you choose whether to carry on.",
      "noPaymentNote": "This plan applies as soon as your workspace is created. Setting up costs nothing.",
      "existingSubscriptionNote": "You already have a subscription, so this workspace joins the plan you are on."
    },
    "intro": {
      "title": "Let’s shape your workspace",
      "subtitle": "I’ll ask a few simple questions, explain the choices, and build a chart that fits your work.",
      "assistantName": "Groot setup guide",
      "assistantSubtitle": "A short conversation to get your books ready",
      "setupLabel": "Your setup",
      "setupSubtext": "I’ll keep track of the details as we go.",
      "progress": "{current} of {total} understood"
    },
    "turn": {
      "answerLabel": "Your answer",
      "answerPlaceholder": "Answer in your own words",
      "keyboardHint": "Enter to send · Shift + Enter for a new line",
      "voice": "Speak",
      "stopVoice": "Stop listening",
      "voiceUnavailableShort": "Voice unavailable",
      "voiceUnavailable": "Voice input is not available in this browser. You can still type your answer.",
      "voiceError": "I couldn't hear that. Try again or type your answer.",
      "answerHint": "Say it naturally. I’ll translate it into setup choices.",
      "customAnswerDivider": "or type your own answer",
      "suggestionsLabel": "Suggestions",
      "quickChoicesLabel": "Quick choices",
      "quickChoicesHint": "Choose the closest match to continue quickly.",
      "optionDescriptions": {
        "ownerKind": {
          "individual": "You run the work yourself, including a sole-proprietor or owner-operated business.",
          "company": "A registered company or team with shared responsibilities, invoices, or employees."
        },
        "booksOrigin": {
          "existing": "Bring the account structure you already use. We’ll take you to import it after setup.",
          "fresh": "Start with a chart shaped around your work. You can change it later."
        }
      },
      "send": "Send",
      "orChoose": "Or choose a quick answer",
      "thinking": "Reading your answer",
      "change": "Change this answer",
      "retry": "Try again",
      "progress": "Question {current} of {total}",
      "sending": "Sending",
      "orPick": "Or pick one",
      "pickOne": "Pick the closest one",
      "dataDisclosure": "Your description helps us improve how the product reads answers like yours. We keep it for 90 days and then delete it."
    },
    "retention": {
      "notice": "Your description helps us improve how the product reads answers like yours. We keep it for 90 days and then delete it."
    },
    "confirmation": {
      "title": "Here is what we understood",
      "intro": "Check each line. Your workspace is built from these answers.",
      "fields": {
        "ownerKind": "How you work",
        "industry": "Line of work",
        "countryCode": "Country",
        "businessName": "Name on your documents",
        "booksOrigin": "Your books today"
      },
      "values": {
        "ownerKind": {
          "individual": "You work for yourself",
          "company": "You invoice or employ other people"
        },
        "booksOrigin": {
          "existing": "You already keep books elsewhere",
          "fresh": "You are starting fresh"
        }
      },
      "confirm": "That is right, continue",
      "correct": "Something is wrong",
      "correcting": "Pick the answer you want to change.",
      "summary": "You {ownerKind}, your line of work is {industry}, and you operate from {country}.",
      "ownerKind": {
        "individual": "work for yourself",
        "company": "invoice or employ other people"
      },
      "nameLine": "Your invoices and receipts will say {name}.",
      "countryLine": "Your currency and tax accounts follow {country}.",
      "change": {
        "businessName": "Change the name",
        "countryCode": "Change the country",
        "keepsBooksElsewhere": "Change this"
      },
      "industryPrompt": "If your line of work is wrong, pick the closest instead.",
      "ownerKindPrompt": "If we read how you work wrongly, change it here.",
      "needs": {
        "title": "Anything else should I set up?",
        "hint": "Tell me about fees, delivery, commissions, or anything else you need to track.",
        "examplesLabel": "Common examples",
        "examples": {
          "platform": "Marketplace fees",
          "platformText": "A marketplace or delivery app deducts commission from each payout",
          "delivery": "Home delivery",
          "deliveryText": "I pay home delivery and courier costs"
        },
        "inputLabel": "Additional setup needs",
        "customHint": "Or type your own",
        "placeholder": "e.g. A delivery app deducts commission from each order",
        "send": "Check this",
        "thinking": "Checking your note",
        "heard": "I heard",
        "included": "Already in your chart",
        "review": "I couldn’t find an exact starter account for this yet. You can add or map it after setup.",
        "noMatch": "I couldn’t match that to a starter account yet. Try describing the fee or cost.",
        "unavailable": "I couldn’t check that just now. You can try again or continue without it.",
        "labels": {
          "platformFees": "Platform fees",
          "deliveryCosts": "Delivery costs",
          "salesCommission": "Commission paid",
          "commissionIncome": "Commission income",
          "marketingAdvertising": "Marketing and advertising"
        }
      }
    },
    "name": {
      "suggestionHint": "We filled this in from your account. Change it if you trade under another name.",
      "useSuggestion": "Use this name",
      "required": "Type the name you trade under before you continue."
    },
    "fallback": {
      "notice": "Our reading is unavailable right now. Answer these questions instead and we will finish setting up your books."
    },
    "errors": {
      "INTERVIEW_EMPTY_ANSWER": "We did not catch that. Type your answer and send it again.",
      "INTERVIEW_TOO_MANY_ANSWERS": "This has taken more questions than we allow. We will finish with a short set of choices.",
      "INTERVIEW_ALREADY_COMPLETED": "Your workspace is already set up. We are taking you to it.",
      "INTERVIEW_INCOMPLETE_READING": "One answer is still missing, so we cannot build anything yet. We will ask for it again.",
      "INTERVIEW_PLAN_NOT_OFFERABLE": "That plan cannot be chosen here. Pick one of the plans on this screen.",
      "FORBIDDEN": "This setup belongs to another account. Sign in with the account that started it.",
      "PROVISION_UNCONFIRMED_READING": "Your answers have not been confirmed yet. Go back to the summary and confirm them.",
      "PROVISION_INDUSTRY_MISSING": "Your line of work is missing. It decides which accounts we create, so we need it first.",
      "PROVISION_NAME_MISSING": "The name you trade under is missing. It goes on every invoice and receipt you send.",
      "PROVISION_NAME_UNCONFIRMED": "This name came from your account details. Keep it, or type the name you trade under.",
      "PROVISION_CHART_SOURCE_CONFLICT": "Two of your answers about your existing books disagree. Tell us once more whether you keep books somewhere else.",
      "UNEXPECTED": "We could not set up your workspace. Your answers are saved, so you can try again."
    },
    "panel": {
      "title": "Your chart of accounts",
      "listedHeading": "Accounts your answers add",
      "counts": "{listed, plural, one {One account comes} other {# accounts come}} from your answers. Another {standard} standard accounts come with every business, so your chart starts with {total}.",
      "awaitingOwnerKind": "Answer the first question and this panel starts filling in with the accounts your work needs.",
      "awaitingIndustry": "Every business starts with {standard} standard accounts. Tell us your line of work and we will add the ones it needs.",
      "standardCovered": "Your work needs no accounts beyond the standard set, so the standard chart of {total} accounts covers it.",
      "showAccounts": "See your accounts",
      "hideAccounts": "Hide accounts",
      "needsHeading": "For what you mentioned"
    },
    "importBranch": {
      "title": "You already keep books elsewhere",
      "body": "We will not create a chart for you. The accounts you import are the only ones this workspace will have.",
      "next": "We take you to the import screen right after your workspace is created.",
      "continueToImport": "Continue to import",
      "reverseHint": "If you would rather start from Groot's chart, change your answer to the books question."
    }
  },
  "marketplace": {
    "title": "Marketplace",
    "subtitle": "Shopee orders, stock and fees in one place",
    "notEntitled": "Marketplace connectors are not switched on for this business.",
    "connection": {
      "title": "Connections",
      "connectShop": "Connect a shop",
      "disconnect": "Disconnect",
      "shopName": "Shop",
      "status": "Status",
      "lastSync": "Last synced",
      "statusConnected": "Connected",
      "statusNeedsReconnect": "Reconnect needed",
      "statusDisconnected": "Disconnected",
      "syncFailed": "We could not sync this shop. Reconnect it to keep orders coming in.",
      "backfillLabel": "How far back to import orders",
      "empty": "No shop is connected yet.",
      "setupTitle": "Marketplace connections",
      "setupDescription": "Connect a marketplace shop so orders, stock and platform fees flow into your books automatically.",
      "platformsTitle": "Platforms",
      "statusPendingApproval": "Awaiting platform approval",
      "statusPlanned": "Planned",
      "reasonPendingApproval": "Our partner profile is under review by Shopee Open Platform. Connecting a shop opens up once Shopee approves it.",
      "reasonPlanned": "Coming after Shopee.",
      "flowTitle": "What happens once a shop is connected",
      "flowDescription": "Nothing is posted to your books until an order is actually shipped.",
      "flowStep1": "Shopee marks an order as paid. Groot reserves the stock and leaves your books untouched.",
      "flowStep2": "Shopee marks it as shipped. Groot raises the sales invoice and takes the stock out.",
      "flowStep3": "Groot posts the commission and selling fees to the accounts set by your fee rules.",
      "flowStep4": "Anything Groot is unsure about is held for you to review, never guessed.",
      "liveTitle": "Already working today",
      "liveDescription": "These do not need a shop connection.",
      "liveFees": "Platform fee rules for Shopee, Lazada and TikTok Shop",
      "liveReconciliation": "Sales statement import, payout matching and fee reconciliation",
      "openReconciliation": "Open Reconciliation"
    },
    "orders": {
      "title": "Orders",
      "orderReference": "Order reference",
      "orderDate": "Order date",
      "gross": "Gross",
      "fees": "Fees",
      "net": "Net",
      "status": "Status",
      "statusReserved": "Stock reserved",
      "statusPosted": "Posted",
      "statusHeld": "Held",
      "statusCancelled": "Cancelled",
      "invoice": "Invoice",
      "empty": "No orders yet.",
      "loadMore": "Load more"
    },
    "review": {
      "title": "Needs review",
      "heldCount": "{count} orders need review",
      "reasonUnmappedProduct": "A product is not mapped to an item",
      "reasonAmountsDoNotTie": "Gross, fees and net do not tie out",
      "reasonPossibleDuplicate": "An invoice may already exist for this order",
      "reasonClosedPeriod": "The accounting period for this order is closed",
      "reasonFeesUnavailable": "Shopee has not released the fee breakdown yet. This will retry automatically.",
      "release": "Release",
      "released": "Order released",
      "empty": "Nothing needs review."
    },
    "mapping": {
      "title": "Product mapping",
      "marketplaceProduct": "Marketplace product",
      "catalogueItem": "Catalogue item",
      "chooseItem": "Choose an item",
      "suggested": "Suggested match",
      "confirm": "Confirm mapping",
      "change": "Change mapping",
      "confirmed": "Mapping saved",
      "ambiguous": "More than one item matches this product",
      "unmapped": "Not mapped yet"
    },
    "fees": {
      "title": "Platform fees",
      "feeType": "Fee type",
      "amount": "Amount",
      "account": "Account",
      "unknownType": "New fee type. Confirm which account it belongs to.",
      "refunded": "Refunded"
    },
    "agent": {
      "cardTitle": "Marketplace orders",
      "heldOrdersTitle": "Orders held for review",
      "releaseConfirmTitle": "Release this order?",
      "releaseConfirmBody": "Groot will put order {orderReference} back into its normal flow.",
      "releaseConfirmAction": "Release order",
      "viewInMarketplace": "Open marketplace"
    },
    "settlement": {
      "title": "Marketplace settlement",
      "description": "Every settlement statement you have imported, with the amount the platform released, the adjustments that sit outside it, and the amount your bank should credit.",
      "historyTitle": "Imports",
      "historyDescription": "One row per statement, per currency. Open the file name to see the import it came from.",
      "refresh": "Refresh",
      "importAction": "Import a settlement file",
      "loading": "Loading settlement history",
      "retry": "Try again",
      "unavailableTitle": "We could not load your settlement history",
      "unavailableDescription": "Nothing was changed. Try again in a moment, and tell us if it keeps happening.",
      "noBusinessTitle": "Choose a business first",
      "noBusinessDescription": "Marketplace settlement is kept per business. Choose one to see its imports.",
      "noImportsTitle": "No statement import yet",
      "noImportsDescription": "This shop has covered periods but no imported statement file, so there is nothing to list here.",
      "emptyTitle": "Import your first settlement statement",
      "emptyDescription": "Groot reads the whole workbook exactly as you downloaded it, separates the released amount from the adjustments, and tells you what your bank should credit.",
      "emptyWhereTitle": "Where to get the file",
      "emptyStep1": "In Seller Centre, open Finance, then My Income.",
      "emptyStep2": "Choose Income Details and pick the payout week you want.",
      "emptyStep3": "Select Export and download the Excel workbook.",
      "emptyAsDownloaded": "Upload it exactly as downloaded. Do not delete sheets, rename the file, or save it again.",
      "loadMore": "Load more",
      "range": "{from} to {to}",
      "basisOrderClaims": "Order level",
      "basisPeriodOnly": "Period only",
      "openHoldsCount": "{count} on hold",
      "noOpenHolds": "None",
      "figuresFloor": "This import has more rows than we read, so these totals are a floor rather than the final figure.",
      "viewSource": "Open the import this came from",
      "howItWorksTitle": "How marketplace settlement works",
      "howItWorksFiguresHeading": "Three figures, not one",
      "howItWorksFiguresBody": "The platform states a released amount. Adjustments sit outside that total, so the amount your bank credits is the released amount plus those adjustments. Groot shows all three, so the difference is never a mystery.",
      "howItWorksClaimsHeading": "One order, one recognition",
      "howItWorksClaimsBody": "Every order reference an import consumes is claimed. If a later statement carries the same order, Groot holds it instead of recognising the revenue twice.",
      "howItWorksCoverageHeading": "Covered periods and gaps",
      "howItWorksCoverageBody": "Period coverage shows which weeks a lane owns and which weeks are missing. Imports made before order claims existed are listed apart, because nothing can claim them after the fact.",
      "howItWorksHoldsHeading": "Holds are yours to decide",
      "howItWorksHoldsBody": "Groot never nets two overlapping statements on its own. It shows you the orders in conflict and records which way you decided, and who decided it.",
      "table": {
        "period": "Period",
        "shop": "Shop",
        "released": "Released amount",
        "adjustments": "Adjustments",
        "expectedBankCredit": "Expected bank credit",
        "gross": "Gross sales",
        "fees": "Platform fees",
        "refunds": "Refunds",
        "claims": "Claims",
        "status": "Status",
        "openHolds": "Holds",
        "source": "Source file"
      },
      "status": {
        "draft_review": "In review",
        "confirmed": "Confirmed",
        "confirmed_with_exceptions": "Confirmed with exceptions",
        "posted": "Posted",
        "partially_posted": "Partly posted",
        "voided": "Voided"
      },
      "shop": {
        "label": "Shop this statement belongs to",
        "placeholder": "Choose a shop",
        "fromStatement": "{username} (named in this statement)",
        "detected": "This statement names the seller {username}.",
        "notNamed": "This statement does not name a seller, so choose the shop yourself.",
        "help": "Every order in this file is recorded against the shop you pick, so the same order can never be counted twice.",
        "required": "Choose which shop this statement belongs to first."
      },
      "figures": {
        "title": "{currency} settlement",
        "released": "Released amount",
        "releasedHelp": "What the platform statement says it released.",
        "adjustments": "Adjustments",
        "adjustmentsHelp": "Money that moved outside that total. A negative figure reduces what you are paid.",
        "expected": "Expected bank credit",
        "expectedHelp": "Released amount plus adjustments. Compare this figure with your bank.",
        "notBooked": "Not booked: {amount}.",
        "notBookedHelp": "Groot did not recognise the adjustment type, so it is held rather than guessed."
      },
      "adjustments": {
        "title": "Adjustments in this statement",
        "adjustmentDated": "Adjustment dated {date}",
        "linkedOrder": "Reverses order {reference}.",
        "originalPeriod": "That order settled on {period}.",
        "unlinked": "No matching order in this file.",
        "unlinkedHelp": "The adjustment is still counted in this import. It names an order this file does not carry, which is normal when you started using Groot part way through."
      },
      "claims": {
        "stepLabel": "Orders",
        "title": "Order check",
        "intro": "Groot records every order in this file so the same order can never be recognised twice.",
        "orderCount": "Orders in this file: {count}",
        "confirmAction": "Confirm import and record orders",
        "confirmed": "Import confirmed. Orders recorded: {count}",
        "alreadyConfirmed": "This import was already confirmed. Nothing was recorded twice.",
        "registered": "Orders recorded: {count}",
        "registeredHelp": "Read from this import. A later file naming any of these orders is held for you to decide.",
        "none": "No orders were recorded from this import.",
        "done": "Done"
      },
      "holds": {
        "kindDuplicate": "Already recorded",
        "kindRestatement": "Recorded at a different amount",
        "kindPeriodOwned": "This period is already covered",
        "owner": "Recorded by the {lane} on {date}.",
        "laneStatement": "statement import",
        "laneConnector": "shop connection",
        "owningBatch": "Earlier import: {batch}",
        "conflictCount": "Orders affected: {count}",
        "delta": "Difference: {amount}",
        "references": "For example: {references}",
        "resolutionHelp": "Groot never merges these and never books the difference. Pick the one that describes what happened.",
        "sameMoney": "Same money, skip these orders",
        "differentOrders": "Different orders, record the conflict",
        "resolved": "Resolved as {resolution} on {date}.",
        "resolvedSameMoney": "same money",
        "resolvedDifferentOrders": "different orders",
        "decisionRecorded": "Decision recorded. Orders affected: {count}"
      },
      "errors": {
        "onHold": "This import is on hold. Decide what happened to the orders already recorded, then confirm again.",
        "shopRequired": "Choose which shop this statement belongs to first. Nothing was confirmed.",
        "shopNotFound": "That shop does not belong to this business. Nothing was confirmed.",
        "crossTenant": "Some orders in this file are recorded against another business. Nothing was confirmed. Contact support with this import.",
        "shopConflict": "The seller name and the shop id in this statement point at two different shops. Groot will not merge them for you.",
        "confirmFailed": "Could not confirm this import. Nothing was recorded, so you can try again."
      }
    },
    "coverage": {
      "title": "Period coverage",
      "description": "Which settlement periods are already in your books, which are missing, and which were imported before order claims existed.",
      "coveredTitle": "Covered",
      "gapsTitle": "Missing",
      "noCovered": "No period is covered yet.",
      "noGaps": "No missing period between the covered ones.",
      "range": "{from} to {to}",
      "laneStatement": "Statement",
      "laneConnector": "Connector",
      "basisOrderClaims": "Order level",
      "basisPeriodOnly": "Period only",
      "incomplete": "We read only part of this shop’s coverage, so a period listed as missing may already be imported.",
      "noShopsTitle": "No marketplace shop yet",
      "noShopsDescription": "A shop appears here the first time you import a statement for it.",
      "unclaimedTitle": "Imported before order claims existed",
      "unclaimedDescription": "These statements were imported before Groot started claiming individual orders. Their order references were not kept, so they cannot be claimed now. Treat these periods as unprotected.",
      "historyIncomplete": "We read only part of your import history, so there may be more of these.",
      "noUnclaimedHistory": "None. Every marketplace import you have is claimed or period covered.",
      "periodUnknown": "Period could not be determined",
      "notClaimable": "Cannot be claimed"
    },
    "holds": {
      "title": "Overlap holds",
      "description": "An import stops here when an order it carries has already been recognised. Decide once per hold, and Groot records what you chose.",
      "loading": "Loading holds",
      "emptyTitle": "Nothing is on hold",
      "emptyDescription": "No order in this import conflicts with one already recognised.",
      "kindDuplicate": "Already recognised",
      "kindRestatement": "Restated at a different amount",
      "kindPeriodOwned": "Period already owned",
      "conflictCount": "{count} orders in conflict",
      "owningLaneLabel": "Already claimed by",
      "owningClaimedAtLabel": "Claimed on",
      "amountDeltaLabel": "Amount difference",
      "laneStatement": "A statement import",
      "laneConnector": "The platform connector",
      "referencesLabel": "Orders in conflict",
      "referencesMore": "and {count} more",
      "noteLabel": "Note",
      "notePlaceholder": "Why you decided this way (optional)",
      "statusOpen": "Open",
      "statusResolved": "Resolved",
      "resolveSameMoney": "Same money",
      "resolveSameMoneyHelp": "These orders are already in your books. Groot skips them and confirms the rest of the import.",
      "resolveSameMoneyAction": "Skip these orders",
      "resolveDifferentOrders": "Different orders",
      "resolveDifferentOrdersHelp": "The two sources mean different orders under one reference. Groot records a distinct conflict and keeps both records.",
      "resolveDifferentOrdersAction": "Record as distinct",
      "resolutionSameMoney": "Decided as the same money. Those orders were skipped.",
      "resolutionDifferentOrders": "Decided as different orders. Recorded as a distinct conflict.",
      "resolvedByOn": "Resolved by {who} on {when}",
      "resolvedUnknownActor": "a teammate",
      "resolvedUnknownTime": "an unrecorded date",
      "resolveSuccess": "Decision recorded. {count} orders affected.",
      "resolveFailed": "We could not record that decision, so nothing changed. Try again.",
      "noNettingNote": "Groot never books the difference between two overlapping statements. Both options above keep every record intact."
    }
  },
  "businessIndustry": {
    "title": "Your industry",
    "description": "Groot builds your chart of accounts from your industry. If the industry recorded here is wrong, your chart is missing accounts your business needs.",
    "recorded": "Groot has your industry recorded as {industry}.",
    "notRecorded": "This business has no industry recorded yet.",
    "choose": "Choose your industry",
    "chooseHint": "Pick the closest match to how this business earns most of its money.",
    "addsCount": "{count} new account(s)",
    "addsNone": "No new accounts",
    "addOnly": "Changing your industry only adds accounts. Groot keeps every account you already have, with the same name and the same number, and it does not touch anything you have already recorded.",
    "apply": "Save industry",
    "saving": "Saving...",
    "saved": "Industry saved. {count} new account(s) added to your chart.",
    "saveFailed": "Could not save the industry. Please try again.",
    "loading": "Loading your industry"
  },
  "autoCountSend": {
    "heading": "AutoCount",
    "loading": "Checking this invoice against AutoCount",
    "noneLabel": "Not sent",
    "noneBody": "Groot has not sent this invoice to AutoCount yet.",
    "succeededNoDocNoBody": "AutoCount reported this invoice as saved but sent back no document number, so there is nothing to reconcile against. Open AutoCount and check what is there before you do anything else.",
    "docNo": "AutoCount document {docNo}",
    "totalMismatchHeading": "AutoCount saved a different document total",
    "attempts": "{count, plural, =1 {# attempt so far} other {# attempts so far}}",
    "updatedAt": "last change {at}",
    "detailToggle": "What AutoCount reported",
    "ambiguousReasonToggle": "Why the outcome is unknown",
    "unknownFailureCode": "The companion did not identify which part failed. Groot support can inspect the protected companion logs.",
    "unknownRemedy": "Groot could not work out what needs fixing here. Send the field named below to Groot support.",
    "refusalHeading": "Groot did not send this invoice.",
    "remedyField": "Field: {field}.",
    "remedyFieldOnLine": "Field: {field}, line {line}.",
    "blocked": "Send stays off until this invoice can be sent safely. The state above says why.",
    "send": {
      "action": "Send to AutoCount",
      "again": "Send to AutoCount again",
      "retryPrerequisites": "Check prerequisites again",
      "sending": "Sending"
    },
    "stateLabel": {
      "queued": "Waiting",
      "leased": "Picked up",
      "writing": "Writing",
      "succeeded": "Saved",
      "failed": "Failed",
      "ambiguous": "Needs checking"
    },
    "stateBody": {
      "queued": "Groot has this invoice queued. Your AutoCount companion picks it up the next time it checks in.",
      "leased": "Your AutoCount companion has taken this invoice and is about to write it. Nothing has reached AutoCount yet.",
      "writing": "Your companion is writing this invoice into AutoCount right now. Leave it alone until it finishes.",
      "succeeded": "AutoCount saved this invoice as document {docNo}. That is the number to reconcile against.",
      "failed": "AutoCount did not save this invoice, and nothing was written to your books.",
      "ambiguous": "Groot never learned whether AutoCount saved this invoice, so it may or may not be in your books. Search AutoCount for the supplier's invoice number (use Find, not the list, because the list hides drafts) before you do anything else, then record what you found under Settings > Integrations > AutoCount > Connection. Do not send it again first."
    },
    "totalCheck": {
      "unknown": "AutoCount saved this invoice, but Groot could not read back the total AutoCount recorded, so the two amounts have not been checked against each other.",
      "agrees": "AutoCount's own total for document {docNo} matches the amount Groot sent.",
      "disagrees": "Groot sent {expected} for this bill, but the total on AutoCount document {docNo} is {posted}. These are document totals, not payments, so a part payment does not explain the difference. Nothing in Groot has changed. Open that document in AutoCount and check it before this bill is paid or reconciled."
    },
    "failureCode": {
      "api_signature_mismatch": "The AutoCount software on your server is a different version than Groot targets, so the write never started. This is not a password problem. Tell Groot support which AutoCount version you run.",
      "ap_api_shape_unverified": "Groot could not find the AutoCount supplier invoice functions it needs on your installation, so nothing was written. This one needs a Groot engineer rather than a setting change.",
      "sql_principal_denied": "The companion could not sign in to your SQL Server, so it never reached AutoCount. The Windows account the companion runs as needs access to the AutoCount database.",
      "autocount_login_rejected": "AutoCount refused the companion's login. Check the AutoCount user name and password the companion uses on your server.",
      "master_data_missing": "A code in this invoice does not exist in AutoCount, and Groot will never create one in your books. Add the code in AutoCount, or point this invoice at a code that is already there, then send it again.",
      "document_rejected": "AutoCount itself rejected this invoice. A closed period or one of your own validation rules is the usual cause. Check AutoCount and the protected companion log.",
      "companion_unauthorized": "The companion could not prove who it was, so Groot turned it away. Enrol it again under Settings > Integrations > AutoCount > Connection.",
      "ap_save_signal_unproven": "AutoCount finished without telling Groot whether it saved this invoice. Treat it as unknown: open AutoCount and look before you send it again.",
      "session_lost": "The companion lost its AutoCount session part way through, so nothing was saved. It signs back in on its own. Send this invoice again once the connection reads as connected.",
      "unclassified": "The companion could not put a name to this failure. Groot support can inspect the protected companion log."
    },
    "refusal": {
      "not_posted_in_groot": "This invoice must be posted in Groot first. AutoCount can only receive it after Groot has created and saved its own A/P journal entry.",
      "party_code_conflict": "This supplier has multiple or conflicting AutoCount creditor codes. Refresh or import your AutoCount creditor master, resolve the supplier to one exact creditor code, then send again. Groot will not auto-create or name-match a creditor while this conflict exists.",
      "item_code_conflict": "An invoice item has multiple or conflicting AutoCount stock codes. Refresh or import the AutoCount item master, resolve the item to one exact code, then check prerequisites again.",
      "item_defaults_missing": "This invoice has linked item lines, but the AutoCount default item group or base UOM is missing. Enter both under Settings > Integrations > AutoCount > Export, then check prerequisites again.",
      "creditor_control_account_missing": "Automatic creditor creation needs the creditor control account from this AutoCount book. Enter it under Settings > Integrations > AutoCount > Export, then check prerequisites again.",
      "post_disabled": "Posting into AutoCount is switched off for this business, so nothing was sent. An owner or finance admin can switch it on under Settings > Integrations > AutoCount > Export.",
      "doc_no_format_missing": "Groot has no AutoCount document number series to post this bill under, and it will never pick one for you. Enter your Doc No. Format under Settings > Integrations > AutoCount > Export, then send this invoice again.",
      "review_pending": "This invoice is still waiting for someone to check what Groot read off it. Review the extracted details and confirm them, then send it to AutoCount.",
      "companion_unavailable": "The AutoCount companion on your own server is not connected, so nothing can reach AutoCount right now. Check that the machine is switched on and Groot AutoCount Bridge is running, then try again.",
      "already_queued": "This invoice is already on its way to AutoCount. Wait for it to finish instead of sending it a second time.",
      "already_posted": "AutoCount already holds this invoice, so Groot will not post it a second time.",
      "ambiguous_unresolved": "An earlier attempt on this invoice ended with an unknown outcome, so Groot does not know whether AutoCount holds it. Open AutoCount and look, record what you found under Settings > Integrations > AutoCount > Connection, and only then decide. Sending it again now can post the same bill twice.",
      "duplicate_supplier_invoice": "Another Groot document already carries this supplier's invoice number for the same creditor, and AutoCount treats that pair as one bill. Work out which document is the real one before you send either.",
      "master_data_missing": "This invoice is missing something AutoCount needs, so Groot did not send it. What has to happen is listed below.",
      "not_an_ap_invoice": "Only supplier invoices can be sent to AutoCount. This document is not one, so there is nothing to post.",
      "input_tax_split_unsupported": "Your business claims the tax on its purchases back, so the tax on this bill has to reach AutoCount as one of your own AutoCount tax codes. Groot has no way to know which code that is yet, so it sent nothing rather than post the tax to the wrong place. Please contact Groot support.",
      "gst_review_pending": "Groot needs to know whether you are claiming the tax on this bill back before it can post it to AutoCount. Review the GST treatment on this invoice, then send it again.",
      "item_link_unconfirmed": "An item on this invoice is not yet matched to a confirmed catalog item. The match may be a guess Groot made from the document that nobody has confirmed, or the item it points at may be a draft Groot created from a document, and Groot will not create an AutoCount stock item from either. Match the line to a confirmed catalog item under Products > Needs review, then send again."
    },
    "remedy": {
      "map_master_data": "A code Groot holds has no match in AutoCount yet, and Groot will never invent one. Someone has to supply the AutoCount code for the item named below, copied from your own AutoCount setup, before this invoice can be sent.",
      "configure_autocount": "Your AutoCount settings are incomplete. Fill in the missing setting under Settings > Integrations > AutoCount > Export, then send this invoice again.",
      "fix_the_invoice": "The invoice itself is incomplete or does not add up. Correct the field named below with Edit extracted fields on this document, then send it again.",
      "not_supported": "Groot cannot carry this invoice into AutoCount at all, and no setting changes that. Foreign currency payables and unknown currencies are the usual causes. Please contact Groot support."
    },
    "toasts": {
      "queued": "Queued for AutoCount. Your companion writes it on its next check in.",
      "masterSyncQueued": "Master sync started. The A/P invoice has not been queued yet."
    },
    "errors": {
      "sendFailed": "We could not send this invoice to AutoCount. Nothing was queued. Please try again.",
      "unknownRefusal": "AutoCount refused this invoice for a reason this version of Groot does not recognise. Nothing was sent, and we have been told about it."
    },
    "masterSync": {
      "state": {
        "syncing": "Syncing prerequisites",
        "ready": "Ready for A/P",
        "blocked": "Needs action",
        "failed": "Retry available"
      },
      "body": {
        "syncing": "Groot AutoCount Bridge is confirming or creating the missing AutoCount master data in dependency order. The A/P invoice has not been sent yet.",
        "ready": "Every required AutoCount code is confirmed. Groot is queueing the A/P invoice without another click.",
        "blocked": "Groot stopped before the A/P invoice because a required setting or exact code needs a person to decide.",
        "failed": "The attempt stopped before a confirmed local save. Nothing is treated as created, and this run can be retried safely."
      },
      "step": {
        "creditor": "Creditor",
        "item_group": "Item group",
        "stock_item": "Stock item (base UOM included)",
        "ap_invoice": "A/P invoice"
      },
      "currentStep": "Current step: {step}",
      "allocatedCode": "AutoCount allocated code {code}, but Groot is still waiting for the local save checkpoint. This does not mean the record was created yet.",
      "blockedHeading": "What you need to fix",
      "failedHeading": "Safe to retry",
      "retry": "Retry master sync",
      "retrying": "Retrying",
      "sendAgainHint": "After fixing or importing the mapping, check prerequisites again below. Groot reruns preflight and either queues the A/P invoice or starts a fresh prerequisite run.",
      "remedy": {
        "companion_unavailable": "Start or re-enrol Groot AutoCount Bridge on the Windows machine, then retry.",
        "settings_missing": "Complete the automatic master-creation settings under Settings > Integrations > AutoCount > Export.",
        "creditor_control_account_missing": "Enter the creditor control account from this AutoCount book under Settings > Integrations > AutoCount > Export.",
        "default_item_group_missing": "Enter an existing AutoCount item group code under Settings > Integrations > AutoCount > Export.",
        "default_base_uom_missing": "Enter the base UOM used by this AutoCount book under Settings > Integrations > AutoCount > Export.",
        "item_defaults_missing": "Enter both the default item group and base UOM from this AutoCount book under Settings > Integrations > AutoCount > Export.",
        "allocator_rejected": "Fix the code allocator or defaults in AutoCount. Groot will not invent a replacement code.",
        "sdk_unsupported": "Update Groot AutoCount Bridge or use a supported AutoCount build. This installed API does not expose the required operation.",
        "runtime_unverified": "Update and restart Groot AutoCount Bridge so it reports master-sync support. Automatic creation stays off until then.",
        "code_conflict": "A different AutoCount record already uses this exact code. Map the correct existing record; Groot will not overwrite it.",
        "master_ambiguous": "Two AutoCount records share this name, so Groot will not choose between them. Open AutoCount, decide which record is correct, and map it in Groot; nothing was created.",
        "uom_unknown": "AutoCount does not have this unit of measure. Add it in AutoCount, or correct the unit on the invoice line, then send again.",
        "uom_master_unreadable": "Groot could not read AutoCount's unit-of-measure list, so it would not create a stock item with an unchecked unit. Check the Bridge's AutoCount permissions, then send again.",
        "invoice_preflight_changed": "Fix the newly reported invoice prerequisite, then send this invoice again.",
        "transport_failed": "Check the connection and retry. Groot reads the exact code before any create, so it will not blindly duplicate the record.",
        "report_lost": "Retry is safe: Groot checks the exact code and accepts a compatible existing row before attempting another create.",
        "operation_failed": "The AutoCount operation stopped before a confirmed save. Check AutoCount and the Bridge log, correct the local issue, then retry.",
        "checkpoint_failed": "Groot could not record the allocated code, so the Bridge did not save it. Check the connection, then retry.",
        "bridge_result_invalid": "The Bridge did not return the exact saved code. Update and restart the Bridge, then retry; Groot has not treated the record as created.",
        "requester_unauthorized": "The original requester's access changed. An owner or finance administrator must use Send Again.",
        "invoice_settings": "Complete the current AutoCount posting settings, then use Send Again.",
        "invoice_review": "Complete the invoice or tax review in Groot, then use Send Again.",
        "invoice_in_progress": "An A/P job already exists for this invoice. Refresh and wait for that job instead of creating another.",
        "invoice_already_posted": "This invoice is already recorded in AutoCount. Inspect the existing document; do not send it again.",
        "invoice_ambiguous": "Inspect AutoCount and resolve the earlier unknown result before attempting another send.",
        "invoice_duplicate": "Another Groot document has the same creditor and supplier invoice number. Open that record instead of sending a duplicate.",
        "invoice_type": "This document no longer qualifies as a posted A/P invoice. Correct and post it in Groot before sending again.",
        "invoice_tax": "This invoice uses a recoverable input-tax split the current AutoCount lane cannot post. Do not retry; contact Groot support.",
        "unknown": "Refresh this invoice. If no specific remedy appears, contact Groot support with the invoice reference.",
        "item_link_unconfirmed": "Match the invoice line to a confirmed catalog item under Products > Needs review, then use Send Again."
      },
      "toasts": {
        "retried": "Master sync queued again.",
        "retryFailed": "Groot could not retry this master sync. Nothing was changed."
      }
    },
    "probeAbsent": "Groot read all {count, plural, =1 {# invoice} other {# invoices}} AutoCount holds and none matches this supplier's invoice number.",
    "probeInconclusive": "Groot tried to read AutoCount's invoices but could not be sure. Search for the supplier's invoice number (use Find, not the list, because the list hides drafts) before recording what you found under Settings > Integrations > AutoCount > Connection."
  },
  "csvImport": {
    "sourceLayout": {
      "sheetLabel": "Sheet",
      "sheetOptionRecognised": "{name} (recognised {format})",
      "recognisedNote": "Recognised as {format}. Groot picked the sheet and header row for you.",
      "ambiguousNote": "This file matches more than one format. Choose the sheet to import.",
      "headerRowLabel": "Header row",
      "headerRowHint": "Choose the row that holds your column names.",
      "rowOption": "Row {number}",
      "rowOptionPreview": "Row {number}: {preview}",
      "columnsFound": "Columns found ({count})",
      "changeFailed": "Groot found no column names on that row. Choose another row."
    },
    "title": "Import from CSV",
    "subtitle": "{step} · {fileName}",
    "steps": {
      "upload": "Upload",
      "mapColumns": "Map Columns",
      "preview": "Preview",
      "validate": "Validate"
    },
    "actions": {
      "cancel": "Cancel",
      "back": "Back",
      "preview": "Preview",
      "validating": "Validating...",
      "confirmImport": "Confirm & Import"
    },
    "template": {
      "savePrompt": "Save this mapping as a template?",
      "saveHint": "Next time you upload a file with the same columns, the mapping will be applied automatically.",
      "namePlaceholder": "Template name (e.g., Shopee Monthly Statement)",
      "saving": "Saving...",
      "saveAndImport": "Save & Import",
      "skipAndImport": "Skip & Import"
    },
    "upload": {
      "processing": "Processing file...",
      "analyzing": "Analyzing columns and mapping fields",
      "dropzone": "Drop your file here or click to browse",
      "supports": "Supports CSV, XLSX, XLS (max {limit} MB)",
      "manageTemplates": "Manage saved templates"
    },
    "mapping": {
      "confidenceHigh": "High",
      "confidenceMedium": "Medium",
      "confidenceLow": "Low",
      "unmapped": "Unmapped",
      "requiredSuffix": "{label} *",
      "aiAnalyzing": "AI is analyzing your columns...",
      "templateApplied": "Template applied: <strong>{name}</strong>",
      "schemaTypeLabel": "Schema type:",
      "sourceColumn": "Source Column",
      "mapsTo": "Maps To",
      "confidence": "Confidence",
      "requiredNote": "* Required fields. Adjust mappings as needed. The AI suggestion is a starting point."
    },
    "schemaTypes": {
      "daily_sales": "Platform & POS sales",
      "sales_statement": "Sales Statement",
      "bank_statement": "Bank Statement",
      "purchase_order": "Purchase Order",
      "goods_received_note": "Goods Received",
      "leave_balance": "Leave Balance"
    },
    "previewStep": {
      "noColumns": "No columns are mapped. Go back and map at least the required fields.",
      "title": "Preview ({count, plural, one {# row} other {# rows}})",
      "columnsMapped": "{count, plural, one {# column mapped} other {# columns mapped}}",
      "titleCapped": "Preview (showing {shown} of {total, plural, one {# row} other {# rows}})"
    },
    "emptyCell": "empty",
    "validation": {
      "someValid": "{validRows} of {totalRows, plural, one {# row is} other {# rows are}} valid",
      "allValid": "{totalRows, plural, one {The only row is valid} other {All # rows are valid}}",
      "errorSummary": "{errorCount, plural, one {# error} other {# errors}} found across {rowCount, plural, one {# row} other {# rows}}. You can import valid rows only or go back to fix mappings.",
      "row": "Row",
      "column": "Column",
      "error": "Error",
      "value": "Value",
      "unmappedColumn": "(unmapped)",
      "showingFirst": "Showing first {shown} of {total, plural, one {# error} other {# errors}}",
      "backToMapping": "Back to Mapping",
      "importValid": "Import {count, plural, one {# Valid Row} other {# Valid Rows}}",
      "importAll": "Import All {count, plural, one {# Row} other {# Rows}}"
    },
    "validationErrors": {
      "notMapped": "Required field \"{label}\" is not mapped to any column.",
      "empty": "Required field \"{label}\" is empty.",
      "notANumber": "\"{label}\" expects a number but got \"{value}\".",
      "notADate": "\"{label}\" expects a date but got \"{value}\"."
    },
    "templates": {
      "loading": "Loading templates...",
      "savedCount": "Saved Templates ({count})",
      "empty": "No saved templates yet. Templates are created when you complete an import and choose to save the mapping.",
      "columnsCount": "{count, plural, one {# column} other {# columns}}",
      "lastUsed": "Last used {date}",
      "deleteConfirm": "Delete?",
      "rename": "Rename",
      "delete": "Delete"
    },
    "fields": {
      "adjustments": "Adjustments",
      "balance": "Balance",
      "businessDate": "Business Date",
      "carryover": "Carry Over Days",
      "channel": "Channel",
      "commissionFee": "Commission Fee",
      "condition": "Condition",
      "creditAmount": "Credit Amount",
      "currency": "Currency",
      "customerName": "Customer Name",
      "debitAmount": "Debit Amount",
      "deliveryDate": "Delivery Date",
      "description": "Description",
      "discountsPromotions": "Discounts / Promotions",
      "employeeEmail": "Employee Email",
      "entitled": "Entitled Days",
      "expectedNetSettlement": "Expected Settlement",
      "grnDate": "GRN Date",
      "grnNumber": "GRN Number",
      "grossAmount": "Gross Amount",
      "grossSales": "Gross Sales",
      "itemCode": "Item Code",
      "leaveTypeCode": "Leave Type Code",
      "lineDescription": "Line Description",
      "locationCode": "Location",
      "marketingFee": "Marketing Fee",
      "netAmount": "Net Amount",
      "orderDate": "Order Date",
      "orderReference": "Order Reference",
      "otherAdjustments": "Other Adjustments",
      "outputGst": "Output GST",
      "paymentMethod": "Payment Method",
      "platformFee": "Platform Fee",
      "platformFees": "Platform Fees",
      "poDate": "PO Date",
      "poNumber": "PO Number",
      "productCode": "Product Code",
      "productName": "Product Name",
      "quantity": "Quantity",
      "quantityOrdered": "Quantity Ordered",
      "quantityReceived": "Quantity Received",
      "quantityRejected": "Quantity Rejected",
      "reference": "Reference",
      "refundAmount": "Refund Amount",
      "refunds": "Refunds",
      "serviceCharge": "Service Charge",
      "shippingFee": "Shipping Fee",
      "sourceReference": "Reference",
      "totalAmount": "Total Amount",
      "transactionDate": "Transaction Date",
      "transactionType": "Transaction Type",
      "unitMeasurement": "Unit of Measure",
      "unitPrice": "Unit Price",
      "used": "Used Days",
      "vendorName": "Vendor Name",
      "year": "Year"
    }
  },
  "dailySales": {
    "setup": {
      "title": "{account} is not ready",
      "titleUnnamed": "A posting account is not ready",
      "body": "Groot records each day of takings through this account until the matching bank settlement clears. Groot can add it for you, or you can choose an account you already use in Payment & posting.",
      "action": "Set up {account}",
      "actionUnnamed": "Set up the account",
      "created": "Groot added the account. You can post daily sales now.",
      "alreadyReady": "The account is already set up. You can post daily sales now.",
      "errors": {
        "parentInUse": "Groot cannot add this account for you. It would sit under an account this business already uses, and that account would stop accepting entries. In Payment & posting, choose the account you use for Sales settlement clearing.",
        "heading": "The account this business points at has sub-accounts, so it cannot take entries. In Payment & posting, choose one of its sub-accounts for Sales settlement clearing.",
        "occupied": "That account is already used for something else, so Groot cannot create it. In Payment & posting, choose an active asset account for Sales settlement clearing.",
        "generic": "Groot could not set up the account. In Payment & posting, choose it yourself for Sales settlement clearing."
      },
      "bodyChecking": "Checking whether Groot can add this account for you.",
      "bodyBlocked": "Groot cannot add this account for you, because it would sit under an account this business already uses. In Payment & posting, choose the account you use for Sales settlement clearing.",
      "openSetting": "Choose it in Payment & posting"
    },
    "columns": {
      "date": "Date",
      "businessDate": "Business date",
      "location": "Location",
      "channel": "Channel",
      "source": "Source",
      "gross": "Gross sales",
      "adjustments": "Adjustments",
      "gst": "Output tax",
      "fees": "Platform fees",
      "commission": "Commission excl. tax",
      "commissionTax": "Commission tax",
      "advertising": "Advertising excl. tax",
      "advertisingTax": "Advertising tax",
      "otherCharges": "Other charges excl. tax",
      "otherChargesTax": "Other charges tax",
      "inputGst": "Input GST",
      "compensation": "Order compensation",
      "storeId": "Store ID",
      "settlement": "Expected settlement",
      "variance": "Variance",
      "reference": "Reference",
      "status": "Status",
      "discounts": "Discounts",
      "refunds": "Refunds",
      "service": "Service charge",
      "other": "Other adjustments",
      "posting": "Posting"
    },
    "tableHeader": {
      "date": "Date",
      "location": "Location",
      "channel": "Channel",
      "source": "Source",
      "gross": "Gross",
      "adjustments": "Adjustments",
      "gst": "Output tax",
      "fees": "Fees",
      "settlement": "Settlement",
      "variance": "Variance",
      "reference": "Reference",
      "status": "Status"
    },
    "status": {
      "row": {
        "ready": "Awaiting confirmation",
        "exception": "Needs review",
        "confirmed": "Confirmed (not posted)",
        "posted": "Posted to ledger",
        "voided": "Voided"
      },
      "batch": {
        "draftReview": "Draft (not confirmed)",
        "confirmed": "Confirmed (not posted)",
        "confirmedWithExceptions": "Confirmed with exceptions (not posted)",
        "partiallyPosted": "Partially posted",
        "posted": "Posted to ledger",
        "voided": "Voided"
      }
    },
    "records": {
      "title": "Imported sales records",
      "subtitle": "Source facts stay visible before and after ledger posting.",
      "emptyTitle": "No Platform & POS sales yet",
      "emptyBody": "Import the Groot template or map a platform export to begin.",
      "unassigned": "Unassigned",
      "locationLabel": "{code} · {name}"
    },
    "batch": {
      "fallbackTitle": "Platform & POS sales batch",
      "loading": "Loading source facts…",
      "description": "{platform} · {rows} source rows · imported {imported}",
      "sourceTotals": "{currency} source totals",
      "calcVariance": "Calculated {calculated} · Variance {variance}",
      "grossLine": "Gross {gross}",
      "reviewOutcome": "Review outcome",
      "validCount": "{count} valid",
      "exceptionsPosted": "{exceptions} exceptions · {posted} posted",
      "actionRequired": "Action required",
      "actionRequiredBody": "Exception rows stay in the audit trail but are excluded from confirmation and report totals. Posting errors can be retried after fixing the named setup issue.",
      "sourceRows": "Source rows",
      "sourceFile": "Source file",
      "columnsNote": "Choose the source facts shown in this batch review.",
      "viewOriginal": "View original",
      "viewJournal": "View journal",
      "viewReversal": "View reversal",
      "voidTitle": "Void import",
      "voidBody": "Groot reverses posted journals and keeps the original import in history.",
      "voidReasonPlaceholder": "Reason for correction",
      "voidAction": "Void import",
      "discardAgain": "Click again to discard",
      "discardDraft": "Discard draft",
      "voidReverse": "Void / reverse",
      "confirmValidRows": "Confirm valid rows",
      "retryFailedPosting": "Retry failed posting",
      "postToLedger": "Post to ledger",
      "journalDialogTitle": "Sales Import journal entry",
      "journalReadOnly": "Read-only ledger entry linked to this Sales Import source row.",
      "postProgress": "{done} completed · {remaining} remaining",
      "toast": {
        "confirmed": "Confirmed {rows} valid rows.",
        "confirmedWithExceptions": "Confirmed {rows} valid rows; {exceptions} exceptions retained.",
        "confirmFailed": "Could not confirm this batch. Review the exceptions and try again.",
        "postPartial": "Some rows could not post. Review the row errors, fix setup, then retry.",
        "postCompleted": "{count, plural, one {Posted # journal entry} other {Posted # journal entries}}",
        "postFailed": "Posting failed. Review the row errors, correct the setup, then retry.",
        "voidedWithReversals": "Batch voided with {count} reversal journals.",
        "voided": "Batch voided.",
        "voidFailed": "Could not void this batch. Check the reversal date and try again.",
        "discarded": "Draft batch and source file discarded",
        "discardFailed": "Could not discard this draft. Please try again.",
        "voidReleaseIncomplete": "This batch is voided, but Groot has not finished releasing the orders it recognised. Void it again to finish. Nothing is double-counted in the meantime."
      }
    },
    "page": {
      "title": "Platform & POS sales",
      "subtitle": "Consolidate POS and delivery-platform sales by business date and Location. Review source facts first; post them to the ledger only when ready.",
      "downloadTemplate": "Download Groot template",
      "importSales": "Import sales",
      "accessTitle": "Finance access required",
      "accessBody": "Only an Owner or Finance Admin can import, confirm, post, or review Platform & POS sales.",
      "locationTrackingDisabled": "Location tracking is disabled, so imports remain Unassigned. Enable Locations in Settings → Business → Tracking dimensions when you are ready to compare outlets.",
      "importPayout": "Import Grab payout",
      "cleanupAction": "Clean up {count} drafts",
      "cleanupConfirm": "Click again to discard {count} drafts",
      "cleanupHelp": "Removes only unconfirmed drafts in the current filtered view. Re-import them to run AI review.",
      "cleanupSuccess": "Discarded {count} draft batches and source files",
      "cleanupFailed": "Could not clean up these drafts. Try again.",
      "cleanupLimit": "Filter the table to {count} or fewer draft batches before cleaning them up."
    },
    "filters": {
      "fromDate": "From date",
      "toDate": "To date",
      "allLocations": "All Locations",
      "allChannels": "All channels",
      "allSources": "All sources",
      "allStatuses": "All statuses"
    },
    "channels": {
      "pos": "POS",
      "shopee": "Shopee",
      "grabfood": "GrabFood",
      "foodpanda": "Foodpanda",
      "other": "Other"
    },
    "statusFilter": {
      "ready": "Review",
      "exception": "Exception",
      "confirmed": "Confirmed",
      "posted": "Posted",
      "voided": "Voided"
    },
    "payout": {
      "overview": {
        "loading": "Loading payout clearing status",
        "unavailable": "Payout clearing is unavailable right now. Try again.",
        "title": "Payout clearing",
        "ties": "Ties",
        "attention": "Needs attention",
        "incompleteStatus": "Incomplete",
        "description": "Marketplace and delivery payouts should clear the exact amount the platforms no longer hold.",
        "oldest": "Oldest outstanding sale: {date}",
        "platformOutstanding": "Still held by the platforms",
        "platformOutstandingNamed": "Still held by {platforms}",
        "platformsFallback": "the platforms",
        "sourceCount": "{count} unsettled source rows",
        "sourceCountPayoutless": "No payout file exists for {platforms}, so this is checked against the clearing account.",
        "countUnavailable": "Source count unavailable",
        "booksClearing": "Clearing account",
        "booksHelp": "What the ledger says the platforms still owe",
        "difference": "Difference",
        "differenceZero": "Platform records and the ledger agree.",
        "differenceNonZero": "Review missing or incorrectly posted payouts.",
        "differenceUnknown": "The difference cannot be calculated from this read. Import the missing per-order file, or open the posted import to see what is missing.",
        "differenceCannotCompute": "Cannot be calculated",
        "incompleteLimit": "This workspace holds more records than one check can read, so these figures cover only part of the history. Do not use the difference as a final reconciliation. Open the Sales settlement clearing account in Account inquiry for the full balance.",
        "incompleteNoSourceRows": "Posted imports from {platforms} with no per-order source rows: {count}. They cannot be matched to a payout, so the difference is not final. Open those imports in the table below to see what was posted, and treat the difference as unconfirmed until each one has per-order rows.",
        "setupNeeded": "Setup needed",
        "setupNotConfigured": "Choose a Sales settlement clearing account in Payment & posting to track what the platforms still owe you after each import.",
        "setupHeading": "Your Sales settlement clearing account has sub-accounts, so it cannot hold this balance. Designate one of its sub-accounts on the Chart of Accounts.",
        "setupLink": "Open Chart of Accounts"
      },
      "import": {
        "title": "Import Grab payout",
        "description": "Upload the Transfers export. Groot joins each payout to sales using its exact Settlement ID.",
        "fileHelp": "Use the GrabMerchant Transfers export with Settlement ID, Net Total, Transfer Date and destination bank details.",
        "chooseFile": "Choose a CSV or Excel file",
        "reading": "Reading payout file…",
        "fileLimit": "CSV, XLSX or XLS up to 20 MB",
        "chooseAnother": "Choose another file",
        "cancel": "Cancel",
        "posting": "Creating payout import…",
        "create": "Create payout import"
      },
      "preview": {
        "ready": "{count} payouts ready to import",
        "postingHelp": "Each payout is recorded once, using the transfer date and the full amount for that Settlement ID."
      },
      "errors": {
        "read": "This is not a readable Grab Transfers export. Download the Transfers file from GrabMerchant and try again.",
        "create": "Could not create the payout import. Nothing was posted. Try again."
      },
      "toast": {
        "created": "Created {count} payout records.",
        "duplicate": "This payout file was already imported."
      },
      "history": {
        "title": "Recent payouts",
        "description": "Settlement IDs stay visible in full so each bank credit can be traced to its source sales."
      },
      "table": {
        "transferDate": "Transfer date",
        "settlementId": "Settlement ID",
        "store": "Store",
        "amount": "Net total",
        "bank": "Destination bank",
        "sources": "Linked sales",
        "status": "Status",
        "viewPosting": "View or reverse posting",
        "viewCashBook": "View in Cash Book",
        "bankUnknown": "Bank not stated",
        "sourceSummary": "{events} source rows across {batches} batches"
      },
      "status": {
        "unmatched": "Awaiting bank match",
        "matched": "Draft ready to post",
        "released": "Released",
        "reversed": "Reversed"
      }
    },
    "itemsSold": {
      "orderCapture": {
        "title": "Capture Grab orders",
        "description": "Keep adding screenshots across dates until you Confirm. Transaction imports record revenue and fees; this draft records quantities and stock cost only.",
        "method": "Order screenshots",
        "uploadTitle": "Add order screenshots",
        "uploadHelp": "Screenshots stay private to your business. Only order details are read; customer and driver details are not extracted.",
        "chooseFiles": "Choose screenshots",
        "filesSelected": "{count} screenshots selected",
        "readScreenshots": "Read screenshots",
        "reading": "Reading screenshots",
        "saveDraft": "Save draft",
        "addScreenshots": "Add screenshots",
        "reviewRequired": "Review required",
        "reviewHelp": "Check the order details against the screenshot before confirming stock use.",
        "unknown": "Unknown",
        "orderId": "Order ID",
        "longOrderId": "Long Order ID",
        "shortOrderId": "Short Order ID",
        "store": "Grab store",
        "businessDate": "Order date",
        "status": "Status",
        "evidence": "Order evidence",
        "evidenceCount": "{count} screenshots",
        "viewEvidence": "View screenshot",
        "duplicateEvidence": "Repeated order screenshot",
        "duplicateHelp": "This screenshot adds evidence to the existing order. Its quantities are counted once.",
        "missingLongId": "Enter the exact Long Order ID shown on the screenshot.",
        "ambiguousId": "The Order ID is unclear. Check the screenshot and enter the exact Long Order ID.",
        "missingStore": "Choose the verified Grab store for this order.",
        "missingDate": "Check the screenshot and enter the order date.",
        "missingFulfilment": "Confirm whether this order was delivered, cancelled or refunded.",
        "arithmeticHold": "The item amounts do not agree with the order total. Check the screenshot before saving the review.",
        "unmatchedMoney": "Matching Grab transactions have not been posted. Import and post them in Daily Sales before confirming stock use.",
        "matchedMoney": "Matched to posted Grab transactions",
        "postedMoneyCoverage": "{covered} of {total} posted money orders covered",
        "heldOrders": "{count} orders need review",
        "reviewOrder": "Review order",
        "saveReview": "Save review",
        "saving": "Saving",
        "delivered": "Delivered",
        "cancelled": "Cancelled",
        "refunded": "Refunded",
        "unknownFulfilment": "Delivery status unknown",
        "disposition": "Stock use",
        "consumed": "Stock was consumed",
        "notConsumed": "Stock was not consumed",
        "dispositionHelp": "A refund does not restore stock. Choose whether the order consumed stock.",
        "menuItem": "Product",
        "modifierGroup": "Add-on group",
        "modifier": "Add-on",
        "quantity": "Quantity",
        "quantityMode": "What the quantity means",
        "totalPieces": "Total pieces, including the base item",
        "additionalPieces": "Additional pieces, on top of the base item",
        "ambiguousQuantity": "Choose whether this quantity is the total or an addition. Check the original wording on the screenshot.",
        "packaging": "Packaging",
        "packagingInDish": "Included in the product formula",
        "packagingProduct": "Separate packaging product",
        "packagingNone": "No packaging stock consumed",
        "packagingHelp": "Count packaging once, in the product formula or a packaging product. The customer packaging charge is not its stock cost.",
        "selectProduct": "Choose a Sales Product",
        "noProductMatch": "No Sales Product matches",
        "formulaMissing": "Add a formula to this product before confirming stock use.",
        "openFormula": "Open Formulas",
        "noStock": "No stock is consumed",
        "noStockHelp": "Use only for an item that does not consume tracked stock. Items with missing formulas still need review.",
        "previewTitle": "Stock use preview",
        "previewHelp": "Quantities and stock cost only. Each order keeps its own date, even when this draft spans several dates.",
        "stockDate": "Stock posting date",
        "confirmTitle": "Confirm stock use",
        "confirmHelp": "This deducts reviewed quantities and records stock cost on each order date. Revenue, discounts and fees stay with the transaction import.",
        "confirm": "Confirm stock use",
        "posting": "Recording stock use",
        "heldNextAction": "Resolve the order details and post matching Grab transactions in Daily Sales, then confirm here.",
        "loadFailed": "The captured orders could not be loaded. Refresh and try again.",
        "saveFailed": "The order review could not be saved. Refresh the draft and try again.",
        "roleDenied": "An owner or finance admin with Stock enabled can capture and confirm these orders.",
        "uploadFailed": "The screenshots could not be uploaded. Try again.",
        "fileInvalid": "Choose a supported image file within the upload size limit.",
        "tooManyFiles": "Choose fewer screenshots and add the rest after saving this draft.",
        "captureSucceeded": "{count} orders saved to the draft",
        "cardTitle": "Grab order screenshots",
        "cardReview": "Review before confirming stock use",
        "cardCaptured": "Saved to your draft",
        "cardHeld": "Saved, with orders held for review",
        "cardFailed": "The orders could not be captured",
        "openReview": "Open order review",
        "keepAdding": "Keep adding screenshots until you are ready to Confirm.",
        "sourceDates": "{start} to {end}",
        "subtotal": "Subtotal",
        "discount": "Discount",
        "total": "Total",
        "currency": "Currency",
        "arithmeticConfirm": "I reviewed the screenshot amounts and confirmed the difference.",
        "conflictConfirm": "I reviewed the conflicting screenshots and confirmed this order.",
        "appendEvidence": "Attach to this order",
        "pairEvidence": "Choose the order shown in this screenshot",
        "removeOrder": "Remove order",
        "pairingHelp": "A printed slip without a Long Order ID must be paired with the merchant order screenshot. Pairing adds evidence only.",
        "noOrders": "No orders have been added to this draft yet.",
        "unavailable": "Order review could not be loaded. Refresh and try again.",
        "roleHelp": "An owner or finance admin with Inventory enabled must review and confirm.",
        "evidenceLoadFailed": "The order screenshot could not be loaded. Try again.",
        "selectStore": "Choose a Grab store",
        "newOrder": "Save as a new order",
        "extractFailed": "Could not read this screenshot. Check it shows a Grab order and try again.",
        "noFormula": "This product needs a formula before confirming.",
        "negativeStock": "Some ingredients would go below zero.",
        "confirmNegativeStock": "Confirm stock may go below zero",
        "formulaQuantity": "Quantity posted for this product",
        "duplicateOrder": "This Long Order ID is already captured. Attach its screenshot to the existing order instead.",
        "ambiguousMoney": "More than one posted money record matches. Resolve the money import before confirming.",
        "overlappingCounts": "These dates overlap quantities already posted from a manual or file batch. Reverse or correct that record before confirming.",
        "capacityHold": "This draft is too large. Finish a smaller draft and start another.",
        "conflictHeld": "The screenshots disagree. Review their identity and quantities before confirming.",
        "totalModifierHelp": "For total-piece wording, enter only the additional quantity beyond the product formula, then select Additional pieces.",
        "location": "Stock leaves from",
        "selectLocation": "Choose a stock location",
        "isPackaging": "This line is packaging",
        "pairOrders": "Attach this order’s screenshots to another order",
        "pairOrdersHelp": "Adds evidence to the chosen order and removes this duplicate draft order. No extra quantities are posted.",
        "pairOrdersConfirm": "Attach evidence and remove duplicate",
        "imageFormatHelp": "Use PNG or JPEG, up to 10 MB each. Convert HEIC or other formats before uploading.",
        "howItWorks": "How screenshot capture works",
        "refundCoverageUnknown": "Refund coverage needs review",
        "refundCoverageHelp": "The available money imports cannot prove whether this order was refunded later. Confirm whether it consumed ingredients; a money refund does not automatically restock food.",
        "inventoryNotManaged": "Screenshot stock posting requires inventory managed in Groot. Review the inventory settings before confirming.",
        "postingAccountMissing": "Configure the on-sale formula posting accounts in Products → Formulas before confirming.",
        "privateDraftHelp": "Screenshot drafts are reviewed from the account that owns their private conversation.",
        "createReplacement": "Create replacement draft",
        "replacementHelp": "Create a new draft from this reversed capture. Review it before confirming again; the reversed record stays in history.",
        "linkedChatDeleteDenied": "Keep this chat because recorded order evidence and replacement drafts are linked to it. The source record remains in {itemsSold}."
      },
      "overview": {
        "title": "Items sold",
        "description": "What each platform sold, by item and quantity. Posting relieves stock through the on sale formulas and books the cost of goods for the period.",
        "record": "Record items sold",
        "loading": "Loading items sold",
        "unavailable": "Items sold needs Stock to be managed in Groot and an owner or finance admin role.",
        "emptyTitle": "No items sold recorded yet",
        "emptyBody": "The platform reports carry the money, not the items. Record the quantities sold for a period here, type them in or upload a file, and posting takes them out of stock.",
        "columns": {
          "period": "Period",
          "platform": "Platform",
          "lines": "Lines",
          "relieved": "Relieved stock",
          "cost": "Cost of goods",
          "status": "Status"
        },
        "unmapped": "{count} to map",
        "noFormula": "{count} without formula",
        "period": "{start} to {end}"
      },
      "platforms": {
        "grabfood": "GrabFood",
        "foodpanda": "Foodpanda",
        "shopee": "Shopee",
        "pos": "POS",
        "other": "Other"
      },
      "status": {
        "draft": "Draft",
        "posted": "Posted",
        "reversed": "Reversed"
      },
      "lineStatus": {
        "pending": "Pending",
        "relieved": "Relieved",
        "no_formula": "No formula",
        "ignored": "Ignored",
        "unmapped": "Choose a product"
      },
      "record": {
        "title": "Record items sold",
        "description": "One record per platform and period. Each line is a platform item and how many were sold.",
        "platform": "Platform",
        "periodStart": "From",
        "periodEnd": "To",
        "location": "Stock leaves from",
        "locationPlaceholder": "Choose a location",
        "methodLabel": "How to enter the items",
        "method": {
          "manual": "Type in",
          "file": "Upload a file"
        },
        "productsUnavailable": "Sales Products could not be loaded, so lines cannot be matched yet. You can still record the counts and map them on the record.",
        "suggested": "Suggested from the name. Change it if it is wrong.",
        "cancel": "Cancel",
        "submit": "Save record",
        "created": "Recorded {count} items sold",
        "createdRemembered": "Recorded {count} items sold, {remembered} matched from earlier records",
        "manual": {
          "help": "Type the item name as the platform shows it and the quantity sold over the period. A name you mapped before is matched automatically next time.",
          "itemName": "Platform item",
          "itemNamePlaceholder": "e.g. Unagi Kabayaki Don",
          "quantity": "Qty sold",
          "product": "Sales Product",
          "productPlaceholder": "Search Sales Products",
          "noProductMatch": "No Sales Product matches",
          "removeRow": "Remove row {index}",
          "addRow": "Add a row",
          "quantityInvalid": "Quantity for {item} must be a positive number with at most three decimals."
        },
        "file": {
          "help": "Any CSV or Excel file with an item name column and a quantity column, such as the GrabMerchant Insights product export. Repeated names are added together.",
          "label": "File",
          "empty": "That file has no rows below its header.",
          "unreadable": "That file could not be read. Save it as CSV or Excel and try again.",
          "reading": "Reading the file",
          "nameColumn": "Item name column",
          "quantityColumn": "Quantity sold column",
          "pickColumn": "Choose a column",
          "unnamedColumn": "Column {index}",
          "summary": "{lines} items found, {mapped} matched to a Sales Product",
          "noLines": "No usable rows in those columns.",
          "skippedTitle": "{count} rows skipped",
          "skippedRow": "Row {row}: {reason}",
          "skippedMore": "{count} more",
          "skipReasons": {
            "NAME_MISSING": "no item name",
            "QUANTITY_INVALID": "quantity is not a number",
            "QUANTITY_NOT_POSITIVE": "quantity is zero or negative",
            "QUANTITY_TOO_PRECISE": "quantity has more than three decimals"
          }
        }
      },
      "batch": {
        "title": "Items sold",
        "subtitle": "{period} on {platform}",
        "loading": "Loading the record",
        "facts": {
          "lines": "Lines",
          "unmapped": "To map",
          "relieved": "Relieved stock",
          "noFormula": "No formula",
          "costPreview": "Cost of goods (preview)",
          "cost": "Cost of goods"
        },
        "viewJournal": "View journal entry",
        "viewReversal": "View reversal entry",
        "reversalReason": "Reversed: {reason}",
        "lineRef": "line {line}",
        "negativeTitle": "{count} stock items would go below zero",
        "negativeLine": "{item}: {available} available at {location}, {after} after posting",
        "columns": {
          "item": "Platform item",
          "quantity": "Qty sold",
          "product": "Sales Product",
          "relief": "Stock relief",
          "actions": "Actions"
        },
        "remembered": "Matched from an earlier record",
        "quantityFor": "Quantity sold of {item}",
        "ignoredLine": "Not a sale of stock",
        "useSuggestion": "Use {product}",
        "componentPreview": "{quantity} {unit} {item} ({cost})",
        "componentPosted": "{quantity} {unit} {item} at {cost}",
        "goesNegative": "Goes below zero",
        "addFormula": "Add a formula",
        "previewPending": "Working out the relief",
        "include": "Include",
        "ignore": "Ignore",
        "removeLine": "Remove {item}",
        "addLine": "Add line",
        "postHelp": "Posting takes the formula components out of stock at their average cost and books one cost of goods entry dated the end of the period. Lines without a formula are counted, not posted. Map or ignore every line first.",
        "delete": "Delete draft",
        "post": "Post stock relief",
        "reverse": "Reverse",
        "posted": "Relieved stock for {relieved} lines, cost of goods {cost}",
        "postedWithGaps": "Relieved stock for {relieved} lines, cost of goods {cost}. {missing} lines have no formula yet.",
        "insufficientStock": "Not enough stock on hand: {items}. Receive stock or change the negative stock policy under Stock settings.",
        "reversed": "Put {count} stock movements back, cost of goods {cost} reversed",
        "deleted": "Draft deleted",
        "negativeConfirmTitle": "Stock will go below zero",
        "negativeConfirmBody": "These sales take more than is on hand. Post anyway and the balance goes negative until stock is received.",
        "negativeConfirmAction": "Post anyway",
        "reverseTitle": "Reverse this record",
        "reverseBody": "Every stock movement is put back at the cost it left with, and the cost of goods entry is reversed. The record stays as evidence.",
        "reverseReason": "Reason",
        "reverseAction": "Reverse record",
        "journalDialogTitle": "Items sold journal entry"
      },
      "errors": {
        "generic": "That did not go through. Please try again.",
        "batchNotFound": "This record no longer exists.",
        "batchNotDraft": "A posted record cannot be edited. Reverse it instead.",
        "batchNotPosted": "Only a posted record can be reversed.",
        "batchVersionStale": "This record changed since you opened it. Close and reopen it.",
        "lineNotFound": "That line no longer exists.",
        "lineDuplicate": "That item is already on this record.",
        "linesRequired": "Add at least one item sold.",
        "linesUnmapped": "Choose a Sales Product for every line, or ignore the ones that are not sales of stock.",
        "noPostableLines": "There is nothing to post: every line is ignored.",
        "tooManyLines": "A record holds at most 500 lines. Split the period.",
        "itemNameRequired": "Every line needs the platform item name.",
        "quantityInvalid": "Quantity sold must be a positive number with at most three decimals.",
        "periodInvalid": "Choose a start and an end date.",
        "periodReversed": "The end date is before the start date.",
        "salesProductNotFound": "That Sales Product no longer exists.",
        "salesProductNotSelectable": "That item is not a Sales Product.",
        "locationRequired": "Choose the location stock leaves from.",
        "noActiveLocation": "Stock needs an active location first. Set one up under Products, Stock.",
        "insufficientStock": "Not enough stock on hand for these sales.",
        "negativeStockConfirm": "Available stock would go below zero. Confirm to post anyway.",
        "inventoryNotManaged": "Stock is not managed in Groot for this business, so nothing can be relieved.",
        "postingAccountMissing": "The cost of goods or inventory account is not set up. Choose them under Accounting, Chart of Accounts, Posting accounts.",
        "formulaBlocked": "One line has a formula that cannot post, for example two active formulas or a component that is no longer a Stock Item. Fix it on the Formulas page.",
        "reversalReasonRequired": "Say why this record is being reversed."
      }
    }
  },
  "columnPicker": {
    "label": "Columns",
    "dialogLabel": "Choose visible columns",
    "heading": "Visible columns",
    "shownCount": "{shown} of {total}",
    "reset": "Reset defaults",
    "exportNote": "Exports always include every column."
  },
  "businessSettings": {
    "chartOfAccounts": {
      "chart": {
        "title": "Chart of accounts",
        "description": "Every account this business posts to. Mark an account claimable to offer it as an expense category."
      },
      "posting": {
        "title": "Posting accounts",
        "description": "The control accounts the system posts to automatically: bank, payables, receivables. An expense claim credits one of these."
      },
      "rates": {
        "title": "Exchange rates",
        "description": "Rates used when a document is in a currency other than your home currency."
      }
    }
  },
  "creditNotes": {
    "page": {
      "title": "Credit Notes",
      "subtitle": "Credit notes your suppliers issued you, in one place."
    },
    "tabs": {
      "all": "All",
      "open": "Unapplied",
      "applied": "Applied"
    },
    "captureAction": "Capture supplier note",
    "outstandingTitle": "Unapplied credit",
    "outstandingHelp": "Money already credited back to you that no bill has taken off yet.",
    "loading": "Loading credit notes...",
    "unapplied": "Not applied",
    "noNumber": "No number",
    "supplierNoteNumber": "Supplier's number: {number}",
    "empty": {
      "title": "No credit or debit notes yet",
      "description": "Notes you raise on a customer's invoice and notes your suppliers send you both appear here. To record a note a supplier sent you, choose Capture supplier note."
    },
    "columns": {
      "date": "Date",
      "note": "Note",
      "party": "Supplier",
      "appliedTo": "Applies to",
      "amount": "Amount",
      "remaining": "Unapplied"
    },
    "source": {
      "apInvoice": "Purchase invoice",
      "businessExpense": "Other expense"
    },
    "capture": {
      "title": "Capture a supplier credit note",
      "subtitle": "Your supplier issued this document. Record it against a bill, or against the supplier if the bill has not arrived.",
      "modeLabel": "What this credit note applies to",
      "modeDocument": "Against a bill",
      "loading": "Loading bills...",
      "noDocuments": "No open bills to credit.",
      "account": "Account to credit",
      "currency": "Currency",
      "accountPlaceholder": "Choose an account",
      "accountHelp": "The account the original cost was booked to. The credit goes back to the same place.",
      "amount": "Amount",
      "date": "Credit note date",
      "reason": "Reason",
      "reasonPlaceholder": "Returned goods, overcharge, discount",
      "tooLarge": "That is more than the bill. The most you can credit is {amount}.",
      "cancel": "Cancel",
      "save": "Capture credit note",
      "successTitle": "Credit note captured",
      "successDescription": "{amount} credited from {party}.",
      "uploadTitle": "The credit note document",
      "uploadHelp": "Upload the credit note page. If it came merged with the invoice, upload just that page.",
      "ocrReviewTitle": "What we read from the credit note",
      "ocrNoteNumber": "Credit note: {number}",
      "ocrOriginalNumber": "Original document: {number}",
      "ocrOriginalDate": "Original document date: {date}",
      "ocrOriginalUuid": "Original document UUID: {uuid}",
      "ocrReason": "Reason: {reason}",
      "ocrSubtotal": "Subtotal: {amount}",
      "ocrTax": "Tax: {amount} ({rate}%)",
      "suggestionsTitle": "Suggested matches",
      "suggestionsLoading": "Finding possible matches",
      "matchReason_original_reference": "original reference matches",
      "matchReason_supplier": "same supplier",
      "suggestParty_ap_invoice": "Use vendor",
      "suggestParty_business_expense": "Use creditor",
      "noSuggestions": "No safe match found. Choose a bill or supplier below.",
      "uploadFailed": "That file could not be uploaded. Try again, or record the credit note without it.",
      "documentAttached": "Credit note document attached.",
      "blockedNoDocument": "Choose the bill this credit note is against.",
      "blockedNoParty": "Enter the supplier this credit note is from.",
      "blockedChooseListedParty": "Choose the supplier from your vendor list.",
      "blockedNoAccount": "Choose the account to credit.",
      "blockedInvalidCurrency": "Enter a three-letter currency code.",
      "blockedNoAmount": "Enter the credit note amount.",
      "blockedTooLarge": "The amount is more than the bill still owes.",
      "laneLabel": "What kind of document is this credit note against?",
      "modeParty_vendor_master": "Against a vendor",
      "modeParty_other_creditors": "Against a creditor",
      "party_vendor_master": "Vendor or supplier",
      "party_other_creditors": "Creditor",
      "partyPlaceholder_vendor_master": "Search your vendors and suppliers",
      "partyPlaceholder_other_creditors": "Who issued the credit note?",
      "findDocument_ap_invoice": "Which purchase invoice?",
      "findDocument_business_expense": "Which bill?",
      "findDocumentPlaceholder_ap_invoice": "Search by invoice number or vendor",
      "findDocumentPlaceholder_business_expense": "Search by number or supplier",
      "noParties": "No matches.",
      "noDocumentsForParty": "Nothing open for this party to credit.",
      "blockedNoDocumentForParty": "Now choose which of their documents this credits.",
      "partyFreeTextHint": "Not in the list? Type the name and we will still record it.",
      "defaultLineDescription": "Credit note",
      "lineItemsTitle": "Line items from the credit note",
      "lineItemsHelp": "Review what OCR read. Changes here are what will be posted.",
      "lineDescriptionColumn": "Description",
      "lineItemCodeColumn": "Item code",
      "lineDescription": "Line {row} description",
      "lineItemCode": "Item code: {code}",
      "lineQuantity": "Quantity",
      "lineUnit": "Unit",
      "lineUnitPrice": "Unit price",
      "lineTaxRate": "Tax %",
      "lineTotal": "Line total",
      "lineSubtotal": "Subtotal",
      "lineTax": "Tax",
      "lineGrandTotal": "Total",
      "addLineItem": "Add line item",
      "removeLineItem": "Remove line item {row}",
      "itemizedAmountHelp": "Calculated from the line items above.",
      "blockedInvalidLineItems": "Complete every line item before capturing the credit note.",
      "kindLabel": "Which note did the supplier send?",
      "kind": {
        "credit": {
          "label": "Supplier credit note",
          "hint": "Lowers what you owe them"
        },
        "debit": {
          "label": "Supplier debit note",
          "hint": "Adds to what you owe them"
        }
      },
      "readsAsCredit": "This document reads as a supplier credit note.",
      "switchToCredit": "Capture it as a credit note",
      "paperRejected": "Groot could not read this as a supplier credit note. If the supplier sent a debit note, switch to a debit note. You can also keep it attached and type the figures.",
      "switchToDebit": "Switch to debit note",
      "blockedUploading": "Wait for the document to finish uploading."
    },
    "lanes": {
      "purchaseInvoice": "Purchase invoice",
      "otherExpense": "Other expense"
    },
    "captureDebit": {
      "title": "Capture a supplier debit note",
      "subtitle": "Your supplier issued this document to charge more on a bill. Record it against that bill.",
      "uploadTitle": "The debit note document",
      "uploadHelp": "Upload the debit note page. If it came merged with the invoice, upload just that page.",
      "uploadFailed": "That file could not be uploaded. Try again, or record the debit note without it.",
      "documentAttached": "Debit note document attached.",
      "date": "Debit note date",
      "reasonPlaceholder": "Freight surcharge, price adjustment, under-billing",
      "noDocuments": "No posted bills to raise a debit note against. Post the bill first.",
      "blockedNoDocument": "Choose the bill this debit note is against.",
      "blockedNoAmount": "Enter the debit note amount.",
      "defaultLineDescription": "Debit note",
      "save": "Capture debit note",
      "successTitle": "Debit note captured",
      "successDescription": "{amount} added to what you owe {party}.",
      "paperNotRead": "Document attached. Groot reads supplier credit notes for you, but not debit notes yet, so type the amount, date and reason from the paper."
    }
  },
  "systemFlags": {
    "header": {
      "title": "Runtime kill switches",
      "subtitle": "Pause scheduled work without a deployment"
    },
    "accessDenied": {
      "title": "Access denied",
      "body": "This page is for Groot platform staff only."
    },
    "loading": "Loading runtime controls…",
    "superOnly": "Viewing and changing runtime kill switches requires the manage_platform_config capability (Super Admin).",
    "panelUnavailable": "This panel could not load. Reload the page to try again. If it keeps failing, ask the platform team to check the server logs.",
    "warning": {
      "title": "Production control",
      "body": "Changes apply to production work immediately. Confirm the exact scope, record an incident reason, and resume it explicitly when the incident is over."
    },
    "state": {
      "paused": "Paused",
      "running": "Running"
    },
    "scopes": {
      "cron": "All Convex cron dispatches",
      "scheduled": "All scheduled-intelligence EventBridge jobs",
      "browser": "All e-invoice browser automation, including active runs at their next safe checkpoint"
    },
    "control": {
      "title": "Change a switch",
      "body": "Select a global scope above or enter a specific job or business scope.",
      "scope": "Exact scope",
      "reason": "Incident reason",
      "reasonPlaceholder": "Required: incident, ticket, or operator decision",
      "pause": "Pause scope",
      "resume": "Resume scope",
      "keyHelp": "Valid keys: cron:*, cron:<job>, scheduled:*, scheduled:<function-path>, browser:*, or browser:<business-id>.",
      "scopeMode": "Scope type",
      "scopeModeKey": "Global or job scope",
      "scopeModeBusiness": "One business (browser automation)",
      "business": "Business",
      "businessHelp": "Pick the tenant from the list. Groot builds the flag key from its id, so a mistyped id can no longer create a row that pauses nothing.",
      "businessNone": "No business selected yet.",
      "resolvedKey": "Flag key: {key}"
    },
    "confirm": {
      "pause": "Pause {key} immediately? Running browser work stops at its next safe checkpoint.",
      "resume": "Resume {key} immediately? New matching work may start."
    },
    "toast": {
      "paused": "Paused {key}.",
      "resumed": "Resumed {key}."
    },
    "errors": {
      "required": "Scope and reason are required.",
      "failed": "The switch could not be changed. Check your access and exact scope.",
      "businessRequired": "Select a business before pausing a tenant scope."
    },
    "history": {
      "title": "Audit history",
      "empty": "No switch changes recorded yet.",
      "paused": "Paused",
      "resumed": "Resumed",
      "actor": "Operator {id}"
    },
    "pausedTenants": {
      "title": "Tenants paused right now",
      "body": "Every browser flag scoped to a single business, resolved to that business name.",
      "empty": "No individual tenant is paused. Global scopes are shown above.",
      "loading": "Resolving business names…",
      "unknown": "Unknown business",
      "unknownHint": "No business matches this id, so this flag pauses nothing. Resume it and pause the right tenant.",
      "idLabel": "Business id",
      "crossLever": "A tenant can also be stopped by an agent token revocation. If a tenant looks paused but is not listed here, check the agent token revocations panel below.",
      "unresolvedHint": "We could not resolve this business name. The directory list was truncated, so this id may still be a real tenant. Verify before resuming."
    },
    "revocations": {
      "title": "Agent token revocations",
      "body": "Deny one token, one agent, or a whole tenant. Every row expires on its own, and Lift ends it sooner.",
      "loading": "Loading agent token revocations…",
      "superOnly": "Viewing and changing agent token revocations requires the manage_platform_config capability (Super Admin).",
      "oneWay": {
        "title": "Revoking a business also stops its browser automation",
        "body": "A live business revocation pauses that tenant's e-invoice browser runs as well. The reverse is not true: pausing browser automation above leaves that tenant's agent tokens working."
      },
      "kindLabel": "What to deny",
      "kind": {
        "jti": "One token",
        "agent_epoch": "One agent",
        "business": "One business"
      },
      "kindHelp": {
        "jti": "Blocks a single token by its jti. The narrowest lever.",
        "agent_epoch": "Blocks every token issued to one agent, including tokens minted after this row.",
        "business": "Blocks every agent token for one tenant, and stops that tenant's browser automation."
      },
      "valueLabel": "Value",
      "valuePlaceholder": {
        "jti": "Token jti",
        "agent_epoch": "Agent id",
        "business": "Business id"
      },
      "ttlLabel": "Expires after",
      "ttlHelp": "The row expires on its own, so a forgotten revocation cannot keep a paying tenant switched off. Lift ends it sooner.",
      "ttl": {
        "1h": "1 hour",
        "24h": "24 hours",
        "7d": "7 days"
      },
      "reasonLabel": "Incident reason",
      "reasonPlaceholder": "Required: incident, ticket, or operator decision",
      "revoke": "Revoke access",
      "lift": "Lift",
      "liftReasonLabel": "Reason for lifting {value}",
      "liftReasonPlaceholder": "Required: why this revocation is being lifted",
      "confirmRevoke": "Revoke {kind} {value} for {ttl}? Agent access stops immediately.",
      "confirmLift": "Lift the revocation on {kind} {value}? Agent access resumes immediately.",
      "toastRevoked": "Revoked {value} until {expiry}.",
      "toastLifted": "Lifted the revocation on {value}.",
      "toastAlreadyClear": "Nothing to lift: {value} already had no revocation.",
      "errors": {
        "valueRequired": "Enter the token, agent, or business id to deny.",
        "reasonRequired": "Record a reason before changing a revocation.",
        "invalidTtl": "Choose one of the supported durations.",
        "notStaff": "This action needs the manage_platform_config capability (Super Admin).",
        "revokeFailed": "The revocation could not be saved. Check your access and the value you entered.",
        "liftFailed": "The revocation could not be lifted. Check your access and the value you entered."
      },
      "active": {
        "title": "Active revocations",
        "empty": "No agent token revocation is active.",
        "expires": "Expires {when}",
        "reason": "Reason: {reason}",
        "alsoBrowser": "Also stops browser automation",
        "createdBy": "Set by {id}"
      },
      "history": {
        "title": "Revocation history",
        "empty": "No revocation changes recorded yet.",
        "revoked": "Revoked",
        "lifted": "Lifted",
        "actor": "Operator {id}",
        "until": "until {when}"
      }
    },
    "lhdnFiling": {
      "title": "LHDN filing",
      "body": "Filing e-invoices with LHDN is off for every business. A business can file only while it is listed here and this deployment's LHDN settings are complete and agree with each other. Listing a business changes nothing until the settings are in place.",
      "loading": "Loading LHDN filing controls...",
      "superOnly": "Only Super Admins can change which businesses may file with LHDN.",
      "deployment": {
        "title": "This deployment",
        "unconfigured": "No LHDN settings are present, so no business can file. This is the default.",
        "incoherent": "The LHDN settings are incomplete or disagree, so no business can file. Settings to check: {switches}.",
        "test": "The settings are complete for LHDN's practice host. A listed business can file test documents.",
        "live": "The settings are complete for LHDN's production host. A listed business can file real documents."
      },
      "businessIdLabel": "Business name or id",
      "businessIdPlaceholder": "Type part of the business name, or paste the business id",
      "reasonLabel": "Reason",
      "reasonPlaceholder": "Required: why this business may file",
      "allow": "Allow filing",
      "revoke": "Stop allowing",
      "confirmAllow": "Allow {business} to file e-invoices with LHDN, and confirm TIN {tin} as belonging to it?",
      "confirmRevoke": "Stop allowing {business} to file e-invoices with LHDN?",
      "toastAllowed": "{business} may now file with LHDN.",
      "toastRevoked": "{business} may no longer file with LHDN.",
      "toastUnchanged": "Nothing changed: {business} was already in that state.",
      "list": {
        "title": "Businesses allowed to file",
        "empty": "No business is allowed to file, so nobody can file with LHDN.",
        "unnamed": "Unnamed business",
        "reason": "Reason: {reason}",
        "allowedAt": "Allowed {when}",
        "by": "by {id}",
        "tinConfirmed": "TIN confirmed: {tin}",
        "tinNotConfirmed": "No TIN confirmed yet"
      },
      "history": {
        "title": "History",
        "empty": "No changes yet.",
        "allowed": "Allowed",
        "revoked": "Stopped",
        "actor": "By {id}"
      },
      "errors": {
        "reasonRequired": "Enter a reason before changing the list.",
        "businessNotFound": "No business has that name or id. Check it and try again.",
        "demoWorkspace": "A demonstration workspace simulates e-invoicing and cannot be allowed to file.",
        "notMy": "Only businesses registered in Malaysia can be allowed to file with LHDN.",
        "notStaff": "You do not have permission to change this list.",
        "allowFailed": "We could not allow this business. Nothing was changed. Please try again.",
        "revokeFailed": "We could not stop allowing this business. Nothing was changed. Please try again.",
        "tinMissing": "This business has no LHDN TIN saved. Ask the owner to save it in e-invoice settings, then try again.",
        "tinHeldByOther": "Another business holds this TIN, so it cannot be confirmed. Nothing was changed.",
        "tinChangedSinceLookup": "The business's TIN changed after you looked it up. Look the business up again, check the new TIN, then confirm. Nothing was changed."
      },
      "tinNote": "Allowing a business confirms the TIN it has saved. On LHDN's production host it can file and check its connection only while that TIN is unchanged and no other business holds it.",
      "lookup": "Look up business",
      "confirmAgain": "Confirm current TIN",
      "preview": {
        "notFound": "No business has that id. Check the id and look it up again.",
        "tin": "TIN that will be confirmed: {tin}",
        "noTin": "This business has no TIN saved, so there is nothing to confirm. It cannot be allowed yet.",
        "heldByOther": "Another business holds this TIN, so it cannot be confirmed for this one.",
        "heldBy": "Held by {names}.",
        "heldByMore": "Held by {names} and {count} more.",
        "heldByAtLeast": "Held by {names} and at least {count} more.",
        "alreadyAllowed": "Already allowed. TIN confirmed: {tin}.",
        "alreadyAllowedUnconfirmed": "Already allowed, but no TIN was confirmed when it was allowed. Allow it again to confirm its TIN."
      },
      "search": {
        "title": "Pick the business you mean",
        "none": "No business has a name like that. Check the spelling, or paste the business id from the account page.",
        "narrow": "Showing the first {count} matches. Type more of the name to narrow it."
      },
      "binding": {
        "bound": "Bound to its TIN. It can file and check on the production host.",
        "no_tin": "Not bound: the business has no TIN saved.",
        "tin_not_held": "Not bound: no live business holds this TIN.",
        "tin_shared": "Not bound: another business holds the same TIN.",
        "not_allow_listed": "Not bound: the business is not allowed to file.",
        "not_confirmed": "Not bound: no TIN was confirmed when it was allowed. Confirm its current TIN.",
        "tin_changed": "Not bound: the business changed its TIN to {tin} since it was confirmed. Check the new TIN, then confirm it.",
        "unreadable": "Not bound: the binding could not be read just now."
      }
    }
  },
  "stockTake": {
    "title": "Stock-take",
    "subtitle": "Count your stock once a period and enter one total. Groot adjusts the books to match.",
    "form": {
      "title": "Record a count",
      "dateLabel": "Count date",
      "dateHelp": "The period end this count describes.",
      "valueLabel": "Counted stock value ({currency})",
      "valueHelp": "The total value of everything on hand. One number: no item list needed.",
      "noteLabel": "Note (optional)",
      "notePlaceholder": "e.g. Counted after the Sunday close",
      "submit": "Record stock-take"
    },
    "preview": {
      "loading": "Reading what the books currently carry…",
      "unavailable": "Could not read the current stock value just now. Nothing has been recorded. Try again in a moment.",
      "bookValue": "Books currently show",
      "priorCount": "Previous count",
      "difference": "Difference",
      "postingTarget": "Counter account: {accountName} ({accountCode}).",
      "explainCogs": "This difference adjusts your cost of sales, so gross profit reflects what you actually used.",
      "explainShrinkage": "Your stock is tracked per item, so this difference is recorded as a stock loss rather than cost of sales.",
      "explainBalanced": "Your count matches the books exactly. The count is still recorded as evidence, and nothing is posted.",
      "alreadyRecorded": "A stock-take is already recorded for {date}. Void it below before recording another.",
      "laterTakeExists": "A stock-take is already recorded for {date}, which is after this date. Counts are recorded in date order, so void that one first or count on a later date."
    },
    "toast": {
      "recordedTitle": "Stock-take recorded",
      "recordedBody": "The books were adjusted by {amount}.",
      "balancedTitle": "Count matches the books",
      "balancedBody": "The count was recorded. Nothing needed adjusting.",
      "failedTitle": "Could not record the stock-take",
      "failedBody": "Nothing was saved. Check the date is in an open period and try again."
    },
    "history": {
      "title": "Recorded stock-takes",
      "loading": "Loading stock-takes…",
      "emptyTitle": "No stock-takes yet",
      "emptyBody": "Record your first count above to set your opening stock value.",
      "date": "Count date",
      "counted": "Counted",
      "book": "Books showed",
      "adjustment": "Adjustment",
      "balanced": "No change",
      "status": "Status",
      "actions": "Actions",
      "void": "Void",
      "statusPosted": "Posted",
      "statusVoided": "Voided",
      "residual": "{amount} unexplained against a last count of {opening}."
    },
    "void": {
      "prompt": "Why is the stock-take for {date} being voided?",
      "reasonRequiredTitle": "A reason is required",
      "reasonRequiredBody": "Say why this count is being voided. The reason stays on the audit trail.",
      "doneTitle": "Stock-take voided",
      "doneBody": "Its adjustment was reversed. You can now record a corrected count for that date.",
      "failedTitle": "Could not void the stock-take",
      "failedBody": "Nothing was changed. The period may be closed."
    },
    "howItWorks": {
      "trigger": "How stock-takes work",
      "title": "How stock-takes work",
      "intro": "A stock-take is the simple way to account for stock without tracking every Stock Item. Count what you have, enter one total, and your cost of sales corrects itself.",
      "step1": "Count everything on hand at the period end and add up what it cost you.",
      "step2": "Enter that one total here with the count date.",
      "step3": "Groot moves your stock value to match and adjusts cost of sales by the difference.",
      "balancedTerm": "When your count matches the books",
      "balancedMeaning": "Nothing is posted, because nothing needs correcting. The count is still saved as evidence that you performed it.",
      "spoilageTerm": "Why there is no separate spoilage figure",
      "spoilageMeaning": "A periodic count measures everything that left your shelves (sold, eaten or thrown away) and cannot tell them apart. A spoilage number would have to be recorded as it happens, not derived from a count.",
      "correctionTerm": "If you counted wrong",
      "correctionMeaning": "A recorded stock-take is part of your accounts, so it is not edited. Void it with a reason (which reverses its adjustment) and record a corrected count.",
      "residualTerm": "The books and your last count do not agree",
      "residualMeaning": "Cost of sales is worked out from your last count. The entry that corrects your books is worked out from the Inventory account itself. Those are normally the same figure, and when they are not, something other than a count moved your Inventory account. Groot shows you by how much. It is not an error, and it does not stop you recording the count."
    },
    "errors": {
      "invalidDate": "Pick the count date first. Nothing was saved.",
      "invalidCountedValue": "The counted value has to be a number of 0 or more. Nothing was saved.",
      "periodClosed": "That accounting period is closed, so nothing was saved. Reopen it on Accounting → Periods, or count into an open period.",
      "alreadyRecorded": "A stock-take is already recorded for that date. Void it below, then record the new count.",
      "outOfOrder": "A stock-take is already recorded on a later date, so this count would be out of order. Void the later one first, or count on a date after it.",
      "futureDate": "That count date is in the future. Choose today or an earlier date.",
      "postingAccountNotConfigured": "Your chart of accounts is missing an account this stock-take posts to. Add or designate it on Accounting → Chart of Accounts → Posting accounts, then try again.",
      "adjustmentAccountNotConfigured": "No inventory adjustments account is designated, so a stock loss cannot be posted. Designate one on Accounting → Chart of Accounts → Posting accounts, then try again.",
      "notFound": "That stock-take is no longer there. Refresh the page and try again.",
      "alreadyVoided": "That stock-take is already voided. Nothing was changed.",
      "voidReasonRequired": "Say why the count is being voided, in at least three characters.",
      "ledgerTooLarge": "This business has more posted history on its Inventory account than a single count can value. Contact support: at this volume a perpetual stock valuation is the right tool, not a periodic count.",
      "reliefProvenanceUnavailable": "Groot could not verify whether earlier Delivery Orders already posted cost of sales. Contact support before recording this stock take.",
      "inventoryAdminOnly": "Only an owner or finance admin can record or void a stock-take. Ask one of them to do it, or to give you access.",
      "inventoryNotManaged": "Another system is the source of truth for your stock, so Groot will not post a count into an inventory account that system owns. Nothing was saved. Record the count in that system, or set Source of truth to Groot in the Stock settings if Groot should value your stock.",
      "valueSeparator": "This field uses a full stop for cents and a comma only between thousands, like 1850.50 or 1,850.50.",
      "valueNotANumber": "Type the counted value as digits, like 1850.50.",
      "valueNegative": "A counted value cannot be negative. Type 0 if there is nothing on hand.",
      "periodInvalid": "That is not a valid date range. Check the period start and end dates.",
      "countSheetRequired": "A counted figure needs its count sheet. Attach one before recording the count.",
      "countSheetNotApplicable": "An estimated figure was not counted, so it cannot carry a count sheet.",
      "estimateProvenanceRequired": "An estimated figure has to record the sales and the margin it was estimated from.",
      "estimateNotApplicable": "A counted figure came from a count, so it cannot also carry an estimate.",
      "historyTooLarge": "There are too many recorded periods to place this one safely. Contact support.",
      "periodOverlaps": "This period overlaps a period you have already recorded.",
      "laterPeriodExists": "A later period is already recorded. Re-enter that period instead of this earlier one.",
      "malformedHistory": "One of your recorded periods has dates Groot cannot read. Contact support."
    },
    "inventoryDisabledNote": "Inventory tracking is turned off, so the per-item stock screens are hidden. A stock-take still works: it adjusts your books from one counted total. Change this in the Stock settings.",
    "evidence": {
      "legend": "Count sheet",
      "prompt": "Attach a photo or a scan of the sheet you counted from.",
      "attach": "Attach count sheet",
      "missing": "No count sheet",
      "required": "A counted figure needs its count sheet before it can be recorded.",
      "uploadFailedTitle": "The count sheet did not upload",
      "uploadFailedBody": "Nothing was attached, so try again."
    },
    "residual": {
      "title": "Your books and your last count do not agree",
      "body": "Your last recorded count closed at {opening}, but the Inventory account holds {book}. Something other than a count moved {amount}, and that amount lands in this period cost of sales.",
      "cause": "Usually an opening balance or a journal entry posted straight to the Inventory account. Nothing is blocked: record this count as normal, then look for that entry if the figure surprises you."
    },
    "valuation": {
      "title": "Valuation review",
      "instructions": "The attached sheet must support the quantities, unit costs and total entered. Review obsolete or damaged stock and net realisable value.",
      "method": "Cost method",
      "choose": "Choose a cost method",
      "specific_identification": "Specific identification",
      "fifo": "FIFO",
      "weighted_average": "Weighted average",
      "attestation": "I reviewed the sheet and valued stock at the lower of cost and net realisable value.",
      "required": "Review the valuation method and supporting sheet before posting.",
      "provisional": "Provisional estimate. A reviewed count is required before period close.",
      "movementTitle": "Inventory movement bridge",
      "movementBody": "Opening stock is {opening}. The ledger before this count holds {book}, a movement of {amount}.",
      "movementCause": "Review the inventory postings during this window if this movement is unexpected.",
      "window": "Valuation interval:",
      "windowHelp": "Opening stock, purchases and the movement bridge cover this entire interval. Skipped months are included after the previous count."
    }
  },
  "closingStock": {
    "title": "Closing stock",
    "subtitle": "Record what your stock is worth at the end of a period, so cost of sales and gross profit come out right.",
    "loading": "Working out your figures",
    "unavailable": "We could not read your stock figures just now. Reload the page to try again.",
    "submit": "Record closing stock",
    "noteLabel": "Note (optional)",
    "notePlaceholder": "Anything the next person should know about this count",
    "period": {
      "legend": "Which period is this?",
      "from": "Period starts",
      "to": "Period ends",
      "toHelp": "The date your stock figure describes. This is the date the entry is posted on.",
      "carriedForward": "The day after your last recorded count, {date}.",
      "firstPeriodHelp": "This is your first recorded count, so pick the day the period started.",
      "invalid": "Check the dates. The period has to start on or before it ends."
    },
    "closing": {
      "label": "Closing stock value ({currency})",
      "help": "One number: what all the stock on hand is worth. No item list needed.",
      "unavailable": "Not available"
    },
    "derivation": {
      "legend": "How cost of sales works out",
      "opening": "Opening stock",
      "purchases": "Purchases in the period",
      "closing": "Closing stock",
      "costOfSales": "Cost of sales",
      "formula": "Opening stock plus purchases, less closing stock, is your cost of sales.",
      "firstPeriod": "None recorded",
      "notYet": "Not yet",
      "notAvailable": "Not available",
      "purchasesUnavailable": "We could not total your purchases for this period, so cost of sales is not shown. Your stock figure still posts correctly.",
      "purchasesFrom": "Counted from {date}, the day after your last recorded period."
    },
    "ledger": {
      "balanceAt": "Inventory account balance at {date}",
      "willMoveBy": "This entry will move it by",
      "noEntryNeeded": "Nothing to post. Your Inventory account already holds this value.",
      "explainCogs": "The difference goes to cost of sales. Stock you bought but have not used yet is not this period cost.",
      "explainShrinkage": "The difference goes to inventory adjustments. Your stock records are kept item by item, so a count that disagrees with them is a loss."
    },
    "basis": {
      "legend": "How did you get this figure?",
      "counted": "Counted",
      "countedHelp": "You counted the stock and have a count sheet to attach.",
      "countedBadge": "Counted",
      "estimated": "Estimated",
      "estimatedHelp": "Worked out from your sales and your usual gross margin.",
      "estimatedBadge": "Estimated",
      "unrecordedBadge": "Not recorded",
      "estimatedDetail": "Estimated from {sales} of sales at a {pct} gross margin, {start} to {end}.",
      "unavailableNoSales": "No sales in this period, so we cannot estimate from your margin.",
      "unavailableNoHistory": "We need at least one counted period before we can estimate from your margin.",
      "unavailableNegative": "That margin implies negative stock. Count it, or check your purchases for this period.",
      "unavailableExceeds": "That margin implies more stock than you ever held this period. Count it instead.",
      "unavailableOther": "We cannot estimate from your margin for this period. Count the stock."
    },
    "conflict": {
      "alreadyRecorded": "A stock figure is already recorded for {date}.",
      "laterPeriod": "A later period is already recorded, ending {date}. Recording this one would change what that count was measured against.",
      "periodOverlaps": "This period overlaps a period you have already recorded.",
      "laterPeriodRecorded": "A later period is already recorded, so recording this earlier one would change what that count was measured against.",
      "malformedHistory": "One of your recorded periods has dates Groot cannot read. Contact support.",
      "historyTooLarge": "There are too many recorded periods to place this one safely. Contact support.",
      "placementGeneric": "This period cannot be placed against the ones you have already recorded."
    },
    "history": {
      "title": "Recorded periods",
      "period": "Period",
      "range": "{start} to {end}",
      "basis": "Basis",
      "closing": "Closing stock",
      "book": "Books said",
      "adjustment": "Adjustment",
      "countSheet": "Count sheet",
      "status": "Status",
      "balanced": "Agreed",
      "statusPosted": "Posted",
      "statusVoided": "Voided",
      "emptyTitle": "No closing stock recorded yet",
      "emptyBody": "Record your first period end and it will appear here.",
      "document": "Document",
      "noDocument": "Nothing posted",
      "entryNoNumber": "Journal entry",
      "voucherVoid": "Void",
      "voucherNoNumber": "No number",
      "costOfSales": "Cost of sales"
    },
    "toast": {
      "recordedTitle": "Closing stock recorded",
      "recordedBody": "Your Inventory account was adjusted by {amount}.",
      "balancedTitle": "Closing stock recorded",
      "balancedBody": "Nothing needed posting: your Inventory account already held this value.",
      "failedTitle": "Could not record the closing stock",
      "failedBody": "Nothing was saved. Check the dates are in an open period and try again."
    },
    "howItWorks": {
      "trigger": "How closing stock works",
      "title": "How closing stock works",
      "intro": "If you do not track stock item by item, your purchases go straight to cost of sales. That overstates cost in the months you stock up. Recording what is left at period end fixes it.",
      "step1": "Set the period. It starts the day after your last recorded count.",
      "step2": "Say whether you counted the stock or estimated it from your margin.",
      "step3": "Enter what the stock on hand is worth, and attach the count sheet if you counted it.",
      "step4": "Record it. Groot adjusts your Inventory account and cost of sales follows.",
      "countedTerm": "Counted",
      "countedMeaning": "Someone walked the shelves and priced what is there. The count sheet is the evidence, so it is required.",
      "estimatedTerm": "Estimated",
      "estimatedMeaning": "Worked back from your sales and your usual gross margin. There is no count sheet by construction, and every estimate is labelled as one wherever it appears.",
      "balancedTerm": "Nothing posted",
      "balancedMeaning": "Your count agreed with the books to the cent. That is the reconciliation succeeding, and the count is still recorded as evidence.",
      "correctionTerm": "Fixing a recorded period",
      "correctionMeaning": "A recorded period cannot be edited, because it has already posted to the ledger. Void it from Products, Stock take, and record it again.",
      "voidNote": "Recorded periods are read-only here. To reverse one, open Products, then Stock take.",
      "voucherTerm": "Voucher",
      "voucherMeaning": "Recording a period posts a journal entry and stamps it with a JV number. That number is the document: click the pill to open the voucher itself and print it.",
      "entryOnlyTerm": "Journal entry number only",
      "entryOnlyMeaning": "A period recorded before Groot started numbering these has a journal entry but no voucher, so the row shows the entry number rather than a document it never had.",
      "noDocumentTerm": "Nothing posted, so no document",
      "noDocumentMeaning": "When the figure agreed with the books there was nothing to post, so there is no journal entry and no voucher to open. The period is still recorded as evidence that it was checked."
    }
  },
  "expenseClaimCapture": {
    "title": "Snap a receipt",
    "subtitle": "Take a photo and Groot reads the amount, vendor and date for you.",
    "photograph": "Take photo",
    "chooseFile": "Choose a file",
    "submit": "Submit claim",
    "submitting": "Submitting...",
    "receiptRequired": "A receipt is required. Take a photo to continue.",
    "captureFailed": "We could not open the camera. Check that Groot has camera access in Settings, then try again.",
    "submitFailed": "We could not submit the claim. Check your connection and try again.",
    "submitted": "Claim submitted",
    "submittedDetail": "Groot is reading the receipt. It will appear in Your claims when it is done.",
    "done": "Done",
    "rejection": {
      "unsupported_type": "That file type is not supported. Use a photo (JPEG, PNG or WebP) or a PDF.",
      "too_large": "That file is too large. The limit is 50 MB.",
      "empty": "That file is empty."
    }
  },
  "expenseClaimList": {
    "title": "Your claims",
    "subtitle": "Everything you have filed, newest first.",
    "emptyTitle": "No claims yet",
    "emptyBody": "Snap a receipt and Groot reads the amount, vendor and date for you.",
    "emptyAction": "Snap a receipt",
    "loadFailed": "We could not load your claims. Check your connection and try again.",
    "retry": "Try again",
    "untitledClaim": "Untitled claim",
    "amountPending": "Reading amount...",
    "datePending": "Reading date...",
    "notRead": "Not read",
    "noReceipt": "No receipt",
    "needsActionOne": "1 claim needs you",
    "needsActionMany": "{count} claims need you",
    "lane": {
      "reading": "Reading receipt",
      "needsReview": "Check and submit",
      "inReview": "Waiting for approval",
      "settled": "Done",
      "rejected": "Sent back",
      "failed": "Could not read"
    }
  },
  "expenseClaimDetail": {
    "title": "Claim",
    "whatGrootRead": "What Groot read",
    "vendor": "Vendor",
    "amount": "Amount",
    "date": "Date",
    "purpose": "Purpose",
    "notRead": "Not read",
    "stillReading": "Still reading...",
    "receiptHeading": "Receipt",
    "receiptLoading": "Loading receipt...",
    "receiptUnavailable": "The receipt could not be loaded. Check your connection and try again.",
    "noReceipt": "No receipt was attached to this claim.",
    "filedOn": "Filed",
    "edit": "Edit",
    "editClaim": "Edit claim",
    "saveChanges": "Save changes",
    "cancel": "Cancel",
    "saving": "Saving...",
    "editFailed": "We could not save your changes. Check your connection and try again.",
    "invalidAmount": "Enter a valid amount.",
    "invalidCurrency": "Enter a three-letter currency code.",
    "invalidDate": "Enter a valid date as YYYY-MM-DD.",
    "currency": "Currency",
    "dateFormat": "YYYY-MM-DD",
    "categoryPlaceholder": "Choose category",
    "noCategory": "No category",
    "editLineItems": "Edit line items",
    "addLineItem": "Add line item",
    "removeLineItem": "Remove",
    "addCharge": "Add charge",
    "chargeLabel": "Charge",
    "invalidLineItem": "Complete each line item with a description and valid amounts.",
    "invalidCharge": "Complete each charge with a label and valid amount.",
    "submit": "Submit claim",
    "submitAnyway": "Submit anyway",
    "submitFailed": "We could not submit this claim. Check your connection and try again.",
    "duplicateFound": "A matching submitted claim was found. Explain why this is not a duplicate to continue.",
    "duplicateOverrideReason": "Why is this not a duplicate?",
    "duplicateOverrideRequired": "Explain why this claim is not a duplicate before continuing.",
    "deleteClaim": "Delete claim",
    "confirmDelete": "Delete permanently",
    "deleteWarning": "This permanently removes the draft claim and cannot be undone.",
    "deleteFailed": "We could not delete this claim. Check your connection and try again.",
    "documents": "Documents",
    "replaceReceipt": "Replace receipt",
    "addSupportingDocument": "Add supporting document",
    "removeDocument": "Remove",
    "supportingDocument": "Supporting document",
    "noSupportingDocuments": "No supporting documents.",
    "documentFailed": "We could not update the documents. Check your connection and try again.",
    "exchangeRate": "Exchange rate",
    "manualExchangeRate": "Exchange rate override",
    "invalidExchangeRate": "Enter a valid exchange rate greater than zero. If you do not have one, add the rate on Accounting → Chart of Accounts.",
    "suggestionsHeading": "Groot found updates",
    "acceptSuggestion": "Accept",
    "rejectSuggestion": "Keep mine",
    "back": "Back to claims"
  },
  "chatAgent": {
    "title": "Ask Groot",
    "subtitle": "Your books, in plain language.",
    "placeholder": "Ask about your business...",
    "send": "Send",
    "thinking": "Groot is thinking...",
    "emptyTitle": "Ask me anything about your business",
    "emptyBody": "Try \"how much did I spend last month\" or \"who owes me money\".",
    "sendFailed": "We could not send that. Check your connection and try again.",
    "streamFailed": "Groot stopped part way through. Your question was saved; try again.",
    "rateLimited": "You have reached the message limit for this hour. Try again shortly.",
    "retry": "Try again",
    "youLabel": "You",
    "agentLabel": "Groot",
    "confirmTitle": "Confirm this step",
    "confirmFallbackMessage": "This step is waiting for your confirmation.",
    "confirmButton": "Confirm",
    "cancelButton": "Cancel",
    "confirmWorking": "Working on it...",
    "confirmedBadge": "Confirmed",
    "cancelledBadge": "Cancelled",
    "confirmTranscript": "Confirmed. Go ahead.",
    "cancelTranscript": "Cancel that step.",
    "valueYes": "Yes",
    "valueNo": "No",
    "cardOpenOnWeb": "Open Groot on the web to see this.",
    "cardFinishOnWeb": "Open Groot on the web to finish this step."
  },
  "openingBalance": {
    "title": "Opening balance",
    "subtitle": "Bring the balances from your old system across, so your books here start from where they really are.",
    "loading": "Working on it",
    "unavailable": "We could not read that just now. Reload the page to try again.",
    "date": {
      "legend": "When do you go live on Groot?",
      "label": "First day on Groot",
      "help": "Everything before this day belongs to your old system. The entry is dated the day before.",
      "invalid": "Pick a real date, spelled year to month to day.",
      "asAt": "The entry will be dated {date}, the day before you go live."
    },
    "chart": {
      "legend": "Step 1. Download your own chart",
      "download": "Download chart as CSV",
      "downloading": "Preparing your file",
      "scanned": "We read {count} rows from your chart of accounts.",
      "exported": "{count} accounts are in the file, ready for you to fill in.",
      "skippedHeadings": "{count} were left out because they are headings, and a heading takes no postings.",
      "skippedInactive": "{count} were left out because they are archived.",
      "nothingSkipped": "Nothing was left out.",
      "controlsAr": "Leave {code} blank. Customer balances are entered one customer at a time in step 3.",
      "controlsAp": "Leave {code} blank. Supplier balances are entered one supplier at a time in step 3.",
      "unavailable": "We could not read your chart of accounts just now, so there is no file to download yet. Reload the page to try again.",
      "templateNote": "Leave blank. Itemised per customer or supplier."
    },
    "source": {
      "legend": "Step 2. Fill it in, then bring it back",
      "uploadCta": "Upload the filled file",
      "uploadHelp": "CSV, XLSX or XLS. A trial balance exported from your old system works too.",
      "manualCta": "Type the balances here instead",
      "manualHelp": "Better for a short chart. Blank means you have not answered yet, not zero.",
      "fileName": "From {name}",
      "clear": "Start over",
      "readNothing": "We could not find any account rows in that file. Check it is the trial balance, and that it still has its heading row.",
      "readFailed": "We could not read that file. Try saving it as CSV and uploading it again.",
      "rowsRead": "We read {count} account rows.",
      "rowsRejected": "{count} rows could not be read. Each one is listed below.",
      "statedDate": "The file says it is as at {date}.",
      "statedDateAmbiguous": "The file says it is as at {date}. That date could be read two ways, so check it against the day you picked.",
      "statedDateMismatch": "The file says it is as at {date}, which is not the day before the date you picked. Check which one is right."
    },
    "manual": {
      "legend": "Your accounts",
      "code": "Code",
      "name": "Account",
      "type": "Type",
      "debit": "Debit",
      "credit": "Credit",
      "itemised": "Itemised in step 3",
      "invalidCell": "Some amounts could not be read. Numbers only, with an optional decimal point.",
      "filled": "You have filled in {count} of {total} accounts."
    },
    "parties": {
      "legend": "Step 3. Who owes you, and who you owe",
      "help": "Add one line for each unpaid customer or supplier invoice. We add them up and post the control account total, so your aged reports and balance sheet agree from day one.",
      "add": "Add a line",
      "side": "Side",
      "sideAr": "A customer owes us",
      "sideAp": "We owe a supplier",
      "who": "Who",
      "amount": "Outstanding",
      "reference": "Reference (optional)",
      "referencePlaceholder": "Their old invoice number",
      "remove": "Remove this line",
      "empty": "Nothing itemised yet. Add a line for each unpaid invoice you are carrying over.",
      "chooseCustomer": "Choose a customer",
      "chooseVendor": "Choose a supplier",
      "noDirectory": "Add your customers and suppliers first, then come back and itemise what they owe.",
      "invalidAmount": "Some outstanding amounts could not be read. Numbers only.",
      "duplicate": "Each historical invoice for the same customer or supplier needs a distinct document reference.",
      "derivedAr": "Customers total, posting to {code}",
      "derivedAp": "Suppliers total, posting to {code}",
      "derivedNoControl": "We could not work out which account these belong to. Set your receivables and payables accounts on Payment & posting, then preview again.",
      "count": "{count} itemised.",
      "issueDate": "Issue date",
      "dueDate": "Due date",
      "currency": "Currency",
      "nativeAmount": "Native amount",
      "nativeAmountPlaceholder": "Optional for home currency",
      "exchangeRate": "Exchange rate",
      "exchangeRatePlaceholder": "Required when currency differs from home currency",
      "rateDate": "Rate date"
    },
    "preview": {
      "cta": "Preview what will post",
      "running": "Working out what will post",
      "legend": "Step 4. Check it, then post it",
      "asAt": "Entry date {date}",
      "totalDebit": "Total debit",
      "totalCredit": "Total credit",
      "difference": "Difference",
      "balanced": "Your trial balance foots. No balancing line is needed.",
      "postedTotals": "What will post, balancing line included: {debit} debit and {credit} credit.",
      "lineCount": "{count} lines will post.",
      "residualLegend": "The balancing line",
      "residualTo": "{amount} goes to {account}, so the entry balances.",
      "residualNoAccount": "Your trial balance does not foot, and we have no account to put the difference in. Designate one on Payment & posting, then preview again. Nothing has been posted.",
      "noResidual": "None needed.",
      "stale": "Something changed since you previewed. Preview again before posting.",
      "notRunYet": "Preview it to see exactly what will land on your books."
    },
    "issues": {
      "legend": "Before you post",
      "blocking": "Stops the posting",
      "notice": "Worth knowing",
      "row": "Row {row}",
      "account": "Account {code}",
      "value": "Cell reads {value}",
      "columns": "Columns found: {columns}",
      "entity": "Record {entity}",
      "clean": "Nothing needs your attention."
    },
    "existing": {
      "legend": "A cutover is already posted",
      "body": "{entry} is already on your books, dated {date}.",
      "replaceNote": "Posting again REPLACES it: we reverse that entry on its own date and post the new one, in one step. Your books never hold both."
    },
    "post": {
      "cta": "Post the opening balance",
      "ctaReplace": "Replace the posted opening balance",
      "posting": "Posting",
      "blocked": "Sort out the items above first. Nothing has been posted.",
      "previewFirst": "Preview it first, so you can see exactly what will land.",
      "replaceReasonLabel": "Reason for replacing the opening balance",
      "replaceReasonPlaceholder": "Explain why the posted cutover must be replaced",
      "replaceReasonRequired": "Enter a reason before replacing the opening balance."
    },
    "toast": {
      "postedTitle": "Opening balance posted",
      "postedBody": "{entry} is on your books, dated {date}.",
      "replacedTitle": "Opening balance replaced",
      "replacedBody": "The previous entry was reversed and {entry} posted, dated {date}.",
      "failedTitle": "Nothing was posted",
      "failedBody": "We could not post that opening balance. Nothing was changed. Please try again."
    },
    "residualLine": "Opening balance carried over from the previous system",
    "howItWorks": {
      "trigger": "How this works",
      "title": "How the opening balance works",
      "intro": "A cutover is one journal entry dated the day before you go live. It carries every balance from your old system across in one go, so nothing here has to be re-entered.",
      "step1": "Download your own chart of accounts as a CSV. It is your chart, not a generic template, so every code already matches.",
      "step2": "Fill in the debit or credit for each account in a spreadsheet, then upload it back. A short chart can be typed in here instead.",
      "step3": "Itemise what each customer owes you and what you owe each supplier. We add those up and post the control account total for you.",
      "step4": "Preview it. You see every line, the footing, and where any difference goes, before anything touches your books.",
      "blankTerm": "A blank cell",
      "blankMeaning": "Means you have not answered yet. It is not zero. A typed zero says the account really is nil, and we keep the two apart.",
      "itemisedTerm": "Itemised, not a lump sum",
      "itemisedMeaning": "We do not accept one total on the receivables or payables control. Without the names behind it, your aged report shows nothing while your balance sheet shows a figure, and no one can ever reconcile the two.",
      "residualTerm": "The balancing line",
      "residualMeaning": "If your trial balance does not foot, the difference goes to one account so the entry balances. We show you which account and how much before you post.",
      "replaceTerm": "Posting a second time",
      "replaceMeaning": "You cannot post two cutovers. A second posting reverses the first one and replaces it in one step, so your books never hold both.",
      "documentTerm": "No voucher number",
      "documentMeaning": "A cutover carries no voucher. It is not a payment or a document somebody signs, it is the point your books start from, so it is identified by its journal entry number alone.",
      "settingsLink": "The account any difference goes to is set on Payment & posting."
    },
    "issue": {
      "headerRowNotFound": "We could not find the heading row in that file, so we do not know which column holds what. Download the file above and fill that in instead.",
      "nameColumnNotFound": "That file has no account name column. We match on the code, so this is only a readability loss.",
      "amountColumnsAmbiguous": "That file offers more than one pair of amount columns and we will not guess. Export just the opening balance columns, or use the file above.",
      "amountColumnsPeriodActivity": "The only amount columns in that file are a period movement, not an opening balance. A period total foots perfectly and is the wrong figure.",
      "amountColumnPairIncomplete": "That file has a debit column without its credit column, or the other way round. Both are needed.",
      "unparseableAmount": "We could not read the amount in this cell, so nothing was taken from it.",
      "bothDrAndCr": "This row carries a debit and a credit. One account, one side. Put the net figure on the side it belongs to.",
      "duplicateCode": "This account code appears more than once in the file. Combine the rows.",
      "totalsRowSkipped": "This looked like a totals row, so it was skipped. Importing it would double every figure.",
      "nonAccountRowSkipped": "This row carries no account code, so it was skipped.",
      "unknownCode": "This code is not in your chart of accounts. Add the account, or take the row out.",
      "headingNotPostable": "This account is a heading. Put the figure on the accounts underneath it.",
      "arApControlTypedDirectly": "This is your customer or supplier control account, and an amount was typed straight onto it. Leave it blank and itemise the balances in step 3 instead.",
      "zeroRowIgnored": "This row is zero on both sides, so nothing will post for it.",
      "conversionDateInvalid": "Pick the day you go live before previewing.",
      "residualAccountNotConfigured": "Your trial balance does not foot, and no account is set to take the difference. Designate one on Payment & posting.",
      "residualAccountNotPostable": "The account set to take the difference is a heading, so nothing can post to it. Point that setting at a real account on Payment & posting.",
      "partyControlNotResolved": "We could not work out which control account these customer or supplier balances belong to. Set your receivables and payables accounts on Payment & posting.",
      "partyDuplicateEntity": "Each historical invoice for the same customer or supplier needs a distinct document reference.",
      "noPostableLines": "Nothing here would post. Fill in at least one balance first.",
      "unknown": "Something about this row needs attention and this page does not recognise it yet ({code}). Reload the page, and tell us if it is still here.",
      "priorActivityOverlap": "This account already has posted activity before go-live. Posting its full opening balance could count that activity twice. Reconcile the earlier entries before posting.",
      "priorActivityOtherAccounts": "Other accounts have posted activity before go-live. Check that your opening trial balance includes everything you intend to carry over.",
      "priorActivityScanIncomplete": "There is too much earlier history to check safely in this preview. Nothing can be posted. Contact support to review the cutover.",
      "replacementReconciliationDependency": "The opening balance is matched to a bank transaction. Unmatch it in Bank reconciliation before replacing it, then review and match the replacement.",
      "replacementSettlementDependency": "An opening invoice has settlement history, so this opening balance cannot be replaced. Post an adjustment instead. If the cutover period is closed, ask your accountant to post the adjustment in an open period.",
      "replacementStockDependency": "Posted stock counts depend on these opening books, so an opening balance cannot be posted or replaced. In Accounting > Closing stock, void the affected counts from newest to oldest, then post the opening balance and record the counts again. If a period is closed, ask your accountant for an adjustment.",
      "replacementDependencyScanIncomplete": "There is too much dependency history to check replacement safely. Nothing can be posted. Contact support to review the opening balance.",
      "partyReferenceTooLong": "Document references can be no more than 200 characters.",
      "partyCurrencyInvalid": "Use a supported three-letter uppercase currency code, such as USD.",
      "partyIssueDateInvalid": "Enter a real issue date in year-month-day format.",
      "partyDueDateInvalid": "Enter a real due date in year-month-day format.",
      "partyRateDateInvalid": "Enter a real exchange-rate date in year-month-day format.",
      "partyIssueDateAfterCutover": "The issue date cannot be after the opening balance date.",
      "partyRateDateAfterCutover": "The exchange-rate date cannot be after the opening balance date."
    },
    "errors": {
      "alreadyPosted": "An opening balance is already posted for this business, so nothing was posted. Reload the page to replace it instead.",
      "notPosted": "There is no posted opening balance to replace, so nothing was changed. Reload the page and try again.",
      "notPostable": "This opening balance cannot be posted yet, so nothing was posted. Sort out the items listed on the page and try again.",
      "previewStale": "Your chart of accounts or your customer records changed since you previewed, so nothing was posted. Preview it again to see what would land now.",
      "partyNotFound": "Some of the customers or suppliers on this opening balance are no longer in your records, so nothing was posted. Reload the page and try again.",
      "tooManyRows": "That file has more account rows than an opening balance can carry, so nothing was imported. The file above is built from your own chart, so a file this large did not come from it. Check you are uploading the trial balance and not a transaction listing.",
      "tooManyParties": "That is more customers and suppliers than can go into one entry, so nothing was imported. Please contact support so we can stage the outstanding documents for you.",
      "controlMismatch": "The customer and supplier balances do not add up to the control account total we were about to post, so nothing was posted. Please contact support.",
      "entryMissing": "The opening balance entry recorded for this business can no longer be found, so nothing was changed. Please contact support.",
      "entryNotPosted": "The opening balance entry recorded for this business is no longer posted, so there is nothing to replace. Nothing was changed. Please contact support.",
      "previewRequired": "Preview the opening balance before posting it, so you can see exactly what will land on your books.",
      "residualAccountNotConfigured": "No account is set to take the difference on an opening balance, so nothing was posted. Designate one on Payment & posting, then try again.",
      "generic": "We could not post that opening balance. Nothing was changed. Please try again.",
      "fxRateMissing": "This foreign-currency opening item needs an exchange rate. Add one on the Exchange rates card in Accounting → Chart of Accounts.",
      "fxInvalid": "The opening item currency amount and exchange rate must be valid positive numbers.",
      "fxHomeMismatch": "The foreign amount and home-currency amount do not agree with the exchange rate."
    },
    "posted": {
      "legend": "Your opening balance is posted",
      "body": "{entry} is on your books, dated {date}.",
      "summary": "{count} lines posted, {debit} debit and {credit} credit.",
      "replaced": "The previous opening balance {entry} was reversed on its own date, so your books never hold both.",
      "replacedUnnamed": "The opening balance that was there has been reversed on its own date, so your books never hold both."
    }
  },
  "salesInvoiceAttribution": {
    "title": "Reporting attribution",
    "description": "Tag this invoice for management reporting. This changes reports only. The issued document, its amounts and its accounts stay exactly as posted, and no new document is created.",
    "save": "Save attribution",
    "saving": "Saving",
    "nothingToSave": "Pick a different value to save.",
    "toast": {
      "savedTitle": "Attribution saved",
      "savedDescription": "Management reports now use the new tags. Posted ledger lines re-tagged: {lines}.",
      "saveFailedTitle": "Could not save the attribution",
      "saveFailedDescription": "The attribution was not saved and nothing on this invoice changed. Please try again."
    }
  },
  "receiptMatching": {
    "modeManual": "I know which invoice(s)",
    "modeAuto": "Let Groot match automatically",
    "formTitle": "Record an unmatched receipt",
    "formIntro": "We'll try to match this payment to an invoice by its reference. If we can't, we'll ask the customer which invoice(s) it covers.",
    "currencyLabel": "Currency",
    "depositToAccountLabel": "Deposited to",
    "referencePlaceholder": "e.g. bank reference or invoice number",
    "referenceHelp": "If this mentions an invoice number, we'll match it automatically.",
    "previewLabel": "Recording a receipt of {amount}",
    "recording": "Recording...",
    "recordButton": "Record receipt",
    "result": {
      "matchedTitle": "Matched automatically",
      "matchedMessage": "This receipt was matched to invoice {invoice} by its reference.",
      "pendingTitle": "We've asked the customer",
      "pendingMessage": "We couldn't match this receipt by reference, so we emailed the customer to ask which invoice(s) it covers. They have until {date} to reply."
    },
    "errors": {
      "alreadyPending": "This customer already has an unmatched receipt awaiting their reply."
    },
    "tierBadge": {
      "reference": "Matched by reference",
      "self_select": "Customer selected",
      "fifo": "Auto-matched (oldest first)"
    },
    "notesLabel": "Notes (internal)",
    "notesPlaceholder": "Optional note for your team"
  },
  "officialReceiptSettings": {
    "title": "Official Receipts",
    "subtitle": "Control how Official Receipts are issued and sent",
    "toggleLabel": "Issue Official Receipts",
    "toggleHelp": "On by default. Each payment you record as received, in the currency it was received in, gets one numbered Official Receipt, and so does a cash sale when it is posted. A post-dated cheque or GIRO gets its receipt when it clears. If the customer already holds a receipt from another system, record that reference instead and Groot issues none. Each receipt records how the money was confirmed, such as by you or matched to a bank line, and shows it on internal screens only. Turning this off stops new Official Receipts; receipts already issued keep their numbers.",
    "ownerOnly": "Only a business owner can change this setting.",
    "saveError": "The Official Receipt setting could not be saved.",
    "state": {
      "defaultOn": "On (default)",
      "defaultOff": "Off (default)",
      "ownerOn": "On",
      "ownerOff": "Off"
    },
    "nextNumber": "Next number: {number}",
    "errors": {
      "nothingToChange": "Choose a setting to change."
    },
    "autoEmailLabel": "Email receipts automatically",
    "autoEmailHelp": "Off by default. When on, each Official Receipt is emailed to the payer as a PDF when it is issued, if the payer has an email address on file. You can always send a receipt yourself from the payment."
  },
  "receiptMatchingSettings": {
    "title": "Receipt matching",
    "subtitle": "How Groot applies a customer payment when it can't tell which invoice it covers",
    "toggleLabel": "Auto-allocate unmatched receipts to the oldest invoice (FIFO)",
    "toggleHelp": "Off by default. When on, a receipt the customer never confirmed settles their oldest open invoice(s) first once the 7-day self-select deadline passes.",
    "enabledToast": "FIFO auto-allocation turned on",
    "disabledToast": "FIFO auto-allocation turned off",
    "saveError": "Couldn't save this setting",
    "disclosure": {
      "whatItMeans": "\"FIFO\" (first in, first out) applies an unmatched receipt to the customer's oldest open invoice(s) first, then the next oldest, until the receipt is used up.",
      "whenItFires": "It only runs after a receipt could not be matched by reference AND the customer did not respond to our self-select email within 7 days.",
      "reversible": "A FIFO-applied receipt can be reversed like any other payment, from the customer's account.",
      "warning": "Turn this on only if you're comfortable with an automatic guess: a customer sometimes deliberately withholds one invoice (for example, pending a return), and FIFO can't know that."
    }
  },
  "receiptMatchPortal": {
    "header": {
      "subtitle": "Confirm Your Payment"
    },
    "footer": {
      "poweredBy": "Powered by Groot Finance"
    },
    "loading": "Loading your receipt...",
    "linkErrors": {
      "expired": {
        "title": "Link Expired",
        "message": "This link has expired. Please contact the business you paid for an updated link."
      },
      "revoked": {
        "title": "Link No Longer Active",
        "message": "This link is no longer active. Please contact the business for an updated link."
      },
      "invalid": {
        "title": "Invalid Link",
        "message": "This link is not valid. Please check the URL or contact the business that sent it to you."
      }
    },
    "success": {
      "title": "Thank You!",
      "message": "We've applied your payment to the invoice(s) you selected. {businessName} has been notified.",
      "canClose": "You can now safely close this page."
    },
    "rateLimited": {
      "title": "Daily Limit Reached",
      "message": "You've reached the maximum number of attempts for today. Please try again tomorrow."
    },
    "otp": {
      "steps": {
        "verify": "Verify",
        "details": "Choose invoice(s)",
        "done": "Done"
      },
      "verifyTitle": "Verify it's you",
      "verifySubtitleOnFile": "For your security, we'll email a 6-digit code to {maskedEmail} to confirm it's really you.",
      "verifySubtitleEnterEmail": "For your security, enter your email and we'll send a 6-digit code to confirm it's really you.",
      "emailLabel": "Email",
      "emailPlaceholder": "you@company.com",
      "sendCode": "Send code",
      "sending": "Sending code...",
      "codeTitle": "Enter your code",
      "codeSubtitle": "We sent a 6-digit code to {maskedEmail}. Enter it below to continue.",
      "codeLabel": "6-digit code",
      "codePlaceholder": "123456",
      "verify": "Verify",
      "verifying": "Verifying...",
      "resend": "Resend code",
      "resendCountdown": "Resend code in {seconds}s",
      "changeEmail": "Use a different email",
      "sessionExpired": "Your session has expired. Please verify again to continue.",
      "errors": {
        "invalidCode": "That code isn't right. Please check it and try again.",
        "tooManyAttempts": "Too many attempts. Please request a new code.",
        "expired": "That code has expired. Please request a new one.",
        "rateLimited": "Too many requests. Please wait a moment and try again.",
        "invalidEmail": "Please enter a valid email address.",
        "emailRequired": "Please enter your email.",
        "generic": "Something went wrong. Please try again."
      }
    },
    "form": {
      "title": "Which invoice(s) does your payment cover?",
      "intro": "{businessName} received your payment of {amount}. Tick which invoice(s) it covers.",
      "noOpenInvoices": "There are no open invoices to choose from right now. Please contact the business directly.",
      "selectInvoiceAria": "Select invoice {invoice}",
      "dueOn": "Due {date}",
      "owed": "owed",
      "allocateToAria": "Amount to allocate to invoice {invoice}",
      "summaryReceipt": "Your payment",
      "summaryUnallocated": "Unallocated",
      "submitting": "Submitting...",
      "submit": "Confirm",
      "errors": {
        "invalidAllocation": "The amounts you entered don't add up to your payment. Please adjust and try again.",
        "generic": "Something went wrong submitting your choice. Please try again."
      }
    }
  },
  "bankCashLineReview": {
    "ariaLabel": "Bank line review",
    "title": "Bank / Cash · Line review",
    "narrative": "Statement narrative",
    "reference": "Statement reference",
    "imported": "Imported",
    "suggestionLabel": "Suggestion",
    "postingLabel": "Posting",
    "suggestion": {
      "held": "Held",
      "suggested": "Suggested"
    },
    "posting": {
      "none": "None",
      "draft": "Draft",
      "posted": "Posted",
      "reversed": "Reversed",
      "voided": "Voided",
      "unverified": "Unverified"
    },
    "reconciliation": {
      "unmatched": "Unmatched",
      "matched": "Matched"
    },
    "search": {
      "scopedEmpty": "No matching AR, AP, approved expense or same-account posted bank line was found in the bounded search. Platform settlements and other-account transfers were not searched.",
      "ambiguous": "Several source candidates need your review. None has been selected or settled.",
      "completeEmpty": "No source candidate was found in this completed search.",
      "completeWithEvidence": "Source evidence considered:",
      "denied": "Source search was denied. No empty result can be inferred.",
      "incomplete": "Source search is incomplete. More evidence may exist.",
      "unavailable": "Source search is unavailable. More evidence may exist."
    },
    "candidate": {
      "reference": "Its document reference appears in the bank line.",
      "amount": "Its outstanding amount matches this bank line; confirm the source before acting.",
      "postedLeg": "A posted bank line has the same account, date and amount; inspect its source.",
      "openSource": "Open source"
    },
    "status": {
      "answered": "Answer recorded for this line. No accounting effect has been confirmed.",
      "denied": "Access to this line was denied.",
      "accessUnavailable": "This bank line is unavailable. Refresh the statement review or check access.",
      "incomplete": "Line review is incomplete.",
      "stale": "This question is out of date. Refresh the line review.",
      "laterState": "This line has a later accounting or match state. Refresh the line review before answering.",
      "sent": "Answer submitted. Refresh the line review to verify the saved state.",
      "failed": "The answer was not saved. Try again.",
      "unavailable": "Line answers will be available when statement review is connected.",
      "ready": "Choosing an answer will not import, post or reconcile this line."
    }
  },
  "bankStatementPreview": {
    "ariaLabel": "Bank statement review",
    "title": "Review statement",
    "summary": "{file} · {count} parsed rows · Preview only; no transactions imported or posted",
    "held": "Review these issues before import",
    "reviewable": "Rows parsed. A separate import confirmation is required",
    "issuesLabel": "Review issues",
    "chosenAccount": "Chosen bank account",
    "accountSelected": "Account selected",
    "chooseAccount": "Choose an account",
    "statementAccount": "Statement account number",
    "statementCurrency": "Statement currency",
    "opening": "Opening balance",
    "closing": "Closing balance",
    "currencyAssumption": "Currency assumption",
    "currencyAssumptionValue": "{currency} from chosen account; confirm before import",
    "none": "None",
    "dateOrder": "Date order",
    "notDetermined": "Not determined",
    "sourceLocation": "Source location",
    "unavailable": "Unavailable",
    "headerRow": "Header row {row}",
    "columnMapping": "Column mapping",
    "chooseColumns": "Choose columns",
    "notProvided": "Not provided",
    "source": "Source: {source}",
    "rowCaption": "First {count} parsed rows. Source row counts nonblank data rows, not sheet row numbers.",
    "unknownField": "Unrecognized field",
    "dateOrders": {
      "DMY": "Day / month / year",
      "MDY": "Month / day / year"
    },
    "dateSources": {
      "file": "Determined from file",
      "default": "Suggested from locale; review",
      "not_needed": "No numeric date order needed"
    },
    "directions": {
      "debit": "Debit",
      "credit": "Credit"
    },
    "table": {
      "sourceRow": "Source row",
      "date": "Date",
      "description": "Description",
      "sourceDebit": "Source debit",
      "sourceCredit": "Source credit",
      "direction": "Direction",
      "amount": "Amount"
    },
    "columns": {
      "transactionDate": "Transaction date",
      "description": "Description",
      "debitAmount": "Debit amount",
      "creditAmount": "Credit amount",
      "currency": "Currency",
      "accountNumber": "Account number"
    },
    "holds": {
      "fileSize": "File must be between 1 byte and 5 MiB.",
      "fileType": "This file type cannot be previewed.",
      "fileContent": "The file contents do not match its type.",
      "pdfUnavailable": "PDF statement rows cannot be extracted for review yet.",
      "xlsUnavailable": "This XLS file cannot be safely previewed yet. Use CSV or XLSX.",
      "workbookSize": "This workbook exceeds the safe preview size.",
      "unreadableFile": "The file could not be read.",
      "rowLimit": "Preview is limited to 1,000 rows.",
      "accountConfirmation": "Confirm the selected bank account.",
      "accountConflict": "Account numbers conflict; check the statement and selected account.",
      "accountComparison": "Provide the selected account number to compare with the statement.",
      "currencyConflict": "Currencies conflict; check the statement and selected account.",
      "currencyAssumption": "Confirm the currency assumed from the selected account.",
      "totalUnreadable": "Check the supplied opening or closing balance and its source.",
      "totalConflict": "Opening balance plus row movements does not equal closing balance.",
      "dateUnreadable": "Check the transaction dates; at least one could not be read.",
      "dateMixed": "The file mixes day-first and month-first dates.",
      "dateConflict": "The selected date order conflicts with the file.",
      "dateReview": "Confirm the suggested date order.",
      "columnMissing": "Map the {field} column.",
      "invalidRow": "Check the amount and description in source row {row}.",
      "unknown": "This preview needs review; check the file and mappings."
    },
    "reasons": {
      "unreadableTotal": "Total cannot be read; check its value and source.",
      "conflictingValues": "Values conflict within the statement.",
      "accountMismatch": "Does not match the selected account.",
      "currencyMismatch": "Does not match the selected account currency.",
      "balanceMismatch": "Does not reconcile with opening balance and rows.",
      "unknown": "This value needs review."
    }
  },
  "dashboardStatementReview": {
    "close": "Close",
    "file": "Statement file",
    "inspect": "Inspect statement",
    "legacyText": "Older .xls workbooks use the existing import route until a bounded reader is available.",
    "legacyButton": "Import legacy .xls",
    "legacyWrongType": "Use the reviewed statement flow for CSV, XLSX or PDF files.",
    "unavailable": "This file has a review that is unavailable to you.",
    "rowLimit": "This review supports up to 500 rows.",
    "page": "Page {page}",
    "accountNumber": "Account number column (optional)"
  },
  "chatStatementBridge": {
    "title": "Review bank statement",
    "intro": "Choose an account and check the observed file mapping. No rows have been imported.",
    "supporting": "{count} accompanying receipt or invoice files are upload evidence only. They are not linked to a bank line or a receipt or invoice record yet. Create or identify the owning document before linking one to a selected line.",
    "loadingAccounts": "Loading bank accounts…",
    "denied": "You do not have access to review bank statements for this business.",
    "reportsOff": "Uploading a bank statement is turned off for you. The business owner decides who can see the company's bank figures: ask them to turn on \"Can see financial reports\" for you in Settings, Team.",
    "incomplete": "The account list could not be checked completely. Try again later.",
    "noAccounts": "No active bank account is available. Add one in Bank Accounts first.",
    "account": "Bank account",
    "chooseAccount": "Choose an account",
    "confirmAccount": "This statement belongs to {name} ••{last4}.",
    "confirmCurrency": "If the file omits currency, use {currency} as a reviewed assumption.",
    "inspecting": "Reading the statement headers…",
    "inspectFailed": "The statement layout could not be read.",
    "sourceRows": "{count} source rows",
    "rowLimit": "This chat review supports up to 500 rows. Use a smaller export or the statement import page.",
    "pages": "{count} pages",
    "pdfFacts": "Currency: {currency} · opening: {opening} · closing: {closing}",
    "printedAccount": "Printed account: {number}",
    "totalsMatched": "Printed totals match the rows.",
    "totalsNotVerified": "Totals were absent or incomplete; no total was verified.",
    "pdfSample": "First {shown} of {count} PDF rows. Check every row in the next review.",
    "pdfHeldPage": "Source page {page} needs review",
    "pdfHeldRow": "Source page {page}, line {row} needs review",
    "rowBalance": "Balance: {amount}",
    "confirmPdfSample": "I checked this PDF sample, account and date order. I will review every row before import.",
    "notProvided": "not provided",
    "sheet": "Worksheet",
    "headerRow": "Header row",
    "chooseColumn": "Choose a column",
    "dateOrder": "Printed date order",
    "dayFirst": "Day / Month / Year",
    "monthFirst": "Month / Day / Year",
    "confirmMapping": "I checked the account, date order, and observed columns or PDF rows.",
    "checking": "Checking statement…",
    "createPreview": "Create review preview",
    "stageFailed": "Statement review is unavailable.",
    "mt940UploadHelp": "CSV, Excel, PDF or MT940 (.sta, .mt940, .940, .txt).",
    "mt940Encoding": "Text encoding: {encoding}.",
    "confirmMt940": "I checked the MT940 account, dates, amounts and direction.",
    "column": {
      "transactionDate": "Date column",
      "description": "Description column",
      "debitAmount": "Debit column",
      "creditAmount": "Credit column",
      "currency": "Currency column (optional)"
    }
  },
  "payablesMeaning": {
    "title": "Payables by meaning",
    "description": "Open balances use posted liability accounts and linked payees.",
    "tabs": "Payable category",
    "trade": "Trade",
    "nonTrade": "Non-trade",
    "relatedParty": "Related party",
    "needsReview": "Needs review",
    "loading": "Loading payables…",
    "denied": "Payables unavailable for this account.",
    "incomplete": "Some balances could not be verified. Review Invoices or Other Expenses.",
    "empty": "No open payables in this category.",
    "invoice": "Purchase invoice",
    "expense": "Other expense",
    "controlUnknown": "Control account unknown",
    "payeeReview": "Payee relationship needs review",
    "accountReview": "Account classification needs review",
    "controlReview": "Control account needs review"
  },
  "incomeMeaning": {
    "lineHeading": "Income type",
    "lineLabel": "Income type for line {number}",
    "sales": "Sales",
    "rental": "Rental income",
    "interest": "Interest income",
    "operatingRevenue": "Operating revenue",
    "otherIncome": "Other income",
    "issueHeld": "This income type can be saved as a draft. Issue is held until the account, earned period and tax treatment are reviewed.",
    "openSettings": "Open account settings",
    "unavailable": "Income accounts unavailable",
    "accountMissing": "Account needs setup or review",
    "settingsTitle": "Income type accounts",
    "settingsIntro": "Choose a chart leaf and its actual profit and loss section. These choices do not enable posting.",
    "loading": "Loading income accounts…",
    "optionsIncomplete": "Account list incomplete. Review the chart before choosing.",
    "chooseAccount": "Choose account",
    "saving": "Saving…",
    "version": "Version",
    "saveFailed": "Could not save. Reload and try again.",
    "settingsHold": "Rental and interest invoices remain draft only while recognition, allocation and tax rules are reviewed.",
    "preparationTitle": "Income posting review",
    "preparationIntro": "Saved draft account candidates and line net amounts. This preview does not issue or post.",
    "saveDraftToPreview": "Save this draft to refresh its income review.",
    "earnedPeriodRequired": "Add the earned service period for this line.",
    "leaseReviewRequired": "Lease classification and earning schedule need review.",
    "taxReviewRequired": "Business tax facts and source document need review.",
    "routeUnavailable": "This income route is not approved for sales invoices.",
    "allocationNeedsReview": "Line net amounts do not reconcile to the document total.",
    "discountAllocationHeld": "Mixed income with an invoice discount needs an approved allocation.",
    "policyReviewRequired": "Income treatment needs review."
  },
  "bankCashMatch": {
    "title": "Match existing cash movement",
    "effect": "Link this statement line to the posted cash movement. No new journal entry will be created.",
    "expiry": "This review expires after 15 minutes.",
    "confirmed": "Match confirmed.",
    "stale": "This review is unavailable or has changed. Prepare it again.",
    "failed": "Could not confirm the match. Review the line and try again.",
    "confirming": "Confirming…",
    "confirm": "Confirm match"
  },
  "bankCashHeld": {
    "advanceDeposit": {
      "title": "Advances and refundable deposits",
      "description": "Review the original agreement, cash evidence and later use of an advance or security deposit. Every proposal stays on hold and nothing is posted.",
      "close": "Close",
      "startReview": "Review advance or deposit",
      "sourceKind": "What was received",
      "advanceRent": "Advance rent",
      "securityDeposit": "Refundable security deposit",
      "action": "Proposed action",
      "actions": {
        "receipt": "Record receipt for review",
        "apply_existing_ar": "Apply to an existing invoice",
        "unbilled_rent": "Review unbilled rent period",
        "refund": "Review refund",
        "damage_retention": "Review damage retention"
      },
      "agreementId": "Agreement number or reference",
      "agreementDocument": "Agreement document",
      "chooseDocument": "Choose an agreement you uploaded",
      "unnamedDocument": "Uploaded document",
      "originalReceipt": "Original receipt review",
      "chooseOriginal": "Choose the original receipt",
      "originalUnverified": "agreement document changed",
      "enterAgreementFirst": "Enter the agreement reference to list its receipts.",
      "noOriginals": "No held receipt found for this agreement and source.",
      "bankAccount": "Receiving bank account",
      "chooseBank": "Choose a bank account",
      "bankLine": "Imported bank credit",
      "chooseBankLine": "Choose the bank credit",
      "bankLinesUnavailable": "Bank credits for this account are unavailable. Check that the account is active and linked to a chart account.",
      "invoice": "Existing customer invoice",
      "chooseInvoice": "Choose an unpaid invoice",
      "periodStart": "Service period start",
      "periodEnd": "Service period end",
      "damageReason": "What damage or agreed deduction is claimed?",
      "amount": "Amount",
      "currency": "Currency",
      "valueDate": "Value date",
      "taxDocument": "Tax document and e-Invoice",
      "taxUnresolved": "Not decided",
      "existingEinvoice": "Existing validated e-Invoice (reference required)",
      "securityDocumentClaim": "Refundable security deposit, no invoice claimed (unverified)",
      "taxReviewRequired": "Needs tax and document review",
      "taxReference": "e-Invoice or tax document reference",
      "selectedLine": "Selected bank credit: {date}, {amount}",
      "originalHeld": "The original receipt is only a held review. Nothing has been recorded in the books.",
      "incomplete": "Only recent records are shown. Open the owning source for older ones.",
      "saveHeld": "Save held review",
      "saving": "Saving…",
      "noPosting": "Saving a review does not receive, apply, refund, keep or post any money.",
      "history": "Held reviews",
      "historyLoading": "Loading held reviews…",
      "historyEmpty": "No held reviews yet.",
      "completeFields": "Enter the agreement reference, a positive amount, a three-letter currency and a date.",
      "denied": "You do not have access to advance and deposit reviews for this business.",
      "unavailable": "The review could not be saved. Try again.",
      "heldResult": "Saved and on hold. {reason}",
      "replayResult": "Already saved and on hold. {reason}",
      "fixResult": "Not saved. {reason}",
      "deniedResult": "Not saved. You do not have access to record this review.",
      "heldReason": {
        "AGREEMENT_SOURCE_UNVERIFIED": "The agreement document is missing or is no longer your upload, so the original terms cannot be checked.",
        "CASH_EVIDENCE_MISSING": "No imported bank credit is linked, so the money received cannot be confirmed.",
        "TAX_FACTS_MISSING": "Your business country or tax registration is not set in Business Profile.",
        "TAX_DOCUMENT_REVIEW": "The tax document is not decided, or the e-Invoice reference is missing.",
        "DEPOSIT_SUBSTANCE_UNRESOLVED": "Keeping part of a deposit for damage needs the agreed deduction to be reviewed first.",
        "LEASE_TREATMENT_REQUIRED": "The lease classification and the earning schedule for this rent period need review.",
        "ORIGINAL_EFFECT_UNPOSTED": "The original receipt is not recorded in the books yet, so it cannot be applied, refunded or kept.",
        "ADVANCE_LIFECYCLE_UNAPPROVED": "Recording advances and deposits in the books is not available yet. This review is kept for later.",
        "unknown": "This review needs another check before anything is recorded."
      },
      "fixReason": {
        "REVIEW_FIELDS_INVALID": "Check the agreement reference, amount, currency, date and the length of each text field.",
        "ORIGINAL_RECEIPT_REQUIRED": "Choose the original receipt for this action. A new receipt does not link to one.",
        "AR_SOURCE_REQUIRED": "Choose an invoice only when applying the money to an existing invoice.",
        "LEASE_PERIOD_REQUIRED": "Enter a valid service period, with the start on or before the end.",
        "DEPOSIT_SUBSTANCE_UNRESOLVED": "Damage retention needs a reason and applies only to a refundable security deposit.",
        "CASH_EVIDENCE_WRONG_ACTION": "A bank credit can be linked only when recording a receipt.",
        "TAX_DOCUMENT_REVIEW": "The no-invoice security deposit claim applies only to a refundable security deposit.",
        "AGREEMENT_SOURCE_UNVERIFIED": "Choose an agreement document you uploaded to this business, the same one used for the original receipt.",
        "ORIGINAL_RECEIPT_UNVERIFIED": "The original receipt does not match this agreement, source or currency, or the amount is more than was received.",
        "CASH_EVIDENCE_UNVERIFIED": "Choose an unmatched bank credit on an active account with the same date, amount and currency.",
        "AR_SOURCE_UNVERIFIED": "Choose a posted, open invoice in the same currency that still owes at least this amount.",
        "REQUEST_EFFECT_CONFLICT": "These details changed after an earlier save attempt. Save again.",
        "unknown": "Some details need checking before this review can be saved."
      }
    },
    "salesErrors": {
      "correctionHeld": "This invoice has a rental or interest line. A posted correction stays held until its recognition, allocation and tax treatment are reviewed.",
      "noteAllocationHeld": "This invoice has a rental or interest line. A credit or debit note stays held until the line allocation is reviewed."
    }
  },
  "chequeClearance": {
    "dialogMessageVerified": "Marking this cheque or GIRO cleared issues its Official Receipt. If you have imported the bank statement, you can also choose the credit that shows it cleared: the clearance is then dated on the credit and matched to it.",
    "legacyNoOr": "Official Receipts are off for this business, so this clearance is not numbered as an Official Receipt.",
    "bankCredit": {
      "label": "Imported bank credit",
      "help": "Optional. Only unmatched credits for exactly {amount} on this bank's imported statement are listed.",
      "placeholder": "Select a bank credit",
      "option": "{date} · {description} · {amount}",
      "unavailable": "Bank statement credits are unavailable. Check Bank Reconciliation access and that this bank has one linked statement account. You can still mark the cheque cleared.",
      "none": "No unmatched credit for this amount is on this statement page. You can still mark the cheque cleared; its Official Receipt is confirmed by you.",
      "nextPage": "Next statement page",
      "loading": "Loading bank credits...",
      "blockedOption": "{date} · {description} · {amount} (suggested for {entry})",
      "blockedNote": "A credit that Bank Reconciliation already suggests for another entry cannot be used here until that suggestion is reviewed.",
      "blockedLink": "Review in Bank Reconciliation"
    },
    "notice": {
      "issued": "Cheque cleared. Official Receipt {receiptNumber} issued.",
      "cleared": "Cheque marked cleared."
    },
    "errors": {
      "pending": "This cheque or GIRO has not cleared yet, so its Official Receipt cannot be issued.",
      "evidenceInvalid": "That bank credit does not match this cheque. Check the amount, currency and bank account, and that it comes from a reviewed statement import.",
      "evidenceUsed": "That bank credit is already matched to another record. Choose a different credit.",
      "dateMismatch": "The clearance must be dated on the bank credit. Choose the credit again.",
      "matchUnproven": "The bank credit and the clearance posting did not agree, so nothing was posted. Try again, or contact support if it keeps happening.",
      "foreignCurrency": "A foreign-currency cheque cannot receive an Official Receipt yet. Ask the business owner to review the Official Receipts setting.",
      "notPending": "This cheque is no longer pending. Refresh the page to see its current status.",
      "browserRequired": "Confirm this clearance yourself while signed in to Groot in your browser.",
      "orUnavailable": "An Official Receipt could not be issued, so nothing was posted. Contact support.",
      "evidenceSuggested": "Bank Reconciliation already suggests that credit for another entry. Review the suggestion there first.",
      "externalReceipt": "This payment's receipt comes from another system, so a bank credit cannot be used as Official Receipt evidence. Clear it without choosing a credit."
    },
    "card": {
      "title": "Clear cheque or GIRO",
      "cheque": "Cheque {reference}",
      "chequeNoReference": "Pending cheque or GIRO",
      "invoices": "Settled invoices: {invoices}",
      "bankCredit": "Bank credit on {date}: {description}",
      "bank": "Bank account: {bank}",
      "effect": "Confirming moves {amount} from Cheque / GIRO Clearing to this bank, matches the bank credit and issues one Official Receipt.",
      "confirm": "Confirm clearance",
      "confirming": "Confirming...",
      "confirmed": "Cleared. Official Receipt issued:",
      "alreadyCleared": "This cheque is already cleared.",
      "alreadyClearedWithReceipt": "This cheque is already cleared. Official Receipt:",
      "loading": "Checking the latest payment and bank details...",
      "settingOff": "Official Receipts are off for this business. Clear this cheque from the invoice's payment history instead.",
      "unavailable": "This clearance is no longer available. Ask Groot to check the statement line again.",
      "hold": "This bank credit cannot clear the cheque.",
      "openInvoice": "Open invoice"
    },
    "noCreditNote": "No bank credit chosen: this clearance posts on today's date, and the Official Receipt is confirmed by you."
  },
  "paymentRecorderCopy": {
    "bankCredit": {
      "label": "Imported bank credit",
      "help": "Optional. If you have imported this bank's statement, choose the exact credit to record the Official Receipt as matched to your bank. The payment is then dated on the statement date.",
      "placeholder": "Select a bank credit",
      "option": "{date} · {description} · {amount}",
      "unavailable": "Imported bank credits are not available for this bank account. The payment records as usual, and its Official Receipt is confirmed by you.",
      "none": "No imported credit for this amount is on this statement page. You can still record the payment; its Official Receipt is confirmed by you.",
      "nextPage": "Next statement page",
      "clear": "Record without a bank credit",
      "dateFromCredit": "Dated on the bank credit's statement date, {date}.",
      "dateCleared": "The bank credit was removed because you changed the payment date. Choose it again to match the receipt to your bank.",
      "blockedOption": "{date} · {description} · {amount} (suggested for {entry})",
      "blockedNote": "A credit that Bank Reconciliation already suggests for another entry cannot be used here until that suggestion is reviewed.",
      "blockedLink": "Review in Bank Reconciliation"
    },
    "orPreview": {
      "mint": "An Official Receipt will be issued with this payment.",
      "mintNumbered": "An Official Receipt will be issued with this payment. Next number: {number}.",
      "none": {
        "setting_off": "No Official Receipt: Official Receipts are turned off for this business.",
        "pending_clearance": "No Official Receipt yet: a post-dated cheque or GIRO gets one when it clears.",
        "external_receipt": "No Official Receipt: the customer's receipt from another system is the receipt of record."
      }
    },
    "errors": {
      "pending": "This payment is still waiting for bank clearance, so it cannot be issued an Official Receipt yet.",
      "evidenceInvalid": "That bank credit does not match this payment. Check the amount, currency and bank account, and that it comes from a reviewed statement import.",
      "evidenceUsed": "That bank credit is already matched to another record. Choose a different credit, or record the payment without one.",
      "evidenceSuggested": "Bank Reconciliation already suggests that credit for another entry. Review the suggestion there first, or record the payment without it.",
      "dateMismatch": "The payment date must be the bank credit's statement date. Choose the credit again.",
      "matchUnproven": "The bank credit and the payment posting did not agree, so nothing was recorded. Try again, or contact support if it keeps happening.",
      "foreignCurrency": "A payment in a foreign currency cannot use a bank credit for an Official Receipt. Record it without choosing a credit.",
      "orUnavailable": "An Official Receipt could not be issued, so nothing was recorded. Contact support.",
      "journalFailed": "This payment couldn't be posted to the ledger, so it wasn't recorded. Try again, or contact support if it keeps happening.",
      "externalReceiptInvalid": "Enter the other system's name (up to 60 characters) and its receipt reference (up to 120 characters).",
      "externalReceiptWithCredit": "A bank credit can only be chosen when Groot issues the Official Receipt. Remove the bank credit, or remove the receipt from another system."
    },
    "externalReceipt": {
      "label": "The customer already has a receipt from another system",
      "help": "Use this for a payment a store, POS or gateway has already receipted. Groot records the reference and does not issue or send its own Official Receipt for it.",
      "systemLabel": "System",
      "systemPlaceholder": "e.g. WooCommerce, POS",
      "referenceLabel": "Receipt number or reference",
      "referencePlaceholder": "e.g. WC-10234"
    },
    "success": {
      "officialReceipt": "Official Receipt",
      "receiptOfRecord": "Receipt of record: {system} {reference}",
      "preparing": "Preparing the receipt...",
      "done": "Done"
    }
  },
  "cashCorrections": {
    "open": "Correct",
    "title": "Correct this cash movement",
    "description": "Nothing is deleted. A reversal adds the exact opposite entry on the same date and keeps both, so the audit trail stays complete.",
    "loading": "Checking what can be corrected...",
    "denied": "You cannot view corrections for this movement.",
    "kind": {
      "receive": "Money received",
      "pay": "Money paid",
      "transfer": "Transfer between our accounts"
    },
    "amount": "Amount",
    "date": "Date",
    "reference": "Reference",
    "voucher": "Voucher",
    "voidLabel": "Void",
    "eligible": {
      "receive": "You can reverse this receipt. The opposite entry posts on {date} and the Cash Book shows both.",
      "pay": "You can reverse this payment. The opposite entry posts on {date} and its payment voucher is voided.",
      "transfer": "You can reverse this transfer. Every posted leg gets an exact opposite entry, so both accounts return to their earlier balances.",
      "receiveWithVoucher": "You can reverse this receipt. The opposite entry posts on {date}, the Cash Book shows both, and its receipt voucher is voided."
    },
    "refused": {
      "ALREADY_REVERSED": "This movement has already been reversed. Both entries stay in the Cash Book.",
      "UNMATCH_FIRST": "This movement is matched to a bank statement line. Clear that match first, then reverse it here.",
      "PERIOD_LOCKED": "The accounting period for this movement is closed. Record an adjusting journal dated in an open period instead.",
      "POSTED_EFFECT_UNPROVEN": "We could not confirm how this movement was posted. Refresh the page and try again.",
      "MATCH_HISTORY_LIMIT": "This movement has too much match history to check here. Please contact support.",
      "REVERSE_INCOMING_FIRST": "The outgoing leg cannot be reversed on its own while the arrival is posted. Reverse the arrival first, or reverse the whole transfer.",
      "LEG_NOT_SEPARATELY_REVERSIBLE": "The parts of this movement cannot be reversed separately. Reverse the whole movement instead."
    },
    "route": {
      "unmatchTransaction": "Unmatch in Bank reconciliation",
      "rejectSuggestedMatch": "Reject match in Bank reconciliation",
      "adjustingEntry": "Record an adjusting journal"
    },
    "reasonLabel": "Why are you reversing this movement?",
    "reasonHint": "At least 10 characters. Finance reviewers will see this reason in the audit trail.",
    "reasonTooShort": "Explain the reversal in at least 10 characters.",
    "notPermitted": "Only an owner or finance administrator can reverse this movement.",
    "confirm": "Reverse movement",
    "submitting": "Reversing...",
    "cancel": "Cancel",
    "close": "Close",
    "success": "Movement reversed. The opposite entry is now in the Cash Book.",
    "holds": {
      "ACCESS_DENIED": "Only an owner or finance administrator of this business can reverse this movement.",
      "BROWSER_CONFIRMATION_REQUIRED": "A signed-in person must confirm this reversal on this screen.",
      "CORRECTION_REASON_REQUIRED": "Explain the reversal in at least 10 characters.",
      "CASH_DOCUMENT_STALE": "This movement changed after you opened it. Close this window and open it again to see its current state.",
      "CASH_DOCUMENT_UNAVAILABLE": "This movement is no longer available.",
      "REQUEST_EFFECT_CONFLICT": "This movement was already corrected with a different reason. Refresh to see its current state.",
      "generic": "This reversal could not be completed. Refresh and try again."
    },
    "errors": {
      "unexpected": "Something went wrong while reversing this movement. Nothing was changed. Please try again."
    },
    "card": {
      "title": "Reverse a cash movement",
      "prepared": "Prepared by the assistant. Check the details, give your reason, then confirm. Nothing changes until you do.",
      "stale": "This movement changed after the assistant prepared this. Ask again for a fresh preview.",
      "unavailable": "This preview is no longer available.",
      "done": "Reversed",
      "historical": "This request is from an earlier conversation. Open the Cash Book to review the movement.",
      "doneIncoming": "Arrival reversed"
    },
    "legs": {
      "legend": "What should be reversed?",
      "incoming": {
        "label": "Reverse the arrival only",
        "hint": "Cancels the arrival on {date}. The money goes back to in transit and the outgoing leg stays posted, so you can confirm the arrival again against the right statement line."
      },
      "whole": {
        "label": "Reverse the whole transfer",
        "hint": "Cancels both legs with exact opposite entries, so both accounts return to their earlier balances."
      },
      "outgoingOnly": "The outgoing leg cannot be reversed on its own while the arrival is posted, because the destination account would keep money that never left. Reverse the arrival first, or reverse the whole transfer.",
      "choose": "Choose what to reverse.",
      "confirmIncoming": "Reverse arrival",
      "confirmWhole": "Reverse transfer",
      "successIncoming": "Arrival reversed. The money is back in transit until you confirm the arrival again."
    }
  },
  "cashBookPage": {
    "fromDate": "From",
    "toDate": "To",
    "fromDateLabel": "Cash Book start date",
    "toDateLabel": "Cash Book end date",
    "loading": "Loading the Cash Book...",
    "howItWorksButton": "How the Cash Book works",
    "reasons": {
      "history": "This account's history is still being checked. An exact balance is not available yet.",
      "invalidRange": "Choose a start date on or before the end date.",
      "currencyUnproven": "No posted movements yet, so the currency is not known. Link this account to a bank account to show a zero balance.",
      "currencyMismatch": "The linked bank account uses a different currency from the posted movements. Check the bank account link.",
      "mixedCurrency": "This account has postings in more than one currency, so an exact balance cannot be shown.",
      "linkedDocuments": "Some receipts or bank matches on this page could not be verified. Refresh, or open Account Inquiry for the ledger view."
    },
    "coverage": {
      "title": "Cash Book history",
      "loading": "Checking history status...",
      "unavailable": "History status is unavailable or access was denied.",
      "notStarted": "History for this account has not been built yet. Build it once to show exact balances. Your ledger and Account Inquiry are not affected.",
      "notStartedNoRole": "History for this account has not been built yet. Ask an owner or finance admin to build it.",
      "scanning": "Checking posted history: {count} postings checked so far.",
      "rebuilding": "Calculating daily balances: {done} of {total} postings.",
      "stalled": "The history build stopped before finishing ({count} postings checked). Resume it to continue from where it stopped.",
      "stalledNoRole": "The history build stopped before finishing. Ask an owner or finance admin to resume it.",
      "complete": "History is complete. Refreshing the balance...",
      "needsReview": "This account needs a review before an exact balance can be shown: its chart settings changed before the Cash Book existed, or its postings use more than one currency. Contact support. Your ledger and Account Inquiry are not affected.",
      "build": "Build history",
      "resume": "Resume building",
      "starting": "Starting...",
      "startFailed": "The history build could not be started. Try again."
    },
    "drawer": {
      "title": "How the Cash Book works",
      "intro": "The Cash Book lists every posted movement on one bank or cash account, with a running balance taken from the ledger.",
      "stepsHeading": "How to use it",
      "step1Title": "Choose an account and period",
      "step1Desc": "Pick a bank or cash account and a date range. Archived accounts stay available for past periods.",
      "step2Title": "Build the history once",
      "step2Desc": "Postings made before the Cash Book existed are checked once per account. Until that finishes, the exact balance is withheld rather than guessed.",
      "step3Title": "Open the document",
      "step3Desc": "Click a voucher or receipt number, marked with a clip icon, to open the document behind the movement.",
      "step4Title": "Check bank matches",
      "step4Desc": "A matched movement links to its imported bank line. Unmatched movements can be reviewed in bank reconciliation.",
      "legendHeading": "Document numbers",
      "legendOR": "Official receipt for a cleared customer payment or cash sale",
      "legendPV": "Payment voucher: money paid from a bank account",
      "legendPCV": "Petty cash voucher: money paid from cash",
      "legendJV": "Journal voucher: a manual or adjusting posting",
      "legendNoneTerm": "No document number",
      "legendNone": "The posting has no voucher or receipt, so its journal entry number is shown instead.",
      "tipsHeading": "Good to know",
      "tip1": "Importing, suggestions and matching never post money. A movement is posted only after a person confirms it in the browser.",
      "tip2": "If a balance cannot be proven, the Cash Book says so instead of showing a number.",
      "tip3": "Chat can read the Cash Book and prepare movements, but a person confirms every posting here.",
      "settingsLink": "Open Payment & posting settings",
      "legendRV": "Receipt voucher: an internal document for money received directly, such as bank interest. It is not given to a customer."
    },
    "bankLink": {
      "invoicesTitle": "Open invoices that match this credit",
      "invoiceOption": "Record payment on {invoice} · {amount} due",
      "invoicesLoading": "Looking for open invoices...",
      "invoicesNone": "No open invoice matches this amount or reference.",
      "invoicesIncomplete": "The invoice search did not finish, so an invoice may be missing from this list.",
      "openInvoices": "Open Sales Invoices",
      "pendingCheque": "A cheque or GIRO awaiting clearance matches this credit ({label}). Open it to clear it instead of recording a new payment.",
      "creditPreselected": "Selected from the bank line you opened in Bank / Cash. Check it before you record the payment.",
      "creditNotOffered": "The bank credit you opened from Bank / Cash is not in this list, so nothing was selected. It may already be matched, or its amount or bank account differs from this payment.",
      "recordCashSale": "No invoice: record as a cash sale"
    }
  },
  "bankCashChat": {
    "lineQuestion": {
      "question": {
        "credit": "What is the source of this money received?",
        "debit": "What was this payment for?"
      },
      "choice": {
        "customer_payment": "Customer payment",
        "bank_interest": "Bank interest",
        "own_transfer": "Transfer between my accounts",
        "owner_funding": "Owner funding or loan",
        "other_receipt": "Another receipt",
        "supplier_payment": "Supplier or expense payment",
        "bank_charge": "Bank charge",
        "not_sure": "Something else / Not sure"
      },
      "fromFile": "{fileName}, imported line"
    },
    "lineReview": {
      "ariaLabel": "Bank line review",
      "title": "Bank / Cash · Line review",
      "narrative": "Statement narrative",
      "reference": "Statement reference",
      "imported": "Imported",
      "suggestionLabel": "Suggestion",
      "postingLabel": "Posting",
      "suggestion": {
        "held": "Held",
        "suggested": "Suggested"
      },
      "posting": {
        "none": "None",
        "draft": "Draft",
        "posted": "Posted",
        "reversed": "Reversed",
        "voided": "Voided",
        "unverified": "Unverified"
      },
      "reconciliation": {
        "unmatched": "Unmatched",
        "matched": "Matched"
      },
      "search": {
        "scopedEmpty": "No matching AR, AP, approved expense or same-account posted bank line was found in the bounded search. Platform settlements and other-account transfers were not searched.",
        "ambiguous": "Several source candidates need your review. None has been selected or settled.",
        "completeEmpty": "No source candidate was found in this completed search.",
        "completeWithEvidence": "Source evidence considered:",
        "denied": "Source search was denied. No empty result can be inferred.",
        "incomplete": "Source search is incomplete. More evidence may exist.",
        "unavailable": "Source search is unavailable. More evidence may exist.",
        "sameAmountInBrowser": "These records only share the amount with this line. If it is none of them, set them aside in Bank / Cash.",
        "unfinishedInBrowser": "Groot could not check every record for this line. You can confirm it is not already recorded in Bank / Cash."
      },
      "status": {
        "answered": "Answer recorded for this line. No accounting effect has been confirmed.",
        "denied": "Access to this line was denied.",
        "accessUnavailable": "This bank line is unavailable. Refresh the statement review or check access.",
        "incomplete": "Line review is incomplete.",
        "stale": "This question is out of date. Refresh the line review.",
        "laterState": "This line already has a later accounting or match state, so it cannot be answered here.",
        "sent": "Answer submitted. Refresh the line review to verify the saved state.",
        "failed": "The answer was not saved. Try again.",
        "unavailable": "Line answers will be available when statement review is connected.",
        "ready": "Choosing an answer will not import, post or reconcile this line.",
        "postedReconciled": "Posted and reconciled. Nothing is left to answer on this line.",
        "reconciled": "Reconciled to an existing record. Nothing is left to answer on this line.",
        "postedUnreconciled": "Posted, but not reconciled yet. Match it to its posting under Needs review.",
        "postingUnresolved": "This line's posting is not final. Resolve it under Needs review before answering.",
        "changed": "This line changed before your answer was saved. Its current state is shown above."
      },
      "openSource": "Open source"
    },
    "candidate": {
      "kind": {
        "ar_invoice": "Customer invoice",
        "ap_bill": "Supplier bill",
        "expense_claim": "Expense claim",
        "business_expense": "Business expense",
        "platform_settlement": "Platform payout",
        "payroll_payment": "Payroll payment",
        "other_account_transfer": "Transfer from another account",
        "posted_cash_leg": "Posted bank movement",
        "other": "Source record",
        "pending_cheque_clearance": "Cheque or GIRO awaiting clearance",
        "reconciliation_suggestion": "Reconciliation suggestion"
      },
      "reason": {
        "invoice_reference_in_bank_line": "Its invoice number appears in the bank line.",
        "bill_reference_in_bank_line": "Its bill number appears in the bank line.",
        "outstanding_amount_matches": "Its outstanding amount matches this bank line; confirm the source before acting.",
        "platform_payout_amount_matches": "The platform payout amount matches this bank line.",
        "payroll_net_pay_amount_matches": "The payroll net pay matches this bank line.",
        "business_expense_amount_matches": "The expense amount matches this bank line.",
        "approved_amount_matches": "The approved claim amount matches this bank line.",
        "transfer_leg_account_date_amount": "A transfer leg has the same account, date and amount.",
        "effective_cash_leg_same_account_date_amount": "A posted bank movement has the same account, date and amount; inspect its source.",
        "other": "Possible match; confirm the source before acting.",
        "cheque_reference_in_bank_line": "Its cheque or GIRO reference appears in the bank line.",
        "pending_instrument_amount_matches": "A cheque or GIRO awaiting clearance has this amount.",
        "reconciliation_high_confidence_suggestion": "Bank reconciliation matched this line to an existing entry with high confidence. Check it there before recording anything new."
      },
      "status": {
        "posted": "Posted",
        "matched": "Matched",
        "unmatched": "Unmatched",
        "source_owned": "Managed in its source",
        "draft": "Draft",
        "sent": "Sent",
        "overdue": "Overdue",
        "paid": "Paid",
        "partially_paid": "Partly paid",
        "unpaid": "Unpaid",
        "unpaid_unrecorded": "Unpaid, no payment recorded",
        "pending": "Pending",
        "approved": "Approved",
        "submitted": "Submitted",
        "reimbursed": "Reimbursed",
        "prepared": "Prepared",
        "confirmed": "Confirmed",
        "held": "Held",
        "other": "Open the record to see its status",
        "pending_clearance": "Awaiting clearance",
        "suggested": "Suggested"
      }
    },
    "match": {
      "title": "Match existing cash movement",
      "effect": "Link this statement line to the posted cash movement. No new journal entry will be created.",
      "expiry": "This review expires after 15 minutes.",
      "confirmed": "Match confirmed.",
      "stale": "This review is unavailable or has changed. Prepare it again.",
      "failed": "Could not confirm the match. Review the line and try again.",
      "confirming": "Confirming...",
      "confirm": "Confirm match",
      "held": "This match is on hold. Open the line's source before trying again.",
      "moneyIn": "Money in",
      "moneyOut": "Money out"
    },
    "sessionReview": {
      "searchIncomplete": "Source search is incomplete. No posting can be prepared.",
      "possibleSources": "Review possible source records",
      "sourceOwnedWorkflow": "This answer needs its source-owned workflow; no direct posting is available.",
      "statementLineReference": "Bank statement line, {date}",
      "searchUnfinished": "Groot could not check every existing invoice, bill, claim, expense and transfer for this line. Before anything posts, you will be asked to confirm the money is not already recorded.",
      "searchPartial": "Groot could not check every record. These are the matches it found.",
      "matchesSettable": "These records only share the amount. If the line is none of them, you can still record it below; you will be asked to confirm.",
      "matchesSettableUnfinished": "These records only share the amount, and Groot could not check every other record. If the line is none of them, you can still record it below; you will be asked to confirm the money is not already recorded."
    },
    "importReview": {
      "totalsUncheckedHeld": "Printed totals are not checked while rows are held for verification.",
      "heldCount": "Held for verification {count}",
      "heldTitle": "{count, plural, one {# row is held for verification} other {# rows are held for verification}}",
      "heldHelp": "These rows could not be read reliably and are not imported. Check them on the statement; the readable rows can still be imported.",
      "heldRowPage": "Page {page}, line {row}",
      "heldRowPosition": "Source position {position}",
      "heldReason": {
        "row_unreadable": "text could not be read",
        "row_ambiguous": "money in or out is unclear"
      },
      "acknowledgeHeld": "I understand {count, plural, one {the held row} other {the # held rows}} will not be imported.",
      "completeWithHeld": "Import complete for the readable rows. {count, plural, one {# held row was} other {# held rows were}} not imported. These are bank lines, not posted accounting entries.",
      "pageRange": "{from} to {to} of {total}",
      "error": {
        "stale": "This review expired or changed. Reload it and review again.",
        "currencyChanged": "The bank account currency changed. Prepare the statement review again.",
        "factsUnreviewed": "Confirm that you checked the account, dates, amounts and direction first.",
        "heldRowsUnacknowledged": "Acknowledge that the held rows will not be imported.",
        "interpretationChanged": "This file is already imported. An owner or finance admin can retract that import from Upload history, then import the file into the right account.",
        "reportsOff": "Uploading a bank statement is turned off for you. The business owner decides who can see the company's bank figures: ask them to turn on \"Can see financial reports\" for you in Settings, Team.",
        "ownerOnly": "Only the person who uploaded this statement can confirm it, while signed in to this business."
      }
    },
    "statementError": {
      "FINANCIAL_REPORTS_OFF": "Uploading a bank statement is turned off for you. The business owner decides who can see the company's bank figures: ask them to turn on \"Can see financial reports\" for you in Settings, Team.",
      "STATEMENT_PREVIEW_EXPIRED": "This PDF reading is no longer available. Inspect the PDF again before creating a review.",
      "NOT_AUTHENTICATED": "Sign in again to review the statement.",
      "INVALID_REQUEST": "The statement selection was not valid. Choose the file and account again.",
      "INVALID_FILE": "Choose a CSV, XLS, XLSX or PDF bank statement.",
      "FILE_TOO_LARGE": "The statement file is too large for this review.",
      "NOT_AUTHORIZED": "You do not have access to review statements for this bank account.",
      "BANK_ACCOUNT_CONFIRMATION_REQUIRED": "Choose an active bank account in this business and confirm the statement belongs to it.",
      "STATEMENT_ATTACHMENT_UNAVAILABLE": "This statement attachment is unavailable. Upload it again in this chat.",
      "STATEMENT_BYTES_UNVERIFIED": "The file contents do not match a supported statement format.",
      "STATEMENT_NEEDS_REVIEW": "The statement needs review before it can be staged.",
      "STATEMENT_ACCOUNT_MISMATCH": "The printed account number differs from the account you chose.",
      "STATEMENT_ACCOUNT_NUMBER_MISSING": "The chosen bank account has no statement account number saved yet. Add it in Manage Accounts under Statement account number, then upload again.",
      "STATEMENT_CURRENCY_MISMATCH": "The statement currency differs from the account you chose.",
      "STATEMENT_DATE_ORDER_REQUIRED": "Choose the printed date order.",
      "STATEMENT_DATES_NEED_REVIEW": "Some dates could not be read with the chosen date order.",
      "STATEMENT_TOTALS_NEED_REVIEW": "The printed opening and closing balances do not agree with the rows.",
      "STATEMENT_CURRENCY_ASSUMPTION_REQUIRED": "Confirm the bank account currency, because the statement does not state one.",
      "STATEMENT_ROW_LIMIT": "This review supports up to 500 statement rows. Use a smaller export.",
      "STATEMENT_SIZE_LIMIT": "The statement is too large for this review. Use a smaller export.",
      "STATEMENT_COLUMNS_REQUIRED": "Choose the date, description, debit and credit columns.",
      "STATEMENT_UNREADABLE": "The statement could not be read. Check the file and try again.",
      "STATEMENT_STAGE_REFUSED": "The statement could not be prepared for review. It may already be under review elsewhere or imported.",
      "UPLOAD_FAILED": "The statement could not be uploaded. Try again.",
      "SERVICE_UNAVAILABLE": "Statement review is temporarily unavailable. Try again shortly.",
      "generic": "The statement review could not continue. Try again."
    },
    "statementHold": {
      "invalid_pdf": "The file is not a readable PDF",
      "file_too_large": "The file is too large",
      "too_many_pages": "The PDF has too many pages",
      "page_too_large": "A page has too much text to read safely",
      "page_unreadable": "A page has no readable text (it may be a scan)",
      "unsupported_layout": "The statement layout is not supported; it needs a Date, Description, Debit and Credit table, or one amount column marked + or -",
      "row_unreadable": "A row could not be read",
      "row_ambiguous": "A row's money in or out is unclear",
      "too_many_rows": "The statement has more rows than this review supports",
      "conflicting_currency": "The statement states two different currencies",
      "conflicting_account_number": "The statement shows two different account numbers",
      "balance_contradiction": "The printed balances do not agree with the rows",
      "file_type_unsupported": "This file type or size is not supported",
      "file_content_mismatch": "The file contents do not match its type",
      "workbook_expansion_unsupported": "The workbook is too large to open safely",
      "row_limit": "The sheet has more rows than this review supports",
      "unreadable_file": "The file or sheet could not be read",
      "column_missing": "A required column is not chosen or not found",
      "account_confirmation_required": "Confirm the bank account first",
      "account_number_mismatch": "The account number in the file differs from the chosen account",
      "currency_mismatch": "The currency in the file differs from the chosen account",
      "currency_assumption_required": "Confirm the bank account currency",
      "total_unreadable": "A printed total could not be read",
      "total_contradiction": "The printed totals do not agree with the rows",
      "date_order_required": "Choose the printed date order",
      "date_order_contradiction": "The dates contradict the chosen date order",
      "date_unreadable": "A date could not be read",
      "mixed_day_order": "The file mixes day-first and month-first dates",
      "row_invalid": "A row has an invalid amount or description",
      "source_row_provenance_unavailable": "The source row positions could not be confirmed",
      "needs_review": "The file needs review",
      "atPageLine": "page {page}, line {row}",
      "atPage": "page {page}",
      "atRow": "row {row}",
      "mt940_invalid": "The MT940 file could not be read. Check the file or request a new export from your bank.",
      "mt940_unsupported": "This MT940 format is not supported yet. Ask your bank for a standard two-decimal MT940 export.",
      "mt940_multi_account": "This file holds statements for more than one account. Choose the file again and Groot will split it by account.",
      "mt940_limit": "This MT940 file exceeds the review limits. Request a smaller export from your bank.",
      "mt940_balance_difference": "The bank balances and movements do not agree. Check the source statement before importing.",
      "mt940_continuity_difference": "Consecutive statements do not carry the same balance forward. Check for a missing statement.",
      "mt940_dates_inconsistent": "The date gap in this file looks wrong. Check the source statement or request a new export from your bank.",
      "mt940Difference": "Statement {statement}: difference {difference}.",
      "mt940DateGap": "Line {row}: value date {valueDate}, entry date {entryDate}."
    },
    "transferArrival": {
      "title": "Transfer arrival",
      "prepared": "Prepared by the assistant. Check the details, then confirm. Nothing is posted until you confirm.",
      "historical": "This request is from an earlier conversation. Confirming checks the transfer and the statement line again first.",
      "checking": "Checking the transfer…",
      "route": "{from} to {to}",
      "arrivesIn": "Arrives in",
      "waitsIn": "Waits in",
      "dates": "Dates",
      "twoDates": "Left {outgoing}, arrived {arrival}",
      "statementLine": "Statement line",
      "effectLabel": "Journal entry",
      "effect": "Posts {amount} into {to} and clears it from {transit}, dated {date}. It is matched to this statement line. No new voucher.",
      "confirm": "Confirm arrival",
      "confirming": "Posting…",
      "posted": "Arrival recorded. The transfer is complete.",
      "failed": "We could not record the arrival. Nothing was posted. Try again.",
      "notAwaiting": "This transfer is no longer waiting for its arrival. Open Bank / Cash to see where it stands.",
      "changed": "This transfer changed after the assistant prepared it. Ask for a new preview.",
      "denied": "Only an owner or finance admin of this business can confirm this.",
      "unavailable": "This preview is no longer available.",
      "openBankCash": "Open Bank / Cash",
      "holds": {
        "TRANSFER_UNAVAILABLE": "This transfer is no longer available. Open Bank / Cash to review it.",
        "TRANSFER_ALREADY_COMPLETED": "This transfer has already arrived.",
        "DESTINATION_EVIDENCE_UNPROVEN": "That statement line no longer matches this transfer's amount, destination bank or a later date.",
        "DESTINATION_EVIDENCE_ALREADY_USED": "That statement line is already matched to something else.",
        "LINE_ANSWER_REQUIRED": "Answer the statement line's question with \"Transfer between my accounts\" before confirming.",
        "SOURCE_OWNER_REQUIRED": "This line may belong to an existing invoice, bill or payment. Open it in bank reconciliation instead.",
        "TRANSFER_DATE_UNPROVEN": "The statement line must be dated after the day the transfer left.",
        "TRANSFER_DATE_CHANGED": "The statement line's date differs from the date expected on this transfer. Correct the transfer first.",
        "generic": "This arrival could not be recorded yet. Nothing was posted. Open Bank / Cash to review the transfer.",
        "SOURCE_SEARCH_UNFINISHED": "Groot could not check every record for this bank line. Confirm the arrival in Bank / Cash.",
        "SOURCE_MATCH_CONFIRMATION_REQUIRED": "An existing record has the same amount as this bank line. Check it in Bank / Cash."
      }
    }
  },
  "bankLineSuggestion": {
    "provider": {
      "rules": "Rules",
      "jev": "Jev",
      "haiku": "Claude Haiku",
      "tokenrouter": "TokenRouter",
      "other": "Another source"
    },
    "route": {
      "bank_charge": "Bank charge",
      "bank_interest": "Bank interest",
      "own_transfer": "Transfer between my accounts",
      "customer_receipt": "Customer payment",
      "supplier_payment": "Supplier payment",
      "statutory_remittance": "Statutory payment",
      "other_expense": "Other expense",
      "other": "Other"
    },
    "bucket": {
      "p60": "60-69%",
      "p70": "70-79%",
      "p80": "80-89%",
      "p90": "90-100%",
      "unscored": "Not scored",
      "other": "Other"
    },
    "card": {
      "title": "Groot's suggestion",
      "route": "Looks like: {route}",
      "account": "Account: {account}",
      "by": {
        "ruleTenant": "Suggested by one of your rules",
        "ruleBuiltin": "Suggested by a built-in rule",
        "rule": "Suggested by a rule",
        "provider": "Suggested by {provider}"
      },
      "withModel": "{source} ({model})",
      "sure": "{percent}% sure",
      "notScored": "Not scored",
      "ruleMatched": "Matched \"{keyword}\" in the bank line.",
      "precedent": "{count, plural, one {Same payee confirmed # time: {account}} other {Same payee confirmed # times: {account}}}",
      "precedentNoAccount": "{count, plural, one {Same payee confirmed # time} other {Same payee confirmed # times}}",
      "useThis": "Use this"
    },
    "metrics": {
      "title": "Bank line suggestions",
      "subtitle": "Groot's suggestions on bank lines you completed in the last {days} days.",
      "windowLabel": "Period",
      "window": {
        "d30": "Last 30 days",
        "d90": "Last 90 days",
        "d365": "Last year"
      },
      "truncated": "This period holds more lines than can be read at once, so these figures cover the most recent lines only.",
      "unavailable": "Bank line suggestion figures are unavailable right now. This is not the same as having no completed lines. Try refreshing the page.",
      "emptyTitle": "No completed bank lines in the last {days} days",
      "emptyDescription": "A line is completed when you post it from the statement or match it to a record you already have in Bank / Cash. Once lines are completed, this shows how often Groot's suggestion was right.",
      "completed": "Lines completed",
      "withSuggestion": "With a suggestion",
      "accepted": "Accepted",
      "corrected": "Corrected",
      "acceptanceRate": "Acceptance rate",
      "unsure": "Groot was not sure",
      "unavailableLines": "Groot could not suggest",
      "ofCount": "{accepted} of {total}",
      "fewLines": "A percentage appears once there are at least {min} lines to measure.",
      "byProvider": "Who suggested",
      "byRoute": "What the line looked like",
      "byProbability": "How sure Groot was",
      "col": {
        "source": "Source",
        "route": "Type",
        "confidence": "Confidence",
        "suggested": "Suggested",
        "accepted": "Accepted",
        "corrected": "Corrected",
        "rate": "Accepted %"
      }
    }
  },
  "cashDirect": {
    "roles": {
      "bankCharges": "Bank charges",
      "bankChargesDesc": "Where fees your bank deducts are posted when you record a bank charge in Bank / Cash. Must be an operating expense, never cost of goods sold.",
      "transferInTransit": "Transfers in transit",
      "transferInTransitDesc": "Holds money moving between two of your own accounts when the banks record it on different days. Must be an asset that is not a bank or cash account.",
      "bankChargesNotSet": "Not set. Bank / Cash will refuse to record a bank charge until you pick an account.",
      "transferInTransitNotSet": "Not set. Transfers that the banks record on different days will be refused until you pick an account."
    },
    "settings": {
      "noIncomeAccounts": "No income account in your chart can take this yet.",
      "interestUsedByBankCash": "Bank / Cash also posts earned bank interest to this account."
    },
    "postsTo": "Posts to",
    "loading": "Loading",
    "offsetDenied": "You do not have access to this business's accounts.",
    "accountingDetails": "Accounting details",
    "accountingDetailsHint": "Only accounts that fit this purpose are listed.",
    "useSetting": "Use the setting",
    "noCompatibleAccounts": "No account in your chart fits this purpose.",
    "optionsIncomplete": "Your chart is too large to list here. Use the setting instead.",
    "openSettings": "Open Payment & posting",
    "source": {
      "role": "set on Payment & posting",
      "assignment": "set in Income type accounts",
      "override": "chosen in Accounting details"
    },
    "accountsEmpty": "No bank or cash accounts yet. Add one in Bank accounts first.",
    "evidenceDenied": "You do not have access to this bank's statement lines.",
    "evidenceEmpty": "No unmatched statement lines for this bank.",
    "destinationLine": "Destination statement line",
    "destinationLineLater": "Not arrived yet",
    "destinationLineHint": "Pick the other bank's credit line if it has already arrived. Its date is the arrival date.",
    "stagedPreview": "The amount waits in Transfers in transit until you confirm the arrival from the other bank's statement.",
    "twoEntriesPreview": "This posts two dated journal entries.",
    "previewTitle": "What will post",
    "preview": {
      "cashAccount": "Bank or cash account",
      "destination": "Destination",
      "transit": "Waits in",
      "amount": "Amount",
      "dates": "Dates",
      "twoDates": "Leaves {outgoing}, arrives {incoming}",
      "arrivalLater": "Leaves {outgoing}, arrival confirmed later",
      "voucher": "Voucher",
      "entries": "Journal entries",
      "oneEntry": "1 journal entry",
      "twoEntries": "2 dated journal entries",
      "existingRecords": "Existing records",
      "sourceSearchConfirmed": "You confirmed this money is not already recorded as an invoice, bill, claim, expense or transfer.",
      "setAside": "Set aside: {records}",
      "noCustomerReceipt": "An internal document for your files. No customer Official Receipt is issued."
    },
    "voucher": {
      "PV": "Payment voucher (PV)",
      "PCV": "Petty cash voucher (PCV)",
      "noneTransfer": "None. A transfer between your own accounts gets no voucher.",
      "RV": "Receipt voucher (RV)",
      "numberingOff": "None. {family} numbering is switched off in Business Settings, Documents.",
      "voidLabel": "Void"
    },
    "inTransitTotal": "In transit: {amount} in {count, plural, one {# transfer} other {# transfers}}",
    "awaitingRoute": "{from} to {to}",
    "waitingIn": "Waiting in {account}",
    "arrivalLine": "Arrival statement line",
    "arrivalPreview": "Posts {amount} into {to} and clears it from {transit}, dated {date}.",
    "confirmArrival": "Confirm arrival",
    "arrivalPosted": "Arrival recorded. The transfer is complete.",
    "arrivalFailed": "We could not record the arrival. Nothing was posted. Try again.",
    "holds": {
      "BANK_CHARGES_ACCOUNT_NOT_SET": "Choose where bank charges post: set Bank charges on Payment & posting.",
      "BANK_CHARGES_ACCOUNT_INCOMPATIBLE": "The Bank charges setting points at an account that is not an operating expense. Update it on Payment & posting.",
      "INTEREST_INCOME_ACCOUNT_NOT_SET": "Choose where bank interest posts: set Interest income in Income type accounts on Payment & posting.",
      "INTEREST_INCOME_ACCOUNT_INVALID": "The Interest income account can no longer take postings. Choose it again in Income type accounts.",
      "TRANSFER_TRANSIT_ACCOUNT_MISSING": "Set Transfers in transit on Payment & posting before recording a transfer that arrives on a later day.",
      "TRANSIT_INCOMPATIBLE": "Transfers in transit must be an active asset account that is not a bank or cash account. Update it on Payment & posting.",
      "TRANSFER_FX_TREATMENT_REQUIRED": "These accounts use different currencies. A transfer between currencies needs an exchange-rate treatment, which is not supported yet.",
      "OFFSET_INCOMPATIBLE": "That account does not fit this purpose. Pick one from Accounting details or use the setting.",
      "TRANSFER_DESTINATION_UNAVAILABLE": "Choose another of your own active bank accounts as the destination.",
      "TRANSFER_DESTINATION_EVIDENCE_REQUIRED": "Choose the matching credit line from the destination bank's statement, answered as a transfer between your own accounts.",
      "TRANSFER_DATE_UNPROVEN": "Pick the destination statement line so its date shows when the money arrived.",
      "DIRECT_CURRENCY_UNSUPPORTED": "This account is not in your home currency. Bank / Cash posts home-currency movements only for now.",
      "LINE_ANSWER_REQUIRED": "Answer what this statement line is for before recording it.",
      "SOURCE_OWNER_REQUIRED": "This line may belong to an existing invoice, bill or payment. Open it in bank reconciliation instead.",
      "SOURCE_EVIDENCE_UNPROVEN": "The selected statement line no longer matches the amount, date or account. Choose a current line.",
      "REQUEST_EFFECT_CONFLICT": "These details changed after the last review. Review them again.",
      "REVIEW_ACCESS_DENIED": "Only an owner or finance admin of this business can record this.",
      "REVIEW_UNAVAILABLE": "We could not prepare this review. Nothing was posted. Try again.",
      "DESTINATION_EVIDENCE_UNPROVEN": "That line does not match this transfer's amount, destination bank or a later date.",
      "DESTINATION_EVIDENCE_ALREADY_USED": "That statement line is already matched to something else.",
      "TRANSFER_ALREADY_COMPLETED": "This transfer has already arrived.",
      "TRANSFER_UNAVAILABLE": "This transfer is no longer available. Refresh the page.",
      "generic": "Review the details and try again.",
      "CASH_SOURCE_ALREADY_USED": "This statement line already has a recorded movement. Open it in the Cash Book instead of recording it again.",
      "SOURCE_SEARCH_UNFINISHED": "Groot could not check every existing invoice, bill, claim, expense and transfer for this line, so it cannot rule out one that already records this money. If you are sure, tick the box below and review again.",
      "SOURCE_MATCH_CONFIRMATION_REQUIRED": "These records have the same amount as this line, but nothing else links them. If the line is none of them, tick the box below and review again.",
      "SOURCE_EVIDENCE_NOT_REVIEWED": "This line came from a statement import that was never reviewed, so it cannot evidence a posting. It stays in Bank reconciliation."
    },
    "summaryOkExceptOptional": "All {total} required posting accounts are set. Not set yet: {names}. Actions that need them will be refused until you pick an account.",
    "sourceSearchConfirm": "I have checked: this money is not already recorded as an invoice, bill, claim, expense or transfer.",
    "sourceMatchConfirm": "I have checked: this money is none of the records listed and is not already recorded as an invoice, bill, claim, expense or transfer.",
    "sameAmountRecords": "Records with the same amount",
    "evidenceNotReviewed": "{count} older bank line(s) are not offered: their statement import was never reviewed, so they cannot evidence a posting. They stay in Bank reconciliation."
  },
  "bankCashRecon": {
    "status": {
      "draft": "Draft"
    },
    "errors": {
      "statementStale": "This bank line changed. Close this sheet, open the line again and review it.",
      "lineGone": "This bank line or its bank account is no longer available. Refresh the list.",
      "bankLinkUnresolved": "Link this bank account to its cash account in Manage accounts, then try again.",
      "statementAmountInvalid": "This bank line's amount cannot be matched. Check the imported statement line.",
      "entryGone": "That journal entry is not available. Refresh the suggestions and choose again.",
      "entryNotPosted": "Only a posted journal entry can be matched. Post or recover the entry first.",
      "cashLegUnavailable": "The Cash Book and this journal entry disagree. Open the entry and check it before matching.",
      "currencyReview": "The bank line and the journal entry are in different currencies. Review the currency before matching.",
      "amountMismatch": "The journal entry's amount or direction differs from this bank line. Choose an entry with the same amount.",
      "entryAlreadyMatched": "That journal entry is already matched to another bank line. Unmatch that line first.",
      "lineAlreadyMatched": "This bank line is already matched. Unmatch it first if the match is wrong.",
      "legUnresolved": "That entry has an older whole-entry match. Unmatch the older line first, then match again.",
      "legAmbiguous": "That journal entry moves this bank account more than once. Match it from the Cash Book review or correct the entry.",
      "entryNotOnBank": "That journal entry does not touch this bank account's ledger account, so it cannot be what this bank line paid or received. Choose an entry that moves this bank account.",
      "historyReview": "This line has a long match history. Ask your accountant to review it before matching.",
      "statementReview": "This line is labelled or classified. Clear the label or the suggestion first.",
      "draftRecoveryFirst": "This line has a draft journal from the old classify step. Discard or post that draft first.",
      "splitInvalid": "Choose at least two different entries for a split match.",
      "splitTotal": "The selected entries do not add up to the bank line amount to the cent.",
      "suggestionClosed": "This suggestion is no longer open. Someone may have already accepted or rejected it.",
      "draftReasonRequired": "Write a reason of at least 10 characters before creating a draft journal.",
      "draftRoleRequired": "Only an owner or finance admin can create a draft journal from a bank line.",
      "noClassification": "This line has no suggested accounts. Choose the debit and credit accounts.",
      "browserRequired": "A signed-in reviewer must confirm this in the browser.",
      "labelTransition": "This label cannot change while the line has a match or a journal. Review the line first.",
      "matchFailed": "We could not match this bank line. Nothing was changed. Try again.",
      "splitFailed": "We could not save this split match. Nothing was changed. Try again.",
      "draftFailed": "We could not create the draft journal. Nothing was changed. Try again.",
      "rejectFailed": "We could not reject this suggestion. Try again.",
      "unmatchFailed": "We could not unmatch this bank line. Try again.",
      "labelFailed": "We could not change this line's label. Try again."
    },
    "reason": {
      "reference": "Reference and amount match",
      "dateProximity": "Amount matches, dates within 3 days",
      "amount": "Amount matches",
      "other": "Suggested match",
      "description": "similar description",
      "paymentLeg": "matched on the amount paid"
    },
    "sheet": {
      "exactDateLegs": "Posted bank movements on this date",
      "legSearchIncomplete": "Some posted movements on this date could not be checked yet. You can still match an entry from the list below."
    },
    "panel": {
      "title": "Review bank line",
      "draftStateTitle": "Draft journal from the old classify step",
      "draftStateBody": "This line has a draft journal. It is not posted and does not reconcile the line. Open it to post it, or discard it and choose a route below.",
      "openDraft": "Open draft journal",
      "discardDraft": "Discard draft",
      "alreadyMatched": "This bank line is matched to an existing posting.",
      "reviewedActions": "Choose what this bank line is",
      "reviewedActionsHint": "Nothing is posted until you confirm on the next screen.",
      "matchTitle": "Match existing",
      "matchBody": "The payment or receipt is already recorded. Link this line to it. No new journal is created.",
      "matchAction": "Find a match",
      "createTitle": "Create",
      "createBody": "Nothing records this yet. Create it where it belongs; that step posts, numbers and reconciles it at once.",
      "createInterest": "Bank interest",
      "createTransferIn": "Transfer from my other account",
      "createCustomerReceipt": "Customer payment",
      "createBankCharge": "Bank charge",
      "createTransferOut": "Transfer to my other account",
      "createSupplierPayment": "Supplier payment",
      "createBankCashHint": "Opens this line in Bank / Cash review.",
      "createNeedsReviewedImport": "Available for statements imported through the reviewed upload. Use Match existing for this line.",
      "createReceivablesHint": "Open the customer's invoice, record a payment of {amount} and choose this bank credit as evidence.",
      "createPayablesHint": "Open the supplier's bill, record a payment of {amount} and choose this bank line.",
      "holdTitle": "Hold",
      "holdQuestionIn": "What is this {amount} coming in for? Which invoice, interest credit or transfer?",
      "holdQuestionOut": "What is this {amount} going out for? Which bill, bank charge or transfer?",
      "holdNote": "Nothing is posted. The line stays in Needs review until you answer.",
      "holdAction": "Keep on hold",
      "suggestionTitle": "Suggested accounts (not posted)",
      "debitShort": "Dr",
      "creditShort": "Cr",
      "dismissSuggestion": "Dismiss suggestion",
      "draftExceptionTitle": "Create a draft journal (exception)",
      "draftExceptionToggle": "None of these fit? Create a draft journal instead",
      "draftExceptionBody": "For owners and finance admins only. This creates a DRAFT journal. It does not post and does not reconcile the line until someone posts it.",
      "draftReasonLabel": "Why can this line not use Match existing or Create?",
      "draftReasonHelp": "At least {min} characters ({count} so far). Saved in the audit trail.",
      "draftReasonTooShort": "Write a reason of at least {min} characters.",
      "draftAccountsIncomplete": "Choose both accounts, or leave both empty to use the suggestion.",
      "draftAccountsHint": "Leave both empty to use the suggested accounts.",
      "useSuggested": "Use the suggested account",
      "createDraft": "Create draft journal",
      "creatingDraft": "Creating draft...",
      "suggestion": {
        "heading": "Groot's suggestion",
        "sure": "{percent}% sure",
        "reasonJev": "{percent}% {name}",
        "reasonJevNext": "{percent}% {name}, next {percent2}% {name2}",
        "notScored": "Not scored",
        "notScoredHint": "This suggestion has no confidence score. Check it before you use it.",
        "attributionJev": "Suggested by Jev ({modelId})",
        "attributionJevNoModel": "Suggested by Jev",
        "attributionHaiku": "Suggested by Claude Haiku ({modelId})",
        "attributionHaikuNoModel": "Suggested by Claude Haiku",
        "attributionFallback": "Suggested by a fallback AI model ({modelId})",
        "attributionFallbackNoModel": "Suggested by a fallback AI model",
        "ruleMatched": "Matched the rule: {keyword}",
        "accountingDetail": "Accounting detail",
        "unsureHeading": "Groot is not sure about this one",
        "unsureModelUnknown": "The description does not clearly point to one account.",
        "unsureBelowGate": "The best guess was too weak to suggest.",
        "unsureOrdersDisagree": "Two readings of this line chose different accounts, so Groot is not suggesting either.",
        "unsureClosest": "Closest account considered, not used: {name} ({percent}%)",
        "unsureChoose": "Choose how to record this line below.",
        "unavailableHeading": "Groot could not suggest an account for this line",
        "unavailableChartTooLarge": "Your chart has more accounts than Groot can read at once. Add a rule for this kind of line instead.",
        "unavailableServiceDown": "The suggestion service did not answer. Use Find suggestions again from the toolbar.",
        "unavailableNoAccounts": "Your chart has no accounts Groot can suggest.",
        "dismissed": "You dismissed the suggestion for this line.",
        "routePill": "Suggested",
        "routeStatutory": "This looks like a payroll remittance. Use Match existing to link the payroll entry.",
        "routeOtherExpense": "This looks like an ordinary expense. Record it in Other Expenses.",
        "routeOtherExpenseLink": "Open Other Expenses",
        "routeOther": "Groot could not tell how this should be recorded. Choose Match existing or one of the options below.",
        "ruleMatchedYours": "Your rule: {keyword}",
        "precedent": "{count, plural, one {Same payee confirmed # time: {name}} other {Same payee confirmed # times: {name}}}",
        "routeStatutoryLink": "Open Payroll"
      },
      "accept": {
        "button": "Accept this suggestion",
        "hint": "You will see the journal and confirm it before anything is posted.",
        "preparing": "Preparing the review...",
        "changed": "This line changed while you were looking. Check it and try again.",
        "failed": "Groot could not prepare this review. Try again, or open the line in Bank / Cash.",
        "openBankCash": "Open this line in Bank / Cash",
        "posted": "Posted.",
        "postedReconciled": "Posted and reconciled."
      },
      "ruleOffer": {
        "title": "Make this a rule",
        "body": "{count, plural, one {# earlier line with {keyword} was recorded to {name}.} other {# earlier lines with {keyword} were recorded to {name}.}}",
        "action": "Always use this for lines like this",
        "saving": "Saving...",
        "saved": "Rule saved. It applies from the next Find suggestions or import.",
        "errors": {
          "limitReached": "You have reached the limit on rules. Delete one you no longer need in Rules, then try again.",
          "keywordUnusable": "These words cannot be used as a rule. Add your own rule in Rules instead."
        }
      }
    },
    "dashboard": {
      "draftPendingRecovery": "{count, plural, one {# bank line has} other {# bank lines have}} a draft journal from the old classify step. They are not posted. Open each line to post or discard its draft.",
      "postedUnverified": "{count, plural, one {# line is} other {# lines are}} labelled posted but could not be checked against the ledger. Open the line to confirm its journal."
    },
    "row": {
      "review": "Review this line",
      "sure": "{percent}% sure",
      "badgeSuggested": "Suggested",
      "badgeRule": "Rule",
      "badgeNotSure": "Not sure",
      "badgeNoSuggestion": "No suggestion"
    },
    "needsReview": {
      "recoverDraft": "Open this line in reconciliation",
      "actionsLabel": "Review actions",
      "matchExisting": "Match existing",
      "matchExistingHint": "Link to a payment or receipt already recorded. No new journal.",
      "create": "Create",
      "createBankCashIn": "Bank interest or transfer in",
      "createBankCashOut": "Bank charge or transfer out",
      "createCustomerReceipt": "Customer payment",
      "createSupplierPayment": "Supplier payment",
      "createBankCashHint": "Bank / Cash review posts and reconciles it in one step.",
      "createSourceHint": "Record the {amount} payment on the invoice or bill and choose this bank line.",
      "hold": "Hold",
      "holdQuestionIn": "What is this {amount} coming in for?",
      "holdQuestionOut": "What is this {amount} going out for?",
      "holdNote": "Nothing is posted while this line is on hold.",
      "holdSensitive": "Owner funding and other receipts stay on hold until your accountant reviews them."
    },
    "unmatchConfirm": {
      "title": "Unmatch this statement line?",
      "line": "{date}, {amount}, {description}",
      "lineWithReference": "{date}, {amount}, {description} (ref {reference})",
      "lineDateAmount": "{date}, {amount}",
      "message": "This statement line is matched to {document}: {line}. Unmatching returns the line to Unmatched. {document} stays in the books until you correct it.",
      "messageNoDocument": "This statement line is matched to a posting: {line}. Unmatching returns the line to Unmatched. The posting stays in the books until you correct it.",
      "confirm": "Unmatch"
    },
    "rules": {
      "title": "Bank statement rules",
      "intro": "Your own rules are tried first, then Groot's built-in rules, then Groot suggests an account. Switching a built-in off sends those lines to Groot's suggestion instead.",
      "suggestOnly": "Rules only suggest an account. Nothing is posted from a rule, and you still review every line.",
      "loading": "Loading rules...",
      "denied": {
        "title": "You cannot see these rules",
        "body": "Your role does not include bank statement rules. Ask an owner or finance admin."
      },
      "yours": {
        "heading": "Your rules",
        "count": "{n} of {limit}",
        "empty": "You have no rules yet.",
        "add": "Add rule",
        "truncated": "This business has more rules than can be shown here, so this list and the built-in switches may be incomplete.",
        "readOnly": "You can see these rules, but only an owner or finance admin can change them."
      },
      "row": {
        "wholeWord": "Whole words only",
        "priority": "Priority {n}",
        "inactive": "Switched off",
        "legacyMoved": "Money moved from {from} to {to}",
        "legacyUnknownAccount": "an unknown account",
        "legacyHelp": "Created before rules could be edited. Delete it and add a new one.",
        "editLabel": "Edit the rule for {keyword}",
        "deleteLabel": "Delete the rule for {keyword}"
      },
      "direction": {
        "out": "Money out",
        "in": "Money in",
        "both": "Money in or out"
      },
      "problem": {
        "archived": "This rule is not being used: its account is archived. Choose another account.",
        "heading": "This rule is not being used: its account is now a group heading. Choose another account.",
        "missing": "This rule is not being used: its account no longer exists. Choose another account."
      },
      "form": {
        "addTitle": "Add a rule",
        "editTitle": "Edit rule",
        "keywordLabel": "Words to look for",
        "keywordHelp": "At least {min} letters or digits, up to {max} characters.",
        "directionLabel": "This applies to",
        "directionOut": "Money out (a payment)",
        "directionIn": "Money in (a receipt)",
        "accountLabel": "Account Groot should suggest",
        "accountPlaceholder": "Choose an account",
        "wholeWordLabel": "Match whole words only",
        "wholeWordHelp": "Off: the words can also match inside a longer word.",
        "priorityLabel": "Priority (optional)",
        "priorityHelp": "Leave blank: the longest words win. A higher number is tried first.",
        "save": "Save rule",
        "saving": "Saving..."
      },
      "errors": {
        "keywordTooShort": "The words need at least {min} letters or digits.",
        "keywordTooLong": "The words can be at most {max} characters.",
        "duplicate": "You already have a rule for these words in this direction. Edit that one instead.",
        "limitReached": "You have reached the limit of {limit} rules. Delete one you no longer need first.",
        "accountNotPostable": "That account cannot be used. Choose an active account that is not a group heading.",
        "priorityInvalid": "Priority must be a whole number from 0 to {priorityMax}.",
        "notFound": "This rule no longer exists. It may have been deleted already.",
        "notEditable": "This rule cannot be edited. Delete it and add a new one.",
        "builtinUnknown": "That built-in rule is not available any more. Reload the page and try again.",
        "browserRequired": "Rules can only be changed in the signed-in app.",
        "generic": "Something went wrong and nothing was changed. Please try again."
      },
      "delete": {
        "title": "Delete this rule?",
        "message": "Lines with {keyword} will no longer be suggested by it. Nothing already recorded changes.",
        "confirm": "Delete rule"
      },
      "builtin": {
        "heading": "Built-in rules",
        "labels": {
          "epf": "EPF / KWSP",
          "socso": "SOCSO / PERKESO",
          "eis": "EIS (employment insurance)",
          "pcb": "PCB (monthly tax deduction)",
          "bankCharge": "Bank charges",
          "bankInterest": "Bank interest earned",
          "ownAccount": "Transfers between your own accounts"
        },
        "unknownLabel": "Built-in rule",
        "suggests": "Suggests: {name}",
        "notUsedYet": "Not used yet: set the {setting} in Payment & posting.",
        "settings": {
          "statutoryPayable": "statutory payables account",
          "bankCharges": "bank charges account",
          "interestIncome": "interest income account"
        },
        "openSettings": "Open Payment & posting",
        "needsOtherBank": "Needs another bank account linked to your chart",
        "usesOtherBank": "{n, plural, one {Uses your other bank account (#)} other {Uses your other bank accounts (#)}}",
        "statutoryHint": "Lines show a hint to record the remittance in Payroll.",
        "on": "On",
        "off": "Off",
        "switchLabel": "Built-in rule on or off: {label}"
      }
    },
    "closingProof": {
      "title": "Statement closing balance vs your books",
      "loading": "Checking this statement against your books",
      "loadFailed": "We could not check this statement against your books just now. Nothing was changed. Please try again.",
      "checking": "Checking...",
      "checkAgain": "Check again",
      "bankLine": "{name} ending {last4} ({currency})",
      "statementPicker": "Statement",
      "statementOption": "{fileName} ({from} to {to})",
      "statementOptionNoClosing": "{fileName} ({from} to {to}, no closing balance)",
      "headline": {
        "agrees": "Agrees with your books at {date}",
        "explained": "Differs by {amount}, and every cent is explained below",
        "unexplained": "{amount} is not explained",
        "unexplainedUnknown": "Part of the difference is not explained",
        "explainedOpeningImplied": "Differs by {amount}. This statement printed no opening balance, so part of this difference cannot be checked against the bank's own figures: check the closing balance and the imported lines."
      },
      "unexplainedParts": {
        "statementDoesNotAdd": "{amount}: the imported lines do not add up to the balances printed on the statement",
        "amountsDiffer": "{amount}: an amount in your books is different from the statement line",
        "noBookEntry": "{amount}: statement lines that have no matching entry in your books"
      },
      "rows": {
        "caption": "Statement closing balance compared with your books",
        "statementClosing": "Statement closing balance",
        "sourcePrinted": "from the PDF",
        "sourceEntered": "entered by you",
        "booksAt": "Books balance at {date}",
        "booksAtLastLine": "Books balance as at the last statement line, {date}",
        "booksAtEntered": "Books balance at {date}, the date you entered",
        "difference": "Difference",
        "differenceNote": "statement minus books",
        "sourceEnteredReadOnly": "typed in by an owner or finance admin"
      },
      "explain": {
        "heading": "Why they differ",
        "opening": "Difference when the statement started",
        "openingStatementPrinted": "Statement opening balance {amount}, printed on the statement",
        "openingStatementImplied": "Statement opening balance {amount} (implied from the closing balance and the lines)",
        "openingBooks": "Books balance before {date}: {amount}",
        "onStatement": "On the statement, not in your books yet",
        "inBooks": "In your books, not on the statement",
        "elsewhere": "Booked in another period",
        "unexplained": "Not explained",
        "total": "Adds up to the difference",
        "withCount": "{label} ({count})"
      },
      "group": {
        "andMore": "and {count} more"
      },
      "item": {
        "reversed": "Reversed",
        "statementDate": "Statement {date}",
        "bookedDate": "Booked {date}"
      },
      "ties": {
        "ok": "The imported lines add up to the printed opening and closing balances",
        "no": "The imported lines do not add up to the printed opening and closing balances.",
        "noAmount": "{amount} of the difference comes from this.",
        "heldStillAdds": "{count, plural, one {# row of the file was withheld, and the lines still add up} other {# rows of the file were withheld, and the lines still add up}}",
        "held": "{count, plural, one {# row of the file was withheld from the import} other {# rows of the file were withheld from the import}}"
      },
      "cannotProve": {
        "title": "Cannot be compared with your books yet",
        "openCashBook": "Open the Cash Book",
        "askAdmin": "An owner or finance admin can enter the closing balance shown on the statement.",
        "statementName": "Statement: {fileName} ({from} to {to})",
        "reasons": {
          "no_statement": "No bank statement has been imported for this account yet. Import a statement to compare its closing balance with your books.",
          "no_closing_balance": "This statement does not show a closing balance, so it cannot be compared with your books yet.",
          "no_lines": "This statement has no lines in Groot, so it cannot be compared with your books.",
          "bank_not_linked": "This bank account is not linked to a Cash at Bank account in your chart, so there is no books balance to compare. Link it in Bank accounts to prove it.",
          "foreign_currency": "This bank account is in a foreign currency, and Groot cannot prove a foreign currency balance against your books yet.",
          "books_not_ready": "The Cash Book for this bank account has not finished building, so your books balance cannot be read yet. Open the Cash Book and check again in a moment.",
          "books_mixed_currency": "Your books hold this bank account in more than one currency, so its balance cannot be proven.",
          "too_many_legs": "This statement period has too many book entries to check at once, so it cannot be proven here.",
          "lines_unreadable": "Some lines of this statement could not be read, so it cannot be proven right now. Check again in a moment.",
          "unknown": "This statement cannot be compared with your books yet.",
          "books_inconsistent": "The Cash Book for this bank account does not add up to itself, and rebuilding it will not fix that. Please contact support so it can be checked."
        }
      },
      "entry": {
        "heading": "Enter the closing balance from the statement",
        "balanceLabel": "Closing balance",
        "balanceHint": "As shown on the statement, for example 1234.56. Use a minus sign if the account is overdrawn.",
        "asAtLabel": "As at date",
        "asAtHint": "The date the statement ends. It cannot be earlier than the last statement line or in the future.",
        "save": "Save",
        "saving": "Saving...",
        "cancel": "Cancel",
        "change": "Change",
        "remove": "Remove",
        "removing": "Removing...",
        "enteredNote": "You entered this closing balance yourself.",
        "invalidNumber": "Enter the closing balance as a number with up to 2 decimals, for example 1234.56.",
        "invalidDate": "Enter a valid date.",
        "changeClosing": "Change the closing balance"
      },
      "errors": {
        "browserRequired": "The closing balance can only be changed in the signed-in app.",
        "printedExists": "This statement already prints its own closing balance, so it cannot be changed here.",
        "invalid": "That closing balance is not valid. Enter it as a number, for example 1234.56.",
        "dateInvalid": "That date does not fit this statement. It cannot be earlier than the last statement line or in the future.",
        "sessionNotFound": "This statement is no longer available. Refresh the page and try again.",
        "generic": "Something went wrong and nothing was changed. Please try again."
      }
    }
  },
  "bankImportRecovery": {
    "retractButton": "Retract import",
    "retractTooltip": "Retract this import if it went into the wrong account or was the wrong file",
    "retractedBadge": "Retracted",
    "retractedSummary": "Retracted {date}",
    "retractedBy": "by {name}",
    "retractedReason": "Reason: {reason}",
    "dialog": {
      "title": "Retract this statement import",
      "intro": "Use this when a statement went into the wrong bank account or was the wrong file. Its lines are withdrawn from this account and kept in the audit trail. The file can then be imported into the right account.",
      "checking": "Checking whether anything has used this import...",
      "unavailable": "This import could not be checked. Close this window and try again.",
      "notReviewed": "This older upload has no reviewed statement behind it. Remove it with Delete in Upload history.",
      "retracted": "This import was retracted on {date}.",
      "eligible": "Nothing from this import has been matched, posted or used in a cash document. {count} imported line(s) will be withdrawn from this account.",
      "suggestionsCleared": "{count} unconfirmed match suggestion(s) will be cleared.",
      "answersKept": "{count} review answer(s) stay in the audit trail with their lines.",
      "reusedKept": "{count} line(s) this statement shared with an earlier import stay with that import.",
      "managerOnly": "Only an owner or finance admin can retract an import.",
      "reasonLabel": "Reason",
      "reasonPlaceholder": "For example: imported into the savings account by mistake",
      "reasonHint": "Recorded in the audit trail. Between 3 and 500 characters.",
      "confirm": "Retract import",
      "retracting": "Retracting...",
      "cancel": "Cancel",
      "close": "Close",
      "blockedTitle": "This import cannot be retracted yet"
    },
    "blocked": {
      "posted": "{count} line(s) from this import were posted to your books. Reverse those entries first, then retract.",
      "receipted": "{count} line(s) back an issued Official Receipt. Reverse that customer payment first, then retract.",
      "cashDocument": "{count} line(s) back a cash document. Reverse that cash document first, then retract.",
      "payout": "{count} line(s) are matched to a platform payout. Unmatch the payout first, then retract.",
      "matched": "{count} line(s) are matched. Unmatch them in Bank reconciliation first, then retract.",
      "reused": "{count} line(s) were reused by a later statement import. Retract that later import first.",
      "unprovable": "This import has more links than can be checked here. Contact support to retract it.",
      "linkInvalid": "This import's records do not agree with each other. Contact support before changing it.",
      "cashSaleReceipted": "{count} line(s) back a cash sale's Official Receipt. Unmatch the line in Bank reconciliation, void the cash sale, then retract."
    },
    "success": "Import retracted. You can now import the file into the right account.",
    "successAlready": "This import was already retracted.",
    "errors": {
      "generic": "Couldn't retract this import. Please try again.",
      "reasonRequired": "Enter a reason between 3 and 500 characters.",
      "notPermitted": "Only an owner or finance admin can retract an import.",
      "browserRequired": "Retract the import yourself in the signed-in app. The assistant cannot do it for you.",
      "notFound": "That import could not be found.",
      "changed": "Something used this import after you opened this window. Check what is blocking it and try again."
    },
    "alreadyImported": "This file is already imported. An owner or finance admin can retract that import from Upload history, then import the file into the right account.",
    "mappingLocked": "This statement is imported, so its account and mapping are locked. If it went to the wrong account, retract it from Upload history and import it again."
  },
  "vouchers": {
    "receipt": {
      "title": "Receipt Voucher",
      "internalNotice": "Internal document. Not an Official Receipt.",
      "receivedFrom": "Received from",
      "voucherNumber": "Voucher No.",
      "voucherNumberBlank": "Voucher number cleared; write it in by hand",
      "receiptDate": "Date",
      "bankReference": "Bank reference",
      "bankReferenceBlank": "No bank reference; write it in by hand",
      "receivedTheSumOf": "Received the sum of",
      "receivedInto": "Received into",
      "receivedFor": "Received for",
      "preparedBy": "Prepared by",
      "checkedBy": "Checked by",
      "approvedBy": "Approved by",
      "glReference": "Journal entry {entryNumber}",
      "registrationNumber": "Reg. No. {value}",
      "voidBadge": "Void",
      "voidReasonEntryReversed": "The receipt entry behind this voucher was reversed",
      "voidReasonEntryDeleted": "The journal entry behind this voucher was deleted",
      "voidReasonManual": "Voided manually"
    }
  },
  "cashSaleBankCredit": {
    "label": "Bank credit (for the Official Receipt)",
    "help": "Optional. Choose the credit on this bank's imported statement that paid for this sale, so its Official Receipt records the bank match. The sale is then dated on the statement date.",
    "placeholder": "Select a bank credit",
    "option": "{date} · {description} · {amount}",
    "none": "No imported credit for {amount} on this bank's statement. The sale still gets its Official Receipt, and you can match the bank line later.",
    "noCredit": "No bank credit chosen. The sale still gets its Official Receipt, and a later bank match is recorded on it.",
    "willIssue": "Posting will issue an Official Receipt, evidenced by the bank credit of {date}.",
    "clear": "Post without a bank credit",
    "linkedHint": "From Bank / Cash: a bank credit of {amount} on {date}. Add the items so the sale total equals it.",
    "linkedPreselected": "Selected from the bank line you opened in Bank / Cash. Check it before you post the sale.",
    "linkedNotOffered": "The bank credit you opened from Bank / Cash is not in this list, so nothing was selected. It may already be matched, or its amount or bank account differs from this sale.",
    "errors": {
      "notApplicable": "A bank credit can only be chosen for a cash sale received into a linked bank account while Official Receipts are on. Post the sale without it.",
      "dateMismatch": "The sale date must be the bank credit's statement date. Choose the credit again.",
      "evidenceInvalid": "That bank credit does not match this sale. Check the amount, currency and bank account, and that it comes from a reviewed statement import.",
      "evidenceUsed": "That bank credit is already matched to another record. Choose a different credit, or post the sale without one.",
      "evidenceSuggested": "Bank Reconciliation already suggests that credit for another entry. Review the suggestion there first, or post the sale without it.",
      "matchUnproven": "The bank credit and the sale posting did not agree, so nothing was posted. Try again, or contact support if it keeps happening.",
      "orUnavailable": "An Official Receipt could not be issued, so the sale was not posted. Contact support."
    }
  },
  "cashSaleReceipt": {
    "label": "Official Receipt",
    "voidLabel": "Void",
    "noneWithReason": "No Official Receipt: {reason}",
    "unavailable": "Official Receipt status could not be loaded.",
    "reasons": {
      "OR_SETTING_OFF": "Official Receipts are off for this business",
      "OR_NOT_ISSUED_AT_POSTING": "not issued when the sale was posted"
    },
    "voidMatched": {
      "title": "Unmatch the bank line first",
      "body": "This cash sale's bank leg is matched in Bank reconciliation. Unmatch it there, then void the sale.",
      "link": "Open Bank reconciliation"
    }
  },
  "officialReceiptDocument": {
    "title": "Official Receipt",
    "receivedInto": "Received into",
    "bankCredit": "Bank credit",
    "bankCreditValue": "{date} · {description}",
    "print": "Print",
    "printNotLogged": "The receipt printed, but the print could not be recorded.",
    "denied": "You do not have access to this Official Receipt.",
    "unavailable": "This Official Receipt could not be found.",
    "internalTitle": "Internal details",
    "internalNote": "Only your team sees this. It is not on the customer's copy.",
    "internalEvidence": "How the money was confirmed"
  },
  "stockValueDishCosts": {
    "title": "Stock overview",
    "description": "Current stock value and product costs. Monthly platform sales and fees are shown separately below.",
    "month": "Reporting month",
    "refresh": "Refresh",
    "loading": "Reading stock and posted sales",
    "error": "We could not load these figures. Try Refresh again.",
    "loadTitle": "Stock overview",
    "loadDescription": "Figures load automatically when your business is ready.",
    "currencyNote": "All money is in your home currency ({currency}).",
    "asOf": "Current stock as of {date}.",
    "unknown": "Unknown",
    "incompleteTitle": "Incomplete figures",
    "incompleteDescription": "Some records could not be included. Totals shown as Unknown are incomplete, so do not use them to reconcile or assess profit.",
    "stock": {
      "total": "Current stock value",
      "unknownCount": "{count} stock balances could not be valued. Known value: {amount}.",
      "books": "Inventory ledger balance",
      "booksUnavailable": "The current Inventory account balance could not be read.",
      "difference": "Difference",
      "differenceHelp": "Stock value minus ledger balance. Check receipts, opening balances and adjustments if these differ. This snapshot is not a certified reconciliation.",
      "title": "Current stock",
      "description": "Current quantities and weighted average costs across all locations. Unit costs keep up to six decimal places.",
      "empty": "No stock balances yet",
      "item": "Stock item",
      "location": "Location",
      "quantity": "Quantity on hand",
      "unitCost": "Average unit cost",
      "value": "Value",
      "itemUnavailable": "Stock item unavailable",
      "unitUnavailable": "Unit unknown",
      "booksAccountMissing": "The Inventory account is not ready for posting. Check Posting accounts under Accounting, Chart of Accounts.",
      "booksLimit": "Inventory history is too large to total here. Contact support to check the books balance.",
      "totalHelp": "Quantity on hand × average unit cost, across all locations.",
      "booksHelp": "Balance recorded in your Inventory account.",
      "fifoCaption": "Costed first in, first out. Each value follows the cost of the layers still on the shelf.",
      "differenceRounding": "This difference is cent rounding. Each posting is rounded to the cent, so a few cents either way is expected."
    },
    "dishes": {
      "title": "Product costs",
      "description": "Current stock-input cost per sales unit, based on on-sale formulas. Margin compares this cost with sale price before platform fees, labour and overhead. Available units are estimates for each product; products can share the same stock.",
      "location": "Product costs and available units at {location}.",
      "locationUnavailable": "Choose a default active stock location to calculate product costs and available units. Separate locations are not combined.",
      "chooseLocation": "Open locations",
      "empty": "No active Sales Products yet",
      "openFormulas": "Open sale formulas",
      "item": "Product",
      "price": "Sale price",
      "cost": "Stock cost per unit",
      "margin": "Margin before other costs",
      "portions": "Available units",
      "limiting": "Limiting input",
      "formula": "Formula",
      "status": {
        "active": "Active",
        "missing": "No formula",
        "blocked": "Needs attention"
      },
      "addFormula": "Set up formula",
      "checkFormula": "Check formula & costs",
      "portionsHelp": "Reserved or unavailable stock is excluded. Estimates are per product, not a combined production plan.",
      "costFifoHint": "Cost of the layers a portion would take next."
    },
    "period": {
      "title": "Monthly platform sales & fees",
      "description": "The month filters posted platform activity and recorded stock cost. Stock and product costs above always show the current position.",
      "foodCost": "Recorded stock cost",
      "itemsSoldCount": "From {count} posted Items Sold batches.",
      "contribution": "Payout less stock cost",
      "contributionHelp": "Net settlement less recorded stock cost. Excludes other business costs; this is not profit. Compare only when Items Sold and platform imports cover the same sales and month. This view does not match the two sources automatically.",
      "empty": "No posted platform imports for this month",
      "emptyDescription": "Review and post the platform statement in Daily Sales to include its money here.",
      "openDailySales": "Open Daily Sales",
      "platform": "Platform",
      "grossSales": "Gross sales",
      "discounts": "Discounts",
      "refunds": "Refunds",
      "commission": "Commission",
      "marketing": "Marketing / ads",
      "otherCharges": "Other charges",
      "paymentProcessing": "Payment fees",
      "deliveryCost": "Delivery costs",
      "netPayout": "Net payout",
      "feePercent": "Fees / gross sales",
      "postedCount": "Based on {count} posted platform records.",
      "currencyMismatch": "{count} records have a different currency and were excluded. These period totals are incomplete.",
      "unclassifiedFees": "Platform fees (no breakdown)",
      "notRecorded": "Not recorded",
      "noItemsSold": "No Items Sold batches posted for this month.",
      "platformTaxes": "Provider tax included",
      "taxHelp": "Fee amounts and Fees / gross sales include provider taxes. Provider tax included is shown for reference and is already part of those fees; do not add it again.",
      "coverageWarning": "{count} posted Items Sold lines had no formula. Recorded stock cost: {amount}. Full stock cost and payout after stock cost are unknown. Review Items Sold and formulas."
    },
    "platforms": {
      "pos": "POS",
      "grabfood": "GrabFood",
      "foodpanda": "Foodpanda",
      "shopee": "Shopee",
      "other": "Other"
    },
    "help": {
      "trigger": "How stock overview works",
      "title": "How these figures work",
      "description": "Current stock and product costs, with monthly platform sales shown separately.",
      "step1": "Stock figures load automatically. Stock value and product costs always describe the current position. The month selector affects only the monthly platform section.",
      "step2": "Compare current stock value with the inventory ledger balance. A difference is a prompt to check receipts, opening balances and adjustments; this screen changes no accounting entries.",
      "step3": "Use product costs to review sale prices and formulas. Use monthly platform results to review sales, commission and marketing. Platform fees are not assigned to individual products.",
      "unknown": "A cost, price, formula or stock quantity is missing. Unknown is not zero.",
      "incomplete": "A read limit or incompatible source record prevented a complete calculation. Do not treat the visible rows as the whole business.",
      "tip": "Available units exclude reserved or unavailable stock. They are per-product estimates, not a plan to make every product at once. Several products can use the same stock input.",
      "settings": "Open Stock settings"
    },
    "roleDenied": "Only the business owner or finance admin can view these figures. Ask a business owner for access.",
    "monthInvalid": "Choose a month from 1900 to 9999."
  },
  "stockTransfer": {
    "title": "Transfer stock",
    "subtitle": "Move stock from one location to another, for example to top up the online store from HQ.",
    "fields": {
      "item": "Stock item",
      "itemPlaceholder": "Choose a stock item",
      "from": "From",
      "fromPlaceholder": "Choose where it is now",
      "to": "To",
      "toPlaceholder": "Choose where it goes",
      "quantity": "Quantity",
      "date": "Date",
      "note": "Reference or note",
      "notePlaceholder": "Optional, for example Restock online store"
    },
    "fromOption": "{location} · {available} available",
    "toOption": "{location} · {onHand} on hand",
    "quantityHint": "Up to {available} available. Reserved and unavailable stock stays where it is.",
    "preview": {
      "title": "After the transfer",
      "line": "{location}: {before} to {after}"
    },
    "valueNote": "Moves at {location}'s average cost of {cost} each. No journal entry is posted, because both locations are part of the same Inventory account.",
    "submit": "Transfer {quantity}",
    "submitIdle": "Transfer",
    "saving": "Transferring...",
    "errors": {
      "quantityInvalid": "Enter a quantity greater than zero.",
      "quantityTooHigh": "Only {available} available at {location}.",
      "sameLocation": "Choose two different locations.",
      "insufficient": "Not enough stock is available at that location any more. Check the quantity and try again.",
      "locationNotFound": "One of these locations is no longer active. Choose another location.",
      "notStockItem": "Only stock items can be transferred.",
      "requestReused": "This form was already used. Reopen it and try again.",
      "dateInvalid": "Choose a transfer date that is today or earlier.",
      "noteTooLong": "Keep the note under 200 characters.",
      "generic": "The transfer could not be saved. Nothing was moved. Please try again."
    },
    "toast": {
      "successTitle": "Stock transferred",
      "successBody": "Moved {quantity} {item} from {from} to {to}."
    },
    "empty": {
      "needLocationsTitle": "Add a second location first",
      "needLocationsBody": "A transfer moves stock between two locations, and this business has only one.",
      "addLocation": "Add a location",
      "noStockTitle": "No stock to transfer yet",
      "noStockBody": "Stock appears here once it has been received or entered as opening stock."
    },
    "howItWorks": {
      "trigger": "How stock transfers work",
      "title": "How stock transfers work",
      "intro": "A transfer moves units of one stock item from one of your locations to another, for example from HQ to the online store when online runs low.",
      "step1": "Choose the stock item and the location it is in now. You can move up to what is available there.",
      "step2": "Choose where it goes and how many. The preview shows both locations before and after.",
      "step3": "Confirm. Both locations update at once, and Activity shows the transfer as two lines: out of one location and into the other.",
      "costTerm": "Cost",
      "costMeaning": "Units move at the average cost they were carried at in the location they leave. The receiving location's average is re-blended, so the total stock value does not change.",
      "ledgerTerm": "No journal entry",
      "ledgerMeaning": "Both locations are part of the same Inventory account, so a transfer changes where stock is, not what it is worth. Nothing is posted to the ledger.",
      "reservedTerm": "Reserved stock",
      "reservedMeaning": "Units reserved for orders or marked unavailable stay where they are."
    }
  },
  "salesNotes": {
    "kind": {
      "credit_note": "Credit note",
      "debit_note": "Debit note",
      "refund_note": "Refund note"
    },
    "adjusts": "for invoice",
    "originalInvoiceFallback": "Original invoice",
    "draftExplainer": "This note is already in your books. Issue it to send it to the customer or file it with LHDN.",
    "issue": "Issue note",
    "issueAndSend": "Issue and send",
    "issuing": "Issuing...",
    "issuedTitle": "Note issued",
    "issuedDescription": "{number} is issued. You can now send it to the customer.",
    "issueFailedTitle": "Could not issue the note",
    "emailNote": "Email to customer",
    "status": {
      "draft": "Draft",
      "issued": "Issued",
      "void": "Void"
    },
    "list": {
      "laneCustomer": "Customer",
      "laneSupplier": "Supplier",
      "partyColumn": "Customer or supplier"
    },
    "errors": {
      "notANote": "This is an invoice, not a credit or debit note. Issue it from the invoice screen.",
      "typeNotIssuable": "Only a credit note or a debit note can be issued here.",
      "void": "This note has been voided, so it cannot be issued or sent.",
      "notDraft": "Only a draft note can be issued. Refresh the page to see its current status.",
      "notIssued": "Issue this note before sending it to the customer.",
      "originalMissing": "The invoice this note adjusts could not be found.",
      "originalVoid": "The invoice this note adjusts has been voided, so the note cannot be issued. Void the note instead.",
      "postingNotActive": "This note's journal entry is no longer posted, so the note cannot be issued. Void it instead.",
      "filedWithLhdn": "This note has been filed with LHDN. Cancel it with LHDN first, or raise the opposite note against the same invoice to reverse it.",
      "notEditable": "A credit or debit note is posted when it is raised, so it cannot be edited. Void it and raise a new note instead.",
      "issueFailed": "The note could not be issued. Refresh the page and try again.",
      "noCustomerEmail": "This customer has no email address on file. Add one to the customer to send the note.",
      "lhdnFilingInProgress": "This note is being filed with LHDN right now. Wait for the result, then try again."
    }
  },
  "stockFifoReversal": {
    "errors": {
      "alreadyRestored": "These goods have already been put back into stock, so there is nothing left to reverse. Nothing was changed.",
      "layerFull": "The stock layer these goods came from is already full, so they cannot be put back into it. Nothing was changed.",
      "restockLocationMismatch": "With first-in first-out costing, returned goods go back to the location they were sold from. Restock them there, then move them with a stock transfer. Nothing was changed.",
      "assemblyLayerConsumed": "The stock made for this sale has already been used or sold since, so it cannot be taken back out. Nothing was changed."
    }
  },
  "customerCredit": {
    "panelTitle": "Customer credit",
    "panelDescription": "The amount this credit note gave back beyond what its invoice still owed. Refund it to the customer, or apply it to another of their open invoices.",
    "panelDescriptionRefundOnly": "The amount this credit note gave back beyond what its invoice still owed. This customer is not in your Customer Directory, so the credit can be refunded but not applied to another invoice.",
    "openCredit": "Open credit",
    "ofTotal": "of {total} on this credit note",
    "noOpenCredit": "No open credit. The invoice still owed at least this much, or the credit has already been refunded or applied.",
    "ineligible": {
      "NOT_A_CREDIT_NOTE": "Only a credit note's credit can be refunded or applied.",
      "NOTE_VOID": "This credit note is void.",
      "NOTE_NOT_POSTED": "This credit note has not been posted to the ledger, so its credit cannot be refunded or applied.",
      "FOREIGN_CURRENCY": "Refunding or applying a foreign-currency credit is not supported yet. Record it as a journal entry with the exchange difference.",
      "PARENT_NOT_SETTLED": "The invoice this credit note was raised against is not open or settled."
    },
    "refund": "Refund",
    "applyToInvoice": "Apply to invoice",
    "history": "Refunds and applications",
    "historyEmpty": "Nothing refunded or applied yet.",
    "historyTruncated": "Showing the latest 100.",
    "kind": {
      "refund": "Refund",
      "application": "Applied"
    },
    "appliedTo": "Applied to {number}",
    "paidFrom": "Paid from {account}",
    "reference": "Ref {reference}",
    "status": {
      "active": "Active",
      "reversed": "Reversed"
    },
    "reversedReason": "Reversed: {reason}",
    "reverseRefund": "Reverse refund",
    "unapply": "Unapply",
    "voidLabel": "Void",
    "journalEntry": "Journal {number}",
    "method": {
      "bank_transfer": "Bank transfer",
      "cash": "Cash",
      "cheque": "Cheque",
      "card": "Card",
      "other": "Other (payment gateway, e-wallet)"
    },
    "refundDialog": {
      "title": "Refund customer credit",
      "description": "Records the money paid back to {customer}. The accounts follow the payment method, the same accounts customer receipts arrive in. A payment gateway's clearing account appears under Other once it is set on Payment & posting.",
      "amount": "Amount",
      "amountHelp": "Up to {amount}",
      "date": "Refund date",
      "method": "Paid by",
      "account": "Paid from",
      "accountHelp": "The bank, cash or clearing account the money left.",
      "reference": "Reference",
      "referencePlaceholder": "Transfer or gateway refund reference",
      "notes": "Notes",
      "cancel": "Cancel",
      "submit": "Record refund",
      "submitting": "Recording",
      "success": "Refund recorded"
    },
    "applyDialog": {
      "title": "Apply customer credit",
      "descriptionFromNote": "Moves credit from {note} onto another open invoice of the same customer. Both sit in receivables, so no cash moves.",
      "descriptionFromInvoice": "Uses credit this customer already holds to settle {invoice}. No cash moves.",
      "invoice": "Invoice",
      "invoicePlaceholder": "Choose an open invoice",
      "invoiceOption": "{number}, {balance} owed",
      "creditNote": "Credit note",
      "creditNotePlaceholder": "Choose a credit note",
      "creditNoteOption": "{number}, {credit} open",
      "amount": "Amount",
      "amountHelp": "Up to {amount}",
      "date": "Apply date",
      "noInvoices": "This customer has no open invoice in {currency}.",
      "noCredits": "This customer holds no open credit in {currency}.",
      "loading": "Loading",
      "truncated": "This customer has a very long history. Only the most recent documents are listed.",
      "cancel": "Cancel",
      "submit": "Apply credit",
      "submitting": "Applying",
      "success": "Credit applied"
    },
    "reverseDialog": {
      "titleRefund": "Reverse this refund?",
      "titleUnapply": "Unapply this credit?",
      "descriptionRefund": "Posts the exact reverse of the refund on its own date and voids its payment voucher. The credit becomes open again. Use this when the refund did not go through or was recorded by mistake.",
      "descriptionUnapply": "Takes the credit off the invoice it was applied to. The invoice owes that amount again and the credit becomes open again.",
      "reason": "Reason",
      "reasonPlaceholder": "Why is this being undone?",
      "cancel": "Cancel",
      "submitRefund": "Reverse refund",
      "submitUnapply": "Unapply",
      "submitting": "Working",
      "success": "Reversed"
    },
    "invoiceApply": {
      "button": "Apply credit",
      "available": "{amount} credit available"
    },
    "debtorCard": {
      "title": "Open credits",
      "description": "Credit this customer holds from credit notes that exceeded what their invoices owed.",
      "fromInvoice": "from {number}",
      "open": "Open"
    },
    "inCredit": "In credit",
    "errors": {
      "generic": "Could not save this. Try again, or contact support if it keeps happening.",
      "exceedsOpen": "That is more than the open credit on this credit note.",
      "exceedsTarget": "That is more than the invoice still owes.",
      "notPosted": "This credit note has not been posted to the ledger.",
      "foreignCurrency": "Refunding or applying a foreign-currency credit is not supported yet. Record it as a journal entry with the exchange difference.",
      "wrongCustomer": "That invoice belongs to a different customer.",
      "targetCurrency": "That invoice is in a different currency.",
      "targetNotOpen": "That invoice has nothing left to pay.",
      "targetIsSource": "Choose a different invoice from the one this credit came from.",
      "dateBeforeNote": "A refund cannot be dated before the credit note.",
      "dateBeforeDocument": "Credit cannot be applied before both the credit note and the invoice exist.",
      "dateInvalid": "Enter a valid date.",
      "reconciled": "This refund is matched to a bank line. Unmatch it in Bank reconciliation first.",
      "requestConflict": "This was already submitted with different details. Refresh and try again.",
      "settlementsActive": "This document has an active customer credit refund or application. Reverse the refund or unapply the credit first.",
      "paymentAccountRequired": "Choose the account the refund was paid from. If the list is empty, set the accounts for this payment method on Payment & posting.",
      "paymentAccountNotAllowed": "That account cannot be used for this payment method. Pick one from the list.",
      "customerRequired": "This credit note's invoice has no directory customer, so its credit can only be refunded.",
      "ledgerMismatch": "This document's journal entry does not name one receivable account, so its credit cannot be moved. Contact support.",
      "amountNotPositive": "Enter an amount greater than zero.",
      "reasonRequired": "Enter a reason, up to 500 characters.",
      "notFound": "This credit note or entry could not be found. Refresh the page.",
      "historyCap": "This invoice has too much credit history to settle safely. Contact support.",
      "textTooLong": "Keep this to 500 characters or fewer."
    }
  },
  "supplierNotePaper": {
    "title": {
      "credit": "The supplier's credit note",
      "debit": "The supplier's debit note"
    },
    "help": "Attach the page the supplier sent. It is kept with the note.",
    "attached": "Attached: {name}",
    "remove": "Remove",
    "uploadFailed": "That file could not be uploaded. Try again, or capture the note without it.",
    "loading": "Loading...",
    "uploading": "Uploading the document. Capture waits until it is attached.",
    "date": {
      "credit": "Credit note date",
      "debit": "Debit note date"
    },
    "dateRequired": "Enter the date printed on the supplier's note."
  },
  "officialReceiptIssue": {
    "errors": {
      "OR_PAYMENT_REVERSED": "This payment was reversed, so it cannot receive an Official Receipt.",
      "OR_PAYMENT_PENDING_CLEARANCE": "This cheque or GIRO has not cleared yet. Its Official Receipt is issued when you mark it cleared.",
      "OR_PAYMENT_NOT_CLEARED": "This cheque or GIRO bounced or was cancelled, so it cannot receive an Official Receipt.",
      "OR_EXTERNAL_RECEIPT_OF_RECORD": "The customer already holds a receipt from another system for this payment, so Groot does not issue one.",
      "OR_SETTING_OFF": "Official Receipts are turned off for this business. An owner can turn them on in Sales invoice settings.",
      "OR_PAYMENT_ALREADY_NUMBERED": "This payment already has Official Receipt {receiptNumber}.",
      "OR_NOT_CUSTOMER_PAYMENT": "Only a customer payment can receive an Official Receipt.",
      "OR_POSTING_UNPROVEN": "This payment has no posted ledger entry, so an Official Receipt cannot be issued. Contact support.",
      "OR_CLEARANCE_MATCH_UNPROVEN": "This payment's bank match changed while the receipt was being issued. Refresh and try again.",
      "OR_SNAPSHOT_SOURCE_UNAVAILABLE": "A document this payment settled could not be read, so no Official Receipt was issued. Contact support.",
      "OR_ISSUER_UNAUTHORIZED": "Only an owner, finance admin or manager can issue an Official Receipt.",
      "BROWSER_CONFIRMATION_REQUIRED": "Issue the Official Receipt yourself, signed in to Groot in your browser.",
      "generic": "The Official Receipt could not be issued. Refresh the page and try again."
    }
  },
  "officialReceiptActions": {
    "download": "Download PDF",
    "downloading": "Preparing PDF...",
    "send": "Send receipt",
    "sending": "Sending...",
    "sendTitle": "Send Official Receipt {number}",
    "sendDescription": "The receipt is emailed as a PDF attachment.",
    "emailLabel": "Send to",
    "emailPlaceholder": "name@company.com",
    "noEmailOnFile": "Customer has no email address on file. Enter one to send the receipt.",
    "invalidEmail": "Enter a valid email address, for example name@company.com.",
    "sentTo": "Receipt sent to {email}.",
    "alreadySentTo": "This receipt was already sent to {email}. No second email was sent.",
    "voidNotSendable": "This receipt is void and cannot be sent.",
    "history": {
      "title": "Earlier sends",
      "state": {
        "accepted": "Sent",
        "pending": "Sending",
        "failed": "Failed",
        "review": "Needs review"
      }
    },
    "evidence": {
      "user_confirmed": "Confirmed by user",
      "cash_leg": "Cash received",
      "bank_matched": "Matched to bank line",
      "cheque_cleared": "Cheque cleared",
      "gateway_confirmed": "Confirmed by payment gateway"
    },
    "errors": {
      "invalidRecipient": "That email address is not valid. Check it and try again.",
      "noRecipient": "Customer has no email address on file. Enter one to send the receipt.",
      "void": "This receipt is void and cannot be sent.",
      "blocked": "An earlier send of this receipt is still unresolved, so it cannot be sent again yet. Contact support if this does not clear.",
      "unknown": "We could not confirm that the email was delivered. Do not send it again yet; check back shortly.",
      "failed": "The receipt email could not be sent. Try again in a moment.",
      "notFound": "This receipt could not be found. Refresh the page and try again.",
      "signedOut": "Your session has ended. Sign in again, then try again.",
      "generic": "The receipt could not be sent. Try again in a moment.",
      "pdfFailed": "The receipt PDF could not be downloaded. Try again in a moment.",
      "network": "We couldn't reach the server. Check your connection and try again."
    }
  },
  "officialReceiptHistory": {
    "issue": "Issue Official Receipt",
    "issuing": "Issuing...",
    "issued": "Official Receipt {receiptNumber} issued.",
    "externalReceipt": "Receipt: {system} {reference}"
  },
  "einvoiceApplicability": {
    "title": "Does e-invoicing apply to you?",
    "intro": "Malaysia's e-invoice rules depend on your annual turnover and your group. Answer once and Groot tells you where you stand. This is guidance only: nothing in Groot is blocked by it.",
    "bandLabel": "Annual turnover or revenue",
    "band": {
      "under_3m": "Under RM3 million",
      "3m_to_5m": "RM3 million to RM5 million",
      "over_5m": "Over RM5 million"
    },
    "relatedPartyLabel": "A non-individual shareholder, a holding company, or a related company or joint venture of mine has annual turnover of RM3 million or more.",
    "relatedPartyHelp": "If this applies, the under RM3 million exemption does not cover you.",
    "yearLabel": "Year turnover first reached RM3 million (optional)",
    "yearPlaceholder": "e.g. 2026",
    "yearHelp": "From 2026 onwards, e-invoicing starts on 1 January of the second year after that year. Leave blank if it was before 2026 or you are not sure.",
    "yearInvalid": "Enter a year from {min} to {max}.",
    "state": {
      "exempt": "E-invoicing is optional for you",
      "relaxation": "E-invoicing applies, with the interim relaxation",
      "mandatory": "E-invoicing is mandatory for you",
      "unknown": "Not answered yet"
    },
    "reason": {
      "unknown": "Choose your turnover band above to see whether e-invoicing applies to you.",
      "exemptUnder3m": "Turnover under RM3 million is exempt from issuing e-invoices, including self-billed e-invoices, and your receipts remain proof of expense. You may still issue them.",
      "notYetInEffect": "E-invoicing is not required of you yet. You may still issue e-invoices before the start date.",
      "relaxation": "E-invoicing is mandatory for your turnover band, but the interim relaxation lets you use consolidated e-invoices and consolidated self-billed e-invoices, and you need not issue an individual e-invoice on a buyer's request if you follow the consolidated route.",
      "relaxationRelatedParty": "Your turnover is under RM3 million, but a related company or shareholder is at RM3 million or more, so the exemption does not apply. The interim relaxation lets you use consolidated e-invoices and consolidated self-billed e-invoices.",
      "mandatory": "E-invoicing is mandatory for you and the interim relaxation no longer applies. Issue an individual e-invoice for each sale unless a consolidated e-invoice circumstance applies, and self-bill where required.",
      "mandatoryRelatedParty": "A related company or shareholder is at RM3 million or more, so the exemption does not apply, and the interim relaxation has ended. Issue an individual e-invoice for each sale unless a consolidated e-invoice circumstance applies, and self-bill where required."
    },
    "effectiveFrom": "Applies from {date}.",
    "relaxationEnds": "The interim relaxation runs to {date}.",
    "reference": "Guideline reference: {ref}",
    "readOnlyNote": "Only the owner or a finance admin can change these answers.",
    "save": "Save answers",
    "saving": "Saving...",
    "savedTitle": "E-invoice applicability saved",
    "savedDescription": "Your answers were saved.",
    "saveErrorTitle": "Could not save your answers",
    "saveErrorDescription": "Please try again in a moment.",
    "advisory": {
      "optional": "E-invoicing is optional for your business, so you can file this invoice or skip it.",
      "review": "Review applicability"
    }
  },
  "reportKit": {
    "errors": {
      "exportFailed": "The report could not be exported. Please try again.",
      "sendFailed": "The report could not be sent. Please try again.",
      "tooLarge": "This report is too large to email. Download it instead.",
      "forbidden": "Only managers, finance admins and owners can email reports.",
      "nothingToExport": "There is nothing to export yet.",
      "recipientNotAllowed": "Reports can only be emailed to you or to members of this business. Invite the person to the business first.",
      "dailyLimit": "This business has reached its daily limit for emailed reports. Try again tomorrow, or download the report instead."
    },
    "pdf": {
      "page": "Page",
      "of": "of",
      "generatedBy": "Generated {date} by {name}",
      "currency": "Currency",
      "criteria": "Criteria"
    },
    "headline": {
      "ariaLabel": "Key figures"
    },
    "exceptions": {
      "nothingNeedsAttention": "Nothing needs attention",
      "toReview": "{count} to review",
      "warn": "Warning",
      "bad": "Problem",
      "open": "Open"
    },
    "filter": {
      "ariaLabel": "Report period",
      "from": "From",
      "to": "To",
      "invalidRange": "The start date must not be after the end date.",
      "presets": {
        "thisMonth": "This month",
        "lastMonth": "Last month",
        "thisQuarter": "This quarter",
        "lastQuarter": "Last quarter",
        "thisFy": "This financial year",
        "lastFy": "Last financial year",
        "last12Months": "Last 12 months",
        "custom": "Custom"
      }
    },
    "output": {
      "ariaLabel": "Report outputs",
      "pdf": "Download PDF",
      "excel": "Download Excel",
      "email": "Email this report",
      "generating": "Preparing..."
    },
    "email": {
      "title": "Email this report",
      "description": "The formal PDF is attached to the email.",
      "address": "Send to",
      "subject": "Subject",
      "message": "Message (optional)",
      "send": "Send",
      "sending": "Sending...",
      "cancel": "Cancel",
      "invalidEmail": "Enter a valid email address.",
      "subjectRequired": "Enter a subject.",
      "sent": "Report sent to {address}",
      "membersOnly": "You can send it to yourself or to a member of this business."
    }
  },
  "profitLossMonthly": {
    "view": {
      "label": "View",
      "period": "One period",
      "months": "12 months"
    },
    "compare": {
      "label": "Compare with last year"
    },
    "columns": {
      "account": "Account",
      "total": "Total",
      "percentOfSales": "% of net sales",
      "priorYear": "Last year",
      "change": "Change",
      "changePercent": "Change %"
    },
    "sections": {
      "operatingRevenue": "Net sales (revenue)",
      "costOfGoodsSold": "Cost of sales",
      "operatingExpense": "Operating expenses",
      "otherIncome": "Other income",
      "otherExpense": "Other expenses"
    },
    "subtotals": {
      "grossProfit": "Gross profit",
      "operatingProfit": "Operating profit",
      "netProfit": "Net profit"
    },
    "table": {
      "ariaLabel": "Profit and loss by account",
      "currencyNote": "All amounts are in {currency}",
      "wholePeriod": "the whole period",
      "expandSection": "Show the accounts in {section}",
      "collapseSection": "Hide the accounts in {section}",
      "drillAria": "{account}, {period}: show the entries",
      "better": "better than last year",
      "worse": "worse than last year",
      "hiddenLeading": "No entries from {first} to {last}"
    },
    "headline": {
      "netSales": "Net sales",
      "grossProfit": "Gross profit",
      "grossProfitWithMargin": "Gross profit, {margin} margin",
      "netProfit": "Net profit",
      "netProfitWithMargin": "Net profit, {margin} margin",
      "netSalesVsLastYear": "Net sales vs last year",
      "netProfitVsLastYear": "Net profit vs last year"
    },
    "exceptions": {
      "title": "Needs attention",
      "costOfSalesZero": "Cost of sales is zero: items sold have no stock cost yet",
      "lossMonths": "Net loss in {months}",
      "truncated": "Large period: figures are a floor, narrow the dates"
    },
    "states": {
      "loading": "Loading your profit and loss...",
      "empty": "No entries were posted in this period.",
      "retry": "Try again",
      "spanTooLong": "That range is too long. Choose {months} months or less.",
      "invalidDate": "Enter a valid date between 1990 and 2100."
    },
    "drill": {
      "subtitle": "Account {code}, {period}",
      "filtersNote": "Location and other filters do not narrow this list. It shows every entry posted to this account in the period.",
      "loading": "Loading the entries...",
      "refused": "Detail is available to owners and finance admins.",
      "error": "The entries could not be loaded. Please try again.",
      "empty": "No entries in this period.",
      "date": "Date",
      "entry": "Entry",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "totals": "Total",
      "net": "Net for this cell",
      "rollupNote": "This list also includes postings to any sub-accounts under this account, so its net can differ from the figure in the table ({amount})."
    },
    "criteria": {
      "location": "Location",
      "project": "Project",
      "department": "Department",
      "salesAgent": "Sales agent",
      "all": "All",
      "unassigned": "Unassigned"
    },
    "document": {
      "titlePeriod": "Profit and Loss",
      "titleMonths": "Profit and Loss, 12 months"
    },
    "period": {
      "to": "to"
    }
  },
  "profitability": {
    "group": {
      "label": "Group by",
      "customer": "Customer",
      "invoice": "Invoice",
      "product": "Product",
      "category": "Category",
      "channel": "Channel",
      "affiliate": "Affiliate",
      "lower": {
        "customer": "customer",
        "invoice": "invoice",
        "product": "product",
        "category": "category",
        "channel": "channel",
        "affiliate": "affiliate"
      }
    },
    "columns": {
      "customer": "Customer",
      "invoice": "Invoice",
      "product": "Product",
      "category": "Category",
      "channel": "Channel",
      "affiliate": "Affiliate",
      "secondary": {
        "invoice": "Customer",
        "product": "Category",
        "customer": "E-mail"
      },
      "quantity": "Qty",
      "sales": "Net sales",
      "cost": "Cost of goods",
      "profit": "Profit",
      "margin": "Margin",
      "share": "Share of sales",
      "referrals": "Referrals",
      "profitBeforeCommission": "Profit before commission",
      "commission": "Commission",
      "netContribution": "Net contribution",
      "netMargin": "Net margin",
      "orderNumber": "Order",
      "referralId": "Referral",
      "affiliateId": "Affiliate ID"
    },
    "headline": {
      "netSales": "Net sales",
      "quantity": "Quantity sold",
      "costOfGoods": "Cost of goods",
      "costOfGoodsPartial": "Cost of goods (costed lines only)",
      "profit": "Profit",
      "profitUnavailable": "Profit (not available)",
      "margin": "Margin",
      "costedProfit": "Profit on costed lines",
      "costedProfitWithMargin": "Profit on costed lines, {margin} margin",
      "notAvailable": "Not available",
      "profitUnavailableNotTracked": "Profit (cost not tracked)",
      "profitOnPnlBasis": "Profit on the Profit and Loss basis, {margin} margin",
      "profitOnProducts": "Profit on product lines",
      "marginOnProducts": "Margin on product lines (sales with no product left out)",
      "marginAllSales": "Margin on all sales, including sales with no product"
    },
    "exceptions": {
      "title": "Needs attention",
      "costMissing": "{count, plural, one {# sale line has} other {# sale lines have}} no recorded cost, {sales} of sales. Profit and margin are left blank for them, never shown as 100%. Add a stock formula or stock record for these products so their cost is recorded.",
      "truncated": "A single day held more sales documents than one read allows, so the figures are a floor. Narrow the dates.",
      "tieOutUnexplained": "Cost of goods differs from the Profit and Loss by {amount}, and stock movements do not explain {unexplained} of it.",
      "tieOutUnavailable": "The Profit and Loss figure could not be read, so cost of goods was not checked against it.",
      "excludedForeign": "{count, plural, one {# foreign-currency document has} other {# foreign-currency documents have}} no usable exchange rate and {count, plural, one {is} other {are}} left out of every figure.",
      "unmatchedReferrals": "{count, plural, one {# affiliate referral} other {# affiliate referrals}} could not be matched to a sales invoice, {amount} of commission.",
      "unmatchedReferralsAtLeast": "{count, plural, one {# affiliate referral} other {# affiliate referrals}} could not be matched to a sales invoice, at least {amount} of commission.",
      "affiliatePartial": "Affiliate commission is only partly linked to orders, so the affiliate figures cover the linked referrals only.",
      "affiliateUnavailableLegacy": "Affiliate commission bills are not linked to orders yet, so no affiliate figures can be shown.",
      "affiliateUnavailableFailed": "Affiliate commission could not be read, so no affiliate figures can be shown.",
      "voidedCommissionBills": "{count, plural, one {# commission bill is} other {# commission bills are}} voided or deleted and left out of the affiliate figures.",
      "unpostedCommissionBills": "{count, plural, one {# commission bill is} other {# commission bills are}} waiting for review and left out of the affiliate figures until confirmed.",
      "costNotTracked": "{count, plural, one {# sale line is an item} other {# sale lines are items}} for which Groot does not track a cost, {sales} of sales. Profit and margin are left blank for them, never shown as 100%.",
      "costUnmatched": "{count, plural, one {# refund line} other {# refund lines}} could not be matched to the invoice it credits, {sales} of sales. Profit and margin are left blank for them, never shown as 100%.",
      "noProduct": "{count, plural, one {# sale line has} other {# sale lines have}} no product, {sales} of sales ({share} of all sales). No stock leaves and no cost is recorded for them, so their profit equals their sales and lifts the margin. Pick a product from the catalogue on the invoice line to record cost."
    },
    "row": {
      "costMissing": "Cost missing",
      "costMissingTitle": "{count, plural, one {# sale line has} other {# sale lines have}} no recorded cost, {sales} of sales",
      "missing": "Missing",
      "noCostExpected": "no cost expected",
      "costNotTracked": "Cost not tracked",
      "notTracked": "Not tracked",
      "costNotTrackedTitle": "{count, plural, one {# sale line is an item} other {# sale lines are items}} for which Groot does not track a cost. {sales} of sales",
      "costUnmatched": "Original not found",
      "unmatched": "Not matched",
      "costUnmatchedTitle": "{count, plural, one {# refund line names} other {# refund lines name}} no invoice that can be found, so what it credits is not known. {sales} of sales"
    },
    "labels": {
      "uncategorised": "Uncategorised",
      "noCustomer": "No customer",
      "channelManual": "Manual invoice",
      "channelWoocommerce": "WooCommerce store",
      "noDescription": "No description"
    },
    "table": {
      "ariaLabel": "Profitability by {group}",
      "currencyNote": "Amounts in {currency}, net of discounts and excluding tax.",
      "showingFirst": "Showing the first {shown} of {count} rows. The total line covers all of them.",
      "showAll": "Show all {count} rows",
      "sortByMargin": "Sort by margin",
      "sortByNetMargin": "Sort by net margin",
      "total": "Total",
      "openInvoice": "Open invoice {number}"
    },
    "tieOut": {
      "tied": "Cost of goods {amount} ties to the Profit and Loss.",
      "explained": "Cost of goods {amount} differs from the Profit and Loss ({gl}) by {difference}. The measured causes are:",
      "unexplained": "Cost of goods {amount} differs from the Profit and Loss ({gl}) by {difference}. {unexplained} of that is not explained by stock movements or by any source listed here.",
      "unavailable": "Profit and Loss figure unavailable, so cost of goods was not checked against it.",
      "truncated": "The list of causes may be incomplete because a stock movement read hit its limit.",
      "componentLine": "{label}: {amount} ({count, plural, one {# item} other {# items}})",
      "beforeChannelCosts": "Cost of goods is before channel fees and affiliate commissions. Commissions the report can match to a linked bill are listed as their own cause; anything else posted to cost of sales would show up in the difference.",
      "filtered": "Cost of goods was not compared with the Profit and Loss because a customer or channel filter is on. The Profit and Loss cannot be filtered that way.",
      "components": {
        "relief_dated_outside_period": "Cost of documents in this period that left stock on a date outside it",
        "relief_for_documents_outside_period": "Cost that left stock in this period for documents dated outside it",
        "movements_not_matched_to_a_line": "Stock movements that could not be matched to a document line",
        "excluded_documents_without_rate": "Documents left out because a foreign invoice has no usable rate",
        "affiliate_commission_postings": "Affiliate commissions posted to cost of sales in this period",
        "relief_ledger_mismatch": "Stock relief on the movements differs from the cost of sales entries posted for it"
      },
      "componentLineOpposite": "{label}: {amount} in the other direction ({count, plural, one {# item} other {# items}})",
      "tiedWithItems": "Cost of goods {amount} from stock, plus {items} of cost of sales not linked to products, ties to the Profit and Loss ({gl}).",
      "itemsHeading": "Cost of sales not linked to products",
      "itemsTotal": "Total not linked to products",
      "itemsOther": "{count, plural, one {# more source} other {# more sources}}, {amount} in all, not listed",
      "itemColumns": {
        "document": "Document",
        "source": "Source",
        "date": "Date",
        "amount": "Cost"
      },
      "itemKinds": {
        "supplier_bill": "Supplier bill",
        "journal": "Journal",
        "stock_take": "Stock count",
        "items_sold": "Items sold",
        "expense": "Expense",
        "other": "Other posting"
      },
      "unreceived": "No goods from this bill were received into stock. If they are goods you sell or use, receive them into stock on the bill.",
      "openBill": "Open bill",
      "openEntry": "Open journal entry {number}"
    },
    "notTracked": {
      "title": "Cost is not tracked in Groot for this business",
      "body": "Stock is kept outside Groot, or Groot is used for invoicing only, so there is no cost of goods to compare with. Sales, quantity and share are shown. Cost, profit and margin appear here once Groot keeps your stock."
    },
    "affiliate": {
      "totalsLine": "Affiliate total",
      "notAdditive": "Affiliate figures are a separate view and are not added to the report total; sales without an affiliate are not in them.",
      "unmatchedHeading": "Referrals not matched to a sales invoice",
      "unmatchedMore": "and {count} more not listed",
      "empty": "No affiliate referrals are linked to a sales invoice in this period."
    },
    "states": {
      "loading": "Loading your profitability report...",
      "empty": "No sales documents in this period.",
      "loadError": "Couldn't load the profitability report. Please try again.",
      "noAccess": "You don't have permission to view the profitability report.",
      "noBusiness": "Select a business to view its profitability.",
      "retry": "Try again"
    },
    "howItWorks": {
      "title": "How the profitability report works",
      "intro": "See what each customer, invoice, product, category, channel or affiliate earned you, from sales and the cost of the stock that left for them.",
      "stepsHeading": "Steps",
      "step1Title": "Pick a period and a grouping",
      "step1Desc": "Choose the dates, then group the sales by customer, invoice, product, category, channel or affiliate. The link in the address bar keeps your choice.",
      "step2Title": "What Cost missing means",
      "step2Desc": "A product was sold but nothing left stock for it, so Groot cannot say what it cost. Its profit and margin stay blank instead of showing a 100% margin. Add a stock formula or stock record and the figure fills in.",
      "step3Title": "How it ties to the Profit and Loss",
      "step3Desc": "Under the table, cost of goods is compared with the cost of sales on the Profit and Loss for the same dates. Cost of sales that did not come from stock, such as a supplier bill never received into stock or a journal, is listed by source with its document number, so the two reports foot. Anything left is shown as not explained.",
      "step4Title": "How exports work",
      "step4Desc": "Use the output menu to download a PDF or an Excel file, or to email the PDF. They contain exactly what is on screen.",
      "goodToKnowHeading": "Good to know",
      "goodToKnow1": "Credit notes and refunds subtract from sales and cost. Voided invoices are left out.",
      "goodToKnow2": "Discounts, shipping, fees and other lines with no catalog item have no cost expected, so their profit equals their sales. A catalog item for which Groot does not track a cost shows Cost not tracked, with no profit or margin.",
      "goodToKnow3": "Amounts are in your home currency. A foreign-currency invoice uses its own exchange rate.",
      "goodToKnow4": "If Groot does not keep your stock, only sales, quantity and share are shown.",
      "goodToKnow5": "The affiliate view takes each affiliate's commission off their profit. It is a separate view and does not add to the report total."
    },
    "period": {
      "to": "to"
    },
    "document": {
      "title": "Profitability by {group}"
    },
    "criteria": {
      "groupedBy": "Grouped by"
    },
    "actions": {
      "howItWorks": "How it works"
    }
  },
  "stockFifoCosting": {
    "errors": {
      "changeLocked": "The costing method cannot be changed because stock has already moved. Your settings were not saved. Contact support to change it safely.",
      "notSupported": "That costing method is not available. Choose weighted average or first in first out (FIFO). Your settings were not saved.",
      "requiresBlockNegativeStock": "First in first out blocks sales that exceed stock, so the negative stock setting has to stay on Block. Your settings were not saved.",
      "unreadable": "The costing method saved for this business could not be read, so Groot did not guess. Nothing was changed. Contact support.",
      "layerScanLimit": "This item has too many separate receipts still on the shelf to work out its cost in one step. Nothing was changed. Contact support.",
      "costPlanMismatch": "The cost of the stock that moved did not match the cost that was planned, so nothing was saved. Refresh and try again. If it repeats, contact support.",
      "invalidAsAtDate": "The date is not valid. Enter a valid date and try again.",
      "supplierReturnLayerConsumed": "Some of the goods being returned are no longer in the stock that receipt put on the shelf, because part of it was already sold or moved. Return fewer units, or save the supplier credit note without returning stock and adjust the stock separately. Nothing was changed.",
      "supplierReturnLayerMissing": "Groot cannot find the stock this receipt put on the shelf, so it will not guess the cost the goods go back at. Save the supplier credit note without returning stock and adjust the stock separately, or contact support. Nothing was changed.",
      "preSwitchRecord": "This was recorded before the stock costing method changed to first-in, first-out, so it cannot be reversed this way. Nothing was changed. Record a stock adjustment instead, or contact support."
    }
  },
  "fxRates": {
    "title": "Currencies & rates",
    "subtitle": "Exchange rates published by Bank Negara Malaysia (BNM) every business day.",
    "howItWorks": "Groot uses these rates to post foreign-currency supplier bills, sales invoices, payments and receipts in your home currency, and to revalue open foreign balances at month end. When a payment or receipt settles a document at a different rate, the difference is booked as realised gain or loss. The rate side for each document type is listed below. On weekends and holidays the previous business day's rate applies, up to {days} days back.",
    "override": "A rate you record under Exchange rates below overrides BNM for its date.",
    "loading": "Loading BNM rates",
    "empty": "No BNM rates have been fetched yet. They are fetched once a day, after Malaysian business hours.",
    "latest": "Latest rates: {date}",
    "tableLabel": "BNM reference rates",
    "col": {
      "currency": "Currency",
      "per": "RM per",
      "buying": "Buying",
      "selling": "Selling",
      "middle": "Middle",
      "date": "Rate date"
    },
    "basis": {
      "title": "Rate side used for each document type",
      "ap": "Bills and supplier payments: {basis}",
      "ar": "Sales invoices and receipts: {basis}",
      "selling": "selling rate",
      "buying": "buying rate",
      "middle": "middle rate"
    },
    "attribution": "Source: Bank Negara Malaysia",
    "terms": "BNM terms of use",
    "sourceMark": {
      "short": "BNM · {date}",
      "label": "About this rate source",
      "type": "Rate type: {type}",
      "typeBoth": "buying and selling rates",
      "dateSession": "Rate date {date}, session {session}"
    }
  },
  "payablesFx": {
    "originalBeside": {
      "title": "Foreign supplier bills in this figure: {amount}, converted at the rate on each bill."
    },
    "owedLine": "owed {original} ({home} in the books)",
    "rateCaption": {
      "text": "{amount} at {rate}",
      "label": "About this rate",
      "sourceUser": "Rate entered on the bill",
      "sourceManual": "Rate from your Exchange rates table",
      "rateDate": "Rate date {date}"
    }
  },
  "inventoryReceiptBillErrors": {
    "legacyNativeBill": "This supplier bill was posted before exchange rates were recorded on bills, so its stock cannot be moved out of the expense at a home currency value. Nothing was changed. Record the stock with a stock adjustment instead.",
    "foreignBillNotPosted": "This supplier bill is in a foreign currency and is not posted yet, so there is no exchange rate to value its stock at. Post the bill first, then receive the items.",
    "currencyMismatch": "This supplier bill was posted in a different currency from the one you are receiving its stock in. Receive the items in the currency the bill was posted in. Nothing was changed.",
    "billBasisUnreadable": "Groot cannot read how this supplier bill was posted to its expense account, so it will not guess how much to move into stock. Nothing was changed. Contact support."
  },
  "fxRevaluation": {
    "headerTitle": "Revalue foreign balances",
    "title": "Revalue foreign balances",
    "subtitle": "Restate open foreign-currency bills, invoices and bank balances at the month-end closing rate. The entry reverses on the first day of the next month.",
    "backToPeriods": "Back to periods",
    "financeOnly": "Only an owner or finance admin can revalue foreign balances.",
    "monthEnd": "Month end",
    "monthEndHint": "Revaluation is done for a whole month, at its last day.",
    "loading": "Reading open foreign balances...",
    "unavailable": "We could not read the open foreign balances. Nothing was posted. Try again.",
    "retry": "Try again",
    "toast": {
      "posted": "Revaluation posted for {date}.",
      "unchanged": "Nothing has changed since the last run, so nothing was posted."
    },
    "liveRun": {
      "posted": "Posted on {date}.",
      "unchanged": "Posted on {date}. Nothing has changed since.",
      "periodEndEntry": "View month-end entry",
      "reversalEntry": "View reversal on {date}",
      "noEntries": "No difference, so no entry was needed.",
      "figures": "Posted: gain {gain}, loss {loss}.",
      "rates": "Rates used: {rates}.",
      "differs": "The figures below differ from this run: a rate or a document has changed since. Re-run replaces it."
    },
    "nothing": {
      "title": "Nothing to revalue at {date}",
      "body": "There are no open foreign-currency bills, invoices or bank balances. Mark this step not applicable and finish closing the period.",
      "action": "Mark not applicable and go back"
    },
    "rates": {
      "title": "Closing rates",
      "subtitle": "Payables use the selling rate; receivables and bank balances use the buying rate. Type a rate to use your own for a currency.",
      "totals": "Gain {gain}, loss {loss}",
      "side": {
        "ap": "Payables, selling",
        "ar": "Receivables, buying",
        "bank": "Bank, buying"
      },
      "typed": "Typed rate",
      "manual": "Manual rate of {date}",
      "missing": "No closing rate is on file for {currency} on or before {date}. {count} items are left out until you type one.",
      "override": "Use my own {currency} rate",
      "overrideAria": "Closing rate for {currency}",
      "overridePlaceholder": "e.g. 4.7250",
      "invalid": "Enter a rate greater than zero.",
      "recalculate": "Recalculate"
    },
    "items": {
      "title": "What will be revalued",
      "document": "Document",
      "party": "Supplier or customer",
      "outstanding": "Outstanding",
      "carried": "Carried ({currency})",
      "revalued": "At closing rate ({currency})",
      "difference": "Gain or loss",
      "noParty": "None",
      "type": {
        "bill": "Supplier bill",
        "sales_invoice": "Sales invoice",
        "bank_account": "Bank account"
      },
      "direction": {
        "gain": "Gain",
        "loss": "Loss"
      },
      "noNumber": "No number"
    },
    "excluded": {
      "legacyTitle": "{count} older foreign bills and invoices are left out",
      "unprovableTitle": "{count} items could not be checked against the books and are left out",
      "more": "and {count} more",
      "reason": {
        "LEGACY_NATIVE": "They were posted before foreign documents were converted at a fixed rate, so their home amount is not on record.",
        "NOTE_ADJUSTED": "It carries a credit or debit note",
        "LINE_UNPROVABLE": "Its posted line could not be found in the books",
        "PAYMENT_BASIS": "A payment on it has no recorded home amount",
        "BASIS_NOT_POSITIVE": "Its carried amount is not a positive balance",
        "BANK": "The bank account history is not complete enough to value",
        "OTHER": "The books could not confirm it"
      }
    },
    "truncated": {
      "body": "The read stopped early for: {sections}. Posting is turned off until the preview is complete, because a revaluation that leaves items out would be wrong.",
      "payables": "supplier bills",
      "receivables": "sales invoices",
      "banks": "bank accounts",
      "entry_lines": "journal lines",
      "other": "some records",
      "settlements_after_period": "payments and receipts dated after the period end (there are too many to check)",
      "receipts": "customer receipts (the history is too long to read)"
    },
    "totals": {
      "gain": "Unrealised gain",
      "loss": "Unrealised loss",
      "net": "Net"
    },
    "postHelp": "Posting adds one entry on the month end and its reversal on {date}, so your books return to the original amounts.",
    "rerunHelp": "Running it again reverses the earlier entries and posts new ones. The change is kept in the audit trail.",
    "recalculateFirst": "Recalculate to apply the rates you typed before posting.",
    "post": "Post revaluation",
    "rerun": "Re-run revaluation",
    "posting": "Posting...",
    "exposure": {
      "title": "Unrealised exposure by currency",
      "subtitle": "Open foreign balances and the unrealised gain or loss at the closing rates on file.",
      "unavailable": "We could not read the exposure. Try again.",
      "empty": "No open foreign balances at {date}.",
      "currency": "Currency",
      "payables": "Payables",
      "receivables": "Receivables",
      "banks": "Bank balances",
      "net": "Net position",
      "unrealised": "Unrealised ({currency})",
      "unknown": "Not available",
      "total": "Total unrealised",
      "incomplete": "Some balances are not included, because a rate is missing or the books could not confirm them. Amounts that cannot be worked out show Not available instead of zero."
    },
    "errors": {
      "notMonthEnd": "Pick the last day of a month.",
      "notEnded": "This month has not ended yet. Revalue it once the month is over.",
      "periodClosed": "This month is already closed. Reopen the period first if you need to revalue it.",
      "nextPeriodClosed": "The next month is already closed, and the reversal posts there. Reopen it first, or revalue before closing it.",
      "rateMissing": "A closing rate is missing for a currency. Type one in Closing rates and recalculate.",
      "truncated": "The preview is incomplete, so it cannot be posted.",
      "stale": "The books changed since this preview, so nothing was posted. Review the refreshed preview and post again.",
      "unavailable": "Revaluation is not available for this month right now. Contact support.",
      "accountNotConfigured": "An unrealised gain or loss account is not set. Choose it under Chart of Accounts, Payment & posting, then post again.",
      "financeOnly": "Only an owner or finance admin can post a revaluation.",
      "postFailed": "The revaluation could not be posted. Nothing was changed. Try again."
    }
  },
  "fxGainLoss": {
    "title": "FX gain and loss",
    "subtitle": "What the business gained or lost on exchange rates, from the ledger.",
    "view": {
      "label": "Basis",
      "realised": "Realised",
      "unrealised": "Unrealised"
    },
    "basis": {
      "aboutRealised": "About realised gains and losses",
      "realised": "Made when a foreign bill, receipt or expense was settled, measured against the rate it was booked at.",
      "aboutUnrealised": "About unrealised gains and losses",
      "unrealised": "The change in value of open foreign balances, as the profit and loss reads it. A month-end revaluation and its reversal on the first of the next month cancel out over a closed pair of months."
    },
    "totals": {
      "gain": "Gain",
      "loss": "Loss",
      "net": "Net",
      "total": "Realised and unrealised together"
    },
    "position": {
      "title": "Unrealised position",
      "help": "What the books still carry as an unrealised gain (positive) or loss (negative). A tax computation needs this figure, because the movement above nets to zero over a closed pair of months.",
      "opening": "At start of period",
      "closing": "At end of period"
    },
    "gross": {
      "show": "Show revaluation runs ({count})",
      "hide": "Hide revaluation runs",
      "title": "Revaluation runs and reversals",
      "phase": {
        "close": "Month-end revaluation",
        "reopen": "Reversal on the first of the month",
        "supersession_reversal": "Reversal of an earlier run",
        "other": "Other entry"
      }
    },
    "byMonth": {
      "title": "By month",
      "month": "Month"
    },
    "documents": {
      "title": "By document",
      "date": "Date",
      "voucher": "Voucher",
      "document": "Document",
      "settled": "Settled",
      "empty": "Nothing to list for this basis in the period.",
      "settlesMany": "Settles {count} documents",
      "wholeEntry": "Whole entry",
      "wholeEntryHelp": "The records for the documents in this entry do not add up to the ledger, so the whole entry is shown.",
      "aboutEntry": "About this row",
      "kind": {
        "ap_payment": "Supplier payment",
        "ar_receipt": "Customer receipt",
        "business_expense": "Business expense",
        "fx_revaluation": "Month-end revaluation",
        "other": "Other entry"
      },
      "trueUpOf": "Bank true-up of"
    },
    "accounts": {
      "show": "Accounts read ({count})",
      "hide": "Hide accounts read",
      "col": {
        "account": "Account",
        "role": "Counts as",
        "foundBy": "Found by",
        "movement": "Movement"
      },
      "role": {
        "realisedFxGain": "Realised gain",
        "realisedFxLoss": "Realised loss",
        "unrealisedFxGain": "Unrealised gain",
        "unrealisedFxLoss": "Unrealised loss"
      },
      "found": {
        "designation": "Account you chose",
        "catalogue_default": "Standard account",
        "revaluation_lane": "Month-end revaluation",
        "caller_named": "Added by you"
      }
    },
    "include": {
      "title": "Include another account",
      "help": "You changed which account holds FX gains or losses, so earlier postings may sit on the old account. Name that account here to include them.",
      "code": "Account code",
      "role": "Counts as",
      "add": "Include",
      "included": "Included",
      "remove": "Remove account {code}",
      "errors": {
        "notFound": "We could not find an account with that code.",
        "typeMismatch": "That account is the wrong type for this role. Gains sit on income accounts and losses on expense accounts.",
        "tooMany": "You can include up to 20 accounts."
      }
    },
    "incomplete": {
      "title": "Some history is not included",
      "body": "The report reached its reading limit. It reads the newest postings first, so the opening position and earlier periods may be understated."
    },
    "states": {
      "loadError": "We could not load the FX report. Please try again.",
      "retry": "Try again",
      "noFx": "No exchange gains or losses in this period.",
      "noFxHistory": "No exchange gains or losses in this period, but the books carry earlier ones."
    },
    "export": {
      "csv": "Export CSV",
      "failed": "We could not export the report. Please try again."
    }
  },
  "supplierStatement": {
    "title": "Supplier statement",
    "back": "Back",
    "from": "From",
    "to": "To",
    "downloadPdf": "Download PDF",
    "pdfFailed": "We could not create the PDF. Please try again.",
    "supplier": "Supplier",
    "statementOf": "Statement of account",
    "picker": {
      "title": "Choose a supplier",
      "hint": "See what a supplier has billed, been paid and is still owed, in the currency of each bill.",
      "search": "Search suppliers",
      "empty": "No suppliers found."
    },
    "column": {
      "date": "Date",
      "reference": "Reference",
      "description": "Description",
      "debit": "Debit",
      "credit": "Credit",
      "balance": "Balance owed"
    },
    "openingBalance": "Opening balance",
    "closingBalance": "Closing balance (you owe)",
    "totalDebits": "Total debits",
    "totalCredits": "Total credits",
    "noTransactions": "No activity in this period.",
    "noBands": "Nothing has been billed by or owed to this supplier.",
    "description": {
      "bill_received": "Bill received",
      "debit_note_received": "Debit note received",
      "credit_note_received": "Credit note received",
      "carried_forward_bill": "Carried-forward bill",
      "payment_made": "Payment made",
      "credit_applied": "Credit applied",
      "opening_payment": "Payment on a carried-forward bill",
      "settlement_unspecified": "Payment (date not recorded)",
      "againstBill": "against bill {number}"
    },
    "home": {
      "carried": "Carried in {currency}",
      "paid": "Paid {amount}",
      "estimated": "estimated",
      "realisedGain": "Realised gain {amount}",
      "realisedLoss": "Realised loss {amount}",
      "none": "No {currency} total: some bills have no exchange rate on file."
    },
    "matchedByName": "Matched by name",
    "matchedByNameHelp": "This bill is not linked to a supplier record, so it was matched because its supplier name is the same. A name that differs even by punctuation counts as another supplier.",
    "aboutMatch": "About matching by name",
    "dateAssumed": "Bill date",
    "dateAssumedHelp": "The payment is real but no date was recorded for it, so it is listed on the bill date.",
    "aboutDate": "About this date",
    "incomplete": {
      "title": "Some bills are not included",
      "body": "The statement reached its reading limit, so the balances may be understated."
    },
    "warnings": {
      "SETTLEMENT_WITHOUT_HISTORY": "Bill {ref}: a payment is marked on it with no dated record, so it is listed on the bill date.",
      "HISTORY_EXCEEDS_PAID": "Bill {ref}: its payment records add up to more than the amount marked paid. Please check it.",
      "generic": "Bill {ref} needs a check."
    },
    "states": {
      "loadError": "We could not load the statement. Please try again.",
      "notFound": "We could not find that supplier.",
      "retry": "Try again",
      "invalidRange": "Choose a start date that is not after the end date."
    }
  },
  "agentWorkspace": {
    "pane": {
      "name": "Groot",
      "label": "Groot",
      "history": "Past tasks",
      "newTask": "New task",
      "expand": "Give Groot the full screen",
      "restore": "Show the page beside Groot",
      "collapse": "Hide Groot",
      "close": "Close Groot",
      "alertsUnread": "Alerts, {count} unread",
      "alertsCapped": "20+"
    },
    "status": {
      "idle": "Ready",
      "working": "Working on it",
      "needs_you": "Waiting for you",
      "error": "Stopped with an error"
    },
    "seam": {
      "label": "Resize the page and Groot"
    },
    "rail": {
      "openAgent": "Open Groot",
      "showPage": "Show {page}",
      "shortcut": "Press Ctrl+K or ⌘K to ask Groot"
    },
    "pageRail": {
      "dashboard": "Dashboard"
    }
  },
  "grootMemory": {
    "title": "Groot memory",
    "description": "Groot remembers lasting facts and preferences you share in chat, so you don't have to repeat them. It never keeps passwords, PINs or account numbers. Only you can see your notes.",
    "undoHint": "Whenever Groot saves a note, chat shows \"Remembered\" with an Undo.",
    "loading": "Loading your notes",
    "empty": {
      "title": "Nothing remembered yet",
      "description": "Tell Groot something worth keeping, like \"our fiscal year ends in June\", and it will appear here."
    },
    "error": {
      "title": "We could not load your notes",
      "description": "This is on our side. Refresh the page in a moment to try again."
    },
    "meta": {
      "auto": "Saved automatically on {date}",
      "you": "Saved by you on {date}",
      "groot": "Saved by Groot on {date}"
    },
    "actions": {
      "edit": "Edit note",
      "delete": "Delete note",
      "save": "Save",
      "cancel": "Cancel"
    },
    "edit": {
      "counter": "{count} of {max}"
    },
    "delete": {
      "title": "Delete this note?",
      "message": "Groot will forget \"{note}\" and stop using it in chat. This cannot be undone.",
      "confirm": "Delete"
    },
    "toast": {
      "updated": "Note updated",
      "deleted": "Note deleted",
      "updateFailed": "We could not update this note. Please try again.",
      "deleteFailed": "We could not delete this note. Please try again."
    }
  },
  "voidDocument": {
    "invoice": {
      "hasPayment": "Cash has already been recorded against this invoice, so it can't be voided. Issue a credit note instead.",
      "hasAdjustmentNotes": "This invoice still has credit or debit notes. Void or delete those first, then void the invoice.",
      "bankReconciled": "This invoice's entry is matched in bank reconciliation, so it can't be voided. Unmatch it in Bank reconciliation first, or issue a credit note instead.",
      "lhdnHeld": "This invoice has been submitted to LHDN. Cancel it with LHDN first, or issue a credit note instead.",
      "stockHasLaterMovements": "Stock for an item on this invoice has moved since it was issued, so voiding it would change the cost of later stock. Issue a credit note instead.",
      "clearingSettled": "The payment for this cash sale has already been settled through a payment provider, so it can't be voided. Issue a credit note instead.",
      "entrySetUnreadable": "Groot couldn't safely tell which journal entries belong to this invoice, so nothing was changed. Issue a credit note instead, or contact support.",
      "fxRevaluationNotRestatable": "A month-end foreign exchange revaluation that includes this invoice can't be restated safely, so nothing was changed. Issue a credit note instead, or re-run that month's revaluation first.",
      "periodLocked": "This invoice, or a month-end foreign exchange revaluation that includes it, is in a locked accounting period, so the invoice can't be voided. Issue a credit note in the current period instead.",
      "periodClosed": "This invoice, or a month-end foreign exchange revaluation that includes it, is in a closed accounting period, so the invoice can't be voided. Issue a credit note in the current period instead.",
      "beforeConversionDate": "This invoice is dated before your opening balance go-live date, so it can't be voided. Issue a credit note on or after go-live instead.",
      "liveDelivery": "This invoice came from a sales order that still has a delivery order that is not cancelled. Cancel or void that delivery order first, then void the invoice."
    }
  },
  "partyBalanceCard": {
    "title": "Customer or supplier balance",
    "customer": "Customer",
    "supplier": "Supplier",
    "outstanding": "Outstanding",
    "youOwe": "You owe",
    "inCreditCustomer": "In credit (you owe them)",
    "inCreditSupplier": "In credit (they owe you)",
    "overdue": "Overdue",
    "creditOnAccount": "Credit on account",
    "creditNetted": "Already deducted from the outstanding amount.",
    "openInvoices": "{count, plural, one {# open invoice} other {# open invoices}}",
    "oldestOverdue": "Oldest invoice is {count, plural, one {# day} other {# days}} overdue",
    "nothingOutstanding": "Nothing outstanding in any currency.",
    "incomplete": "This total may be partial because the read stopped early.",
    "asOf": "As of {date}",
    "viewAccount": "View account",
    "viewStatement": "View statement"
  },
  "orderReadingCard": {
    "title": "Order reading",
    "customer": "Customer",
    "poNumber": "PO number",
    "requestedDate": "Requested date",
    "item": "Item",
    "quantity": "Quantity",
    "unitPrice": "Unit price",
    "totalAsPrinted": "Total as printed",
    "sumOfLines": "Sum of the lines",
    "notPrinted": "Not printed",
    "confirmImage": "Read from an image, accuracy not measured. Check every line.",
    "nothingCreated": "Nothing was created and nothing was sent.",
    "notMatched": "The lines are not matched to your products yet.",
    "noWorkspace": "A quotation or sales order cannot be made from this reading yet.",
    "offer": "Say \"create the sales order\" or \"make a quotation\" and I will match the lines to your products and show you the document to confirm.",
    "next": "Check the lines and tell me which customer this is for.",
    "nextCustomer": "Check the lines and confirm the customer is {customer}."
  },
  "orderConfirmationCard": {
    "ariaLabel": "Order confirmation",
    "title": {
      "quotationCreate": "Quotation ready to create",
      "salesOrderCreate": "Sales order ready to create",
      "purchaseOrderCreate": "Purchase order ready to create",
      "change": "Order change ready to confirm",
      "deliveryOrder": "Delivery order ready to create",
      "invoiceDelivered": "Invoice for delivered goods ready to create"
    },
    "intro": {
      "create": "Nothing is created until you confirm.",
      "change": "Nothing changes until you confirm."
    },
    "fields": {
      "customer": "Customer",
      "supplier": "Supplier",
      "project": "Project",
      "order": "Order",
      "poNumber": "Customer PO number",
      "validUntil": "Valid until",
      "terms": "Payment terms",
      "orderDate": "Date",
      "source": "Source",
      "notes": "Notes",
      "reason": "Reason",
      "invoiceDate": "Invoice date",
      "dueDate": "Due date",
      "customerRecord": "Customer record",
      "deliveryDate": "Delivery date",
      "shipFrom": "Ships from",
      "deliveries": "Deliveries",
      "priceChangeReason": "Reason for the price change"
    },
    "lines": {
      "item": "Item",
      "quantity": "Qty",
      "unitPrice": "Unit price",
      "amount": "Amount",
      "catalogue": "Catalogue item",
      "oneOff": "One-off line",
      "total": "Total",
      "tax": "Includes tax"
    },
    "sources": {
      "email": "Customer email",
      "customer_po": "Customer purchase order",
      "chat": "Chat request",
      "photo": "Photo",
      "whatsapp": "WhatsApp",
      "manual": "Entered by hand",
      "other": "Other"
    },
    "actions": {
      "revise": "Apply changes",
      "submit": "Submit",
      "accept": "Accept",
      "approve": "Approve",
      "cancel": "Cancel order",
      "receive": "Record receipt",
      "convert": "Convert to invoice"
    },
    "confirm": {
      "quotationCreate": "Create quotation",
      "salesOrderCreate": "Create sales order",
      "purchaseOrderCreate": "Create purchase order",
      "deliveryOrder": "Create delivery order",
      "invoiceDelivered": "Create draft invoice"
    },
    "confirming": "Working...",
    "done": {
      "quotation": "Quotation created.",
      "salesOrder": "Sales order created.",
      "purchaseOrder": "Purchase order created.",
      "change": "Done.",
      "invoice": "Invoice created.",
      "deliveryOrder": "Delivery order created.",
      "invoiceDelivered": "Draft invoice created. Nothing was issued or sent."
    },
    "open": {
      "quotation": "Open quotation {number}",
      "quotationNoNumber": "Open quotation",
      "salesOrder": "Open sales order {number}",
      "salesOrderNoNumber": "Open sales order",
      "invoice": "Open invoice",
      "deliveryOrder": "Open delivery order {number}",
      "deliveryOrderNoNumber": "Open delivery order",
      "invoiceNumbered": "Open invoice {number}"
    },
    "expired": "This preview expired. Ask me to prepare it again.",
    "historical": "This is an earlier preview. Ask me to prepare it again to confirm.",
    "errors": {
      "stale": "This changed after the preview was prepared. Ask me to prepare it again.",
      "unauthorized": "Only an owner or finance admin can confirm this. A sales order or quotation you prepared as a manager waits in Sales orders for them.",
      "expired": "This preview expired. Ask me to prepare it again.",
      "alreadyConfirmed": "This was already confirmed.",
      "invalid": "Something in this order is no longer valid. Ask me to prepare it again.",
      "unknown": "I could not complete this, so nothing was created. Try again, or ask me to prepare it again.",
      "choiceEmail": "A regular customer needs an email address. Ask me to prepare it again with one.",
      "customerExists": "A customer with this name is already on file. Ask me to prepare it again and I will use them.",
      "addon": "This needs an add-on that is not switched on for this business. Contact us to add it.",
      "delivery": {
        "addon": "Delivery orders need the Invoices plan, and it is not switched on for this business. Contact us to add it.",
        "stockNotManaged": "Stock is not managed in Groot for this business, so Groot cannot make a delivery order. An owner or finance admin can change this in Stock, Settings.",
        "policy": "This business has not chosen delivery orders. An owner or finance admin can choose \"Delivery Order deducts stock\" under Fulfillment in Stock, Settings, then ask me to prepare it again.",
        "notDeliverable": "This sales order can no longer be delivered. Only an accepted order that has not been cancelled or voided can have a delivery order.",
        "nothingLeft": "There is nothing left to deliver on this order. Check the Delivery Orders screen.",
        "location": "Groot needs a stock location to ship from, and it is not available. Check Stock, Locations, or use the Delivery Orders screen.",
        "changed": "What is left to deliver changed after this card was prepared. Ask me to prepare it again.",
        "stockChanged": "Whether a line of this order moves stock changed after this card was prepared, so nothing was created. Ask me to prepare it again.",
        "stockAddon": "Delivering goods out of stock needs the Stock add-on, and it is not switched on for this business. Contact us to add it.",
        "periodClosed": "The accounting period of this delivery date was closed after this card was prepared, so stock cannot leave on it. Choose a date in an open period on the Delivery Orders screen.",
        "lineInput": "A line or quantity in this request does not fit the order, so nothing was created. Ask me to prepare it again with a line from the order and a quantity above zero.",
        "unit": "That quantity cannot be converted exactly into the unit of the order, so nothing was created. Use the unit on the order line, or make this delivery on the Delivery Orders screen."
      },
      "invoiceDelivered": {
        "alreadyInvoiced": "One of these deliveries is already billed by an invoice, so nothing was created. Void or delete that invoice first to bill it again.",
        "changed": "What this invoice would bill changed after the card was prepared, so nothing was created. Ask me to prepare it again.",
        "theseDeliveries": "one of these deliveries",
        "thisOrder": "this order"
      },
      "salesAccessOff": "Sales access is turned off for you, so nothing was created. Ask the business owner or a finance admin to turn it back on.",
      "salesAgentNeeded": "Saving a new customer to your list needs a sales agent linked to you, so nothing was created. Ask the business owner or a finance admin to link one, or ask me to prepare it again as a one-off customer.",
      "priceChangeReason": "A price on this card now differs from the standard price, so nothing was created. Ask me to prepare it again and give the reason for the price."
    },
    "newCustomer": {
      "kind": {
        "saved": "New customer, will be saved as a regular customer when you confirm",
        "savedDone": "New customer, saved as a regular customer",
        "oneOff": "One-off customer, not added to your customer list"
      },
      "fields": {
        "email": "Email",
        "contactPerson": "Contact person",
        "phone": "Phone",
        "address": "Address",
        "tin": "TIN",
        "brn": "Registration number"
      },
      "switch": {
        "label": "Save as a regular customer",
        "hintOn": "Confirming also adds this customer to your customer list, so you can pick them next time.",
        "hintOff": "A one-off customer: the details stay on this document and nothing is added to your customer list.",
        "needsEmail": "A one-off customer. To save them as a regular customer, ask me to prepare it again with an email address."
      }
    },
    "deliver": {
      "scope": "A draft delivery order for the lines below of {order}. It is posted later, when the goods have gone.",
      "scopeNoNumber": "A draft delivery order for the lines below of this order. It is posted later, when the goods have gone.",
      "partialLink": "To choose another date or location, use the Delivery Orders screen.",
      "line": {
        "movesStockFrom": "Moves stock from {warehouse}",
        "movesStock": "Moves stock",
        "noStock": "No stock moved",
        "converted": "= {quantity} {unit} of the order"
      }
    },
    "invoice": {
      "line": {
        "delivery": "Delivery {number}"
      },
      "termsDiffer": "These terms ({chosen}) differ from the order's ({order}).",
      "truncated": "Showing the first {shown} of {count} lines. The invoice holds all of them.",
      "draftNote": "This makes a draft invoice. Issuing and sending it are separate steps that you confirm yourself."
    }
  },
  "duplicateDifferences": {
    "list": "Different: {items}",
    "referenceNumber": "receipt no. {value}",
    "totalAmount": "amount {value}",
    "transactionDate": "date {value}",
    "vendorName": "vendor {value}",
    "currency": "currency {value}",
    "lineItems": "line items"
  },
  "paymentTermLabels": {
    "due_on_receipt": "Due on receipt",
    "cod": "Cash on delivery",
    "net_7": "Net 7",
    "net_14": "Net 14",
    "net_15": "Net 15",
    "net_30": "Net 30",
    "net_45": "Net 45",
    "net_60": "Net 60",
    "net_90": "Net 90",
    "custom": "Custom"
  },
  "financialStatementCard": {
    "periodRange": "{from} to {to}",
    "outOfBalanceBy": "Out of balance by {amount}",
    "cashTies": "Ties to the ledger",
    "cashDiffersBy": "Differs from the ledger by {amount}",
    "totalOf": "Total {section}",
    "showMore": "Show {count} more",
    "showFewer": "Show fewer",
    "columnCode": "Code",
    "columnAccount": "Account",
    "columnType": "Type",
    "columnDebit": "Debit",
    "columnCredit": "Credit",
    "comparedWith": "Compared with {period}",
    "change": "Change",
    "equityTies": "Ties to the balance sheet",
    "equityDiffersBy": "Differs from the balance sheet by {amount}"
  },
  "chartVocabulary": {
    "finding": {
      "peak": "{series} peaked in {period} at {amount}",
      "rankOne": "{name}: {percent}% of the amounts listed",
      "rankThree": "Three names hold {percent}% of the amounts listed",
      "aging90": "{percent}% is over 90 days old",
      "agingOldest": "Oldest unpaid bucket: {period}, {amount}",
      "netProfit": "Net profit of {amount}",
      "netLoss": "Net loss of {amount}",
      "lossPeriods": "{count} loss periods: {periods}",
      "composition": "{name}: {percent}% of the amounts listed",
      "lossMany": "{count} loss periods, lowest {period} at {amount}",
      "changeUp": "{series} rose {change} ({percent}%) from {from} to {to}",
      "changeDown": "{series} fell {change} ({percent}%) from {from} to {to}",
      "changeSame": "{series} unchanged from {from} to {to}",
      "changeFromZeroUp": "{series} rose {change} from {from} to {to}",
      "changeFromZeroDown": "{series} fell {change} from {from} to {to}",
      "statUp": "Up {change} from {from}",
      "statDown": "Down {change} from {from}",
      "statSame": "Same as {from}",
      "compositionTotal": "{name}: {percent}% of the total",
      "rankOneTotal": "{name}: {percent}% of the total",
      "rankThreeTotal": "Three names hold {percent}% of the total"
    },
    "other": "Other"
  },
  "filePicker": {
    "chooseOne": "Choose file",
    "chooseMany": "Choose files",
    "noFile": "No file chosen",
    "remove": "Remove {name}"
  },
  "customerAliases": {
    "title": "Aliases and item codes",
    "help": "Names this customer goes by in an order message, and the code they use for each of your items. Used to match an order to the right customer and item.",
    "loading": "Loading...",
    "unavailable": "Aliases and item codes are available to an owner or finance admin.",
    "searchPlaceholder": "Search aliases and codes",
    "aliasesHeading": "Aliases",
    "noAliases": "No aliases yet.",
    "aliasPlaceholder": "For example: Ah Seng",
    "aliasLabel": "Alias",
    "add": "Add",
    "edit": "Edit",
    "remove": "Remove",
    "save": "Save",
    "cancel": "Cancel",
    "codesHeading": "Their item codes",
    "noCodes": "No item codes yet.",
    "itemPlaceholder": "Find one of your items",
    "codePlaceholder": "Their code for it",
    "codeLabel": "Customer item code",
    "itemMissing": "Item no longer available",
    "truncated": "Only the first 200 are shown.",
    "errorTitle": "Could not save",
    "errors": {
      "generic": "Something went wrong. Please try again.",
      "ALIAS_TAKEN": "That alias already belongs to {name}. Use a different one.",
      "ALIAS_INVALID": "Enter an alias of up to 80 characters and 6 words, with at least one letter or number.",
      "ALIAS_LIMIT": "This customer has the most aliases allowed.",
      "CODE_LIMIT": "This customer has the most item codes allowed.",
      "CODE_TAKEN": "This customer already uses that code for another item.",
      "CODE_INVALID": "Enter a code of up to 80 characters and 6 words, with at least one letter or number.",
      "ITEM_ALREADY_CODED": "This customer already has a code for that item. Edit it instead.",
      "ITEM_NOT_FOUND": "That item could not be found.",
      "NOT_AUTHORIZED": "Only an owner or finance admin can change this."
    }
  },
  "expenseApprovalOverride": {
    "heading": "Approval override reason",
    "summary": "{hasName, select, true {Approved by {name}} other {Approved}}{hasDate, select, true { on {date}} other {}}{hasFlags, select, true { despite: {flags}} other {}}. Reason: {reason}",
    "flagPolicyFailed": "policy check failed",
    "flagPolicyUnavailable": "policy check unavailable",
    "flagDuplicateSuspected": "suspected duplicate",
    "flagDuplicateConfirmed": "confirmed duplicate",
    "flagDuplicateUnavailable": "duplicate check unavailable",
    "flagOverPolicyLimit": "over the category limit"
  },
  "agentSalesDocs": {
    "card": {
      "unit": "Unit",
      "cancel": "Cancel",
      "cancelled": "Cancelled. Nothing was created.",
      "cancelledChange": "Cancelled. Nothing was changed.",
      "handoff": "Only an owner or finance admin can confirm this. It waits for them on the Sales orders page for 24 hours.",
      "openOrders": "Open Sales orders",
      "zeroPriceWarning": "{count, plural, one {# line is priced at 0.00 ({lines}). Check the unit price before you confirm.} other {# lines are priced at 0.00 ({lines}). Check the unit prices before you confirm.}}",
      "superseded": "This card was replaced by a newer one. Use the latest card."
    },
    "roleRefusal": "Only an owner, a finance admin or a manager can prepare a quotation or a sales order, so I can't make one for you. Please ask one of them.",
    "requirements": {
      "customerId": "Customer",
      "lineItems": "Items",
      "customerTerms": "Payment terms",
      "currency": "Currency",
      "orderDate": "Date",
      "validUntil": "Valid until",
      "notes": "Notes",
      "customerPoNumber": "Customer PO number",
      "newCustomer": "New customer details"
    },
    "reading": {
      "title": "Customer request for quotation",
      "rfqNumber": "RFQ number",
      "offer": "Say \"make a quotation\" and I will match the lines to your products, price them from your catalogue and show you the quotation to confirm."
    }
  },
  "agentInvoice": {
    "refusal": {
      "role": "Only the business owner or a finance admin can create, issue, change or send sales invoices, so I have not started anything. Please ask the owner or a finance admin to do it, or to give you that role."
    },
    "requirement": {
      "customer": "Customer",
      "lines": "Line items",
      "lineDescription": "Item description",
      "lineUnitPrice": "Unit price",
      "paymentTerms": "Payment terms",
      "dueDate": "Due date",
      "invoiceDate": "Invoice date",
      "taxRate": "Tax rate",
      "discount": "Discount",
      "notes": "Notes",
      "paymentInstructions": "Payment instructions",
      "project": "Project",
      "invoice": "Draft invoice",
      "exchangeRate": "Exchange rate",
      "cashSaleBankCredit": "Bank credit"
    },
    "card": {
      "title": "Draft invoice ready to create",
      "subtotal": "Subtotal",
      "discount": "Discount",
      "tax": "Tax",
      "draftNotice": "Confirming creates a draft invoice. Nothing is issued or sent to the customer.",
      "linesShown": "Showing the first {shown} of {total} lines.",
      "created": "Draft invoice {number} created.",
      "createdNoNumber": "Draft invoice created.",
      "openInvoice": "Open invoice {number}",
      "openInvoiceNoNumber": "Open invoice"
    }
  },
  "agentProjects": {
    "toolName": "Add project",
    "step": {
      "prompt": "Would you like to put {document} under a project?",
      "pick": "Use the project \"{name}\" for this.",
      "new": "Create a new project for this.",
      "skip": "No project for this one.",
      "newLabel": "New project",
      "skipLabel": "Skip project",
      "pickLabel": "Use existing project",
      "skipped": "Kept without a project.",
      "askName": "What should the new project be called? You can also give it a short code and start and end dates.",
      "documents": {
        "quotation": "this quotation",
        "order": "this sales order",
        "invoice": "this invoice"
      }
    },
    "card": {
      "preview": "New project to confirm",
      "created": "Project created",
      "pending": "Nothing has been created yet. Confirm on the card below.",
      "name": "Name",
      "code": "Code",
      "startDate": "Start date",
      "endDate": "End date",
      "openSettings": "Open Projects in Business settings"
    },
    "roleRefused": "Ask the owner or a finance admin to create a project."
  },
  "adminPilot": {
    "panel": {
      "title": "Pilot baseline",
      "description": "What this business told us before its pilot began. Groot staff enter it here; Groot does not measure it.",
      "loading": "Loading the baseline",
      "denied": "This account is outside your scope, so its baseline is not shown.",
      "notFound": "This account no longer exists.",
      "unknownPerson": "a Groot staff member",
      "status": {
        "none": "Not in a pilot yet. Fill in the form to enrol this business and record its week-0 baseline.",
        "enrolled": "In the {cohort} pilot. Revision {version}, recorded {date} by {name}.",
        "withdrawn": "Withdrawn from the {cohort} pilot. Revision {version}, recorded {date} by {name}."
      },
      "readOnly": "Recording a baseline needs the account manager or super role. You can read what was recorded.",
      "signupSource": "Signup source on record: {source}",
      "form": {
        "cohort": "Pilot",
        "cohortHint": "A short name for the pilot, such as affin. Lowercase letters, numbers and hyphens.",
        "capturedOn": "Week-0 date",
        "capturedOnHint": "The day the figures below describe. It cannot be in the future.",
        "hoursHeading": "Hours a week the business spends on",
        "hoursHint": "What the business told you. Leave a box empty if nobody asked. Enter 0 only if the answer was none.",
        "hoursPaymentPrep": "Payment preparation",
        "hoursCollectionsMatching": "Collections matching",
        "hoursReconciliation": "Reconciliation",
        "hoursReporting": "Reporting",
        "oldestUnreconciledDays": "Age in days of the oldest unreconciled item",
        "note": "Reason for this change",
        "noteHintFirst": "Optional for the first entry.",
        "noteHintRevision": "Required. It is kept with the revision."
      },
      "actions": {
        "saveFirst": "Enrol and save baseline",
        "save": "Save as a new revision",
        "saving": "Saving",
        "withdraw": "Withdraw from the pilot"
      },
      "saved": "Saved as revision {version}.",
      "history": {
        "title": "History",
        "empty": "No revisions yet.",
        "line": "Revision {version}, {date}, {name}",
        "withdrawn": "Withdrawn",
        "notRecorded": "not recorded",
        "days": "{count} days",
        "summary": "Week-0 date {capturedOn}. Hours a week: payment preparation {paymentPrep}, collections matching {collections}, reconciliation {reconciliation}, reporting {reporting}. Oldest unreconciled item: {age}.",
        "truncated": "Only the newest {count} revisions are shown."
      },
      "errors": {
        "INVALID_COHORT": "The pilot name must be 2 to 32 characters: lowercase letters, numbers and hyphens.",
        "INVALID_DATE": "That is not a real date.",
        "DATE_IN_FUTURE": "The week-0 date cannot be in the future.",
        "INVALID_HOURS": "Hours must be a number from 0 to 168.",
        "INVALID_AGE": "The age must be a whole number of days from 0 to 3650.",
        "NOTE_TOO_LONG": "The reason is too long. Keep it under 500 characters.",
        "REASON_REQUIRED": "Say why you are changing this baseline.",
        "NOTHING_CHANGED": "Nothing has changed since the last revision.",
        "NOT_ENROLLED": "This business is not in a pilot yet, so there is nothing to withdraw.",
        "STALE_BASELINE": "Someone else saved a newer revision. The page now shows it; review it and try again.",
        "BUSINESS_NOT_FOUND": "This account no longer exists.",
        "generic": "The baseline could not be saved. Nothing was changed. Try again, and tell Groot engineering if it keeps happening."
      }
    },
    "report": {
      "title": "Pilot report",
      "subtitle": "Weekly figures for one pilot, counted from recorded events",
      "intro": "Every figure is counted from events Groot recorded. A figure with nothing to count shows no data, never 0. The proposal's targets sit beside the related figure; this page never says a target was met.",
      "cohort": "Pilot",
      "week": "Week",
      "weekRange": "{start} to {end} (Malaysia time)",
      "previousWeek": "Previous week",
      "nextWeek": "Next week",
      "thisWeek": "This week",
      "download": "Download CSV",
      "loading": "Counting the week",
      "noCohorts": "No pilot has a business yet. Record a baseline on an account to start one.",
      "denied": "You cannot read the pilot report. It needs the product, engineering or super staff role.",
      "tooLarge": "This pilot has more than {limit} businesses, which is more than one report covers.",
      "failed": "The report could not be made. Nothing is shown. Try again, and tell Groot engineering if it keeps happening.",
      "retry": "Try again",
      "timing": {
        "future": "This week has not started, so there is nothing to count yet.",
        "in_progress": "This week is still in progress. The weekly figures count what has happened so far."
      },
      "asAt": "Open bank lines are as at {date}, the day this report was made, not the end of the week.",
      "version": "Definitions version {version}.",
      "targetNote": "Targets are the proposal's own and are shown for comparison only.",
      "sections": {
        "people": "People",
        "documents": "Documents",
        "bank": "Bank lines",
        "exceptions": "Open items",
        "baseline": "Week-0 baseline, entered by staff",
        "targets": "Targets Groot cannot yet count"
      },
      "columns": {
        "figure": "Figure",
        "cohort": "Whole pilot",
        "basis": "From",
        "target": "Proposal target",
        "business": "Business"
      },
      "basis": "{withData} of {total} businesses",
      "byBusiness": "By business",
      "noData": "no data",
      "atLeast": "at least {value}",
      "definitions": {
        "title": "What each figure counts"
      },
      "reasons": {
        "unavailable": "the figures could not be read",
        "not_recorded": "not recorded",
        "no_denominator": "nothing to divide by",
        "none_open": "nothing is open",
        "before_account_existed": "the business did not exist yet",
        "week_not_started": "the week has not started",
        "not_measured": "Groot does not record this",
        "no_bank_account": "no bank account is connected",
        "no_businesses": "no business is in the pilot"
      },
      "metrics": {
        "members": {
          "label": "Members",
          "definition": "People with an active membership of the business whose membership existed by the end of the week. Groot staff are not counted."
        },
        "activeUsers": {
          "label": "Active users",
          "definition": "Members who did at least one recorded action in the business during the week: any action Groot writes to the business audit log, such as creating or changing a record. Only looking at a screen is not counted."
        },
        "weeklyActiveRate": {
          "label": "Weekly active share of members",
          "definition": "Active users divided by members, one decimal."
        },
        "documentsProcessed": {
          "label": "Documents processed",
          "definition": "Expense claims plus supplier invoices created in the week whose reading did not fail and was not still running or cancelled."
        },
        "expenseClaims": {
          "label": "Expense claims processed",
          "definition": "Expense claims created in the week, excluding those still being read, failed or cancelled."
        },
        "supplierInvoices": {
          "label": "Supplier invoices processed",
          "definition": "Supplier invoices created in the week, excluding those still being read, failed or cancelled."
        },
        "linesCompleted": {
          "label": "Bank lines completed",
          "definition": "Statement lines a person finished in the week, either matched to an entry or posted after review, with one counter account. Split lines are not recorded and so are not counted."
        },
        "linesMatched": {
          "label": "Bank lines matched to an entry",
          "definition": "Of the lines completed, those matched to an entry that already existed."
        },
        "linesWithSuggestion": {
          "label": "Completed lines that had a suggestion",
          "definition": "Of the lines completed, those where Groot had suggested an account before the person acted."
        },
        "linesAccepted": {
          "label": "Suggestions accepted",
          "definition": "Lines where the person used the account Groot had suggested."
        },
        "linesCorrected": {
          "label": "Suggestions corrected",
          "definition": "Lines where the person used a different account from the one Groot had suggested."
        },
        "acceptanceRate": {
          "label": "Share of suggestions accepted",
          "definition": "Accepted divided by lines that had a suggestion, one decimal. Lines with no suggestion are neither."
        },
        "correctionRate": {
          "label": "Share of suggestions corrected",
          "definition": "Corrected divided by lines that had a suggestion, one decimal."
        },
        "openItems": {
          "label": "Bank lines still open",
          "definition": "Statement lines not yet reconciled or posted, as at the moment the report was made (not as at the end of the week)."
        },
        "oldestOpenItemDays": {
          "label": "Age of the oldest open bank line",
          "definition": "Whole days from the transaction date of the oldest open statement line to the day the report was made."
        },
        "baselineHoursPaymentPrep": {
          "label": "Week-0 hours a week: payment preparation",
          "definition": "Entered by Groot staff from what the business reported before the pilot. Not measured by Groot."
        },
        "baselineHoursCollectionsMatching": {
          "label": "Week-0 hours a week: collections matching",
          "definition": "Entered by Groot staff from what the business reported before the pilot. Not measured by Groot."
        },
        "baselineHoursReconciliation": {
          "label": "Week-0 hours a week: reconciliation",
          "definition": "Entered by Groot staff from what the business reported before the pilot. Not measured by Groot."
        },
        "baselineHoursReporting": {
          "label": "Week-0 hours a week: reporting",
          "definition": "Entered by Groot staff from what the business reported before the pilot. Not measured by Groot."
        },
        "baselineOldestUnreconciledDays": {
          "label": "Week-0 age of the oldest unreconciled item",
          "definition": "Entered by Groot staff from what the business reported before the pilot. Not measured by Groot."
        },
        "manualTimeChange": {
          "label": "Change in manual time against the week-0 baseline",
          "definition": "Groot records the week-0 hours a business reported but does not record the hours it spends afterwards, so no change can be counted."
        },
        "autoMatchRate": {
          "label": "Clean transactions matched automatically",
          "definition": "Groot records what a person finally did with a completed line, not whether the line was clean or whether it was matched without anyone acting, so this cannot be counted."
        }
      },
      "targets": {
        "weeklyActiveRate": "At least 70 percent weekly active",
        "manualTimeChange": "At least 30 percent less manual time",
        "autoMatchRate": "At least 60 percent of clean transactions matched automatically"
      }
    }
  },
  "financialReportsOff": {
    "title": "Financial reports are turned off for you",
    "body": "The owner decides who can see profit and loss, balance sheet, cash flow and the journal. Ask the owner to turn on financial reports for you.",
    "back": "Back to dashboard"
  },
  "equityChanges": {
    "title": "Statement of changes in equity",
    "subtitle": "How the owners' interest in the business moved over the period, by component of equity.",
    "columns": {
      "capital": "Capital",
      "retainedProfits": "Retained profits",
      "otherReserves": "Other reserves",
      "total": "Total"
    },
    "rows": {
      "opening": "Balance at {date}",
      "closing": "Balance at {date}",
      "profit": "Profit / (loss) for the period",
      "capitalIntroduced": "Capital introduced / (returned)",
      "distributions": "Drawings and dividends",
      "other": "Other movements"
    },
    "period": {
      "range": "{from} to {to}"
    },
    "badge": {
      "ties": "Ties to the balance sheet",
      "doesNotTie": "Does not tie: {amount} difference",
      "rowsDoNotFoot": "The rows of this statement do not add up to its closing balance (difference {amount}). Please report this."
    },
    "reconciliation": {
      "heading": "Tie to the balance sheet",
      "closing": "Closing balance per this statement at {date}",
      "balanceSheet": "Total equity on the balance sheet at {date}",
      "difference": "Difference",
      "ties": "The closing balance equals the total equity on the balance sheet.",
      "doesNotTie": "The closing balance does not equal the total equity on the balance sheet. The difference is shown above and has not been adjusted."
    },
    "retained": {
      "heading": "Retained profits as the balance sheet shows them",
      "note": "Split at the start of the financial year that began on {date}."
    },
    "details": {
      "title": "Accounts behind the movements",
      "intro": "Capital introduced, drawings and dividends, and other movements, by equity account. A movement is never hidden inside a total.",
      "truncated": "Showing {shown} of {count} accounts, largest first. The row totals above include all of them."
    },
    "basis": {
      "heading": "What this statement is built from",
      "body": "Posted journal entries up to the end date, in your home currency. Each equity account is placed in a column from its own subtype and name, never from its account code. Profit is the net of your revenue and expense accounts in the period. Drawings and dividends are the debits of accounts that declare themselves drawings, dividends or distributions. Any other movement of an equity account is shown under other movements, with the account named. The opening balance equity account used when you moved your books to Groot is shown under other movements, not as capital introduced. Nothing is posted by this statement."
    },
    "states": {
      "loading": "Building the statement",
      "loadError": "We could not build this statement. Please try again.",
      "retry": "Try again",
      "noAccess": "You do not have access to this statement. Ask the business owner or a finance admin.",
      "tooLarge": "This ledger is too large to build the statement in one read yet. Please contact support.",
      "empty": "No equity balance is held and nothing moved equity in this period."
    },
    "export": {
      "csv": "CSV",
      "failed": "The CSV could not be created. Please try again."
    },
    "document": {
      "row": "Movement",
      "reconciliation": "Reconciliation to the balance sheet",
      "account": "Account",
      "movement": "Movement"
    }
  },
  "sqlBridgeSend": {
    "heading": "SQL Account",
    "loading": "Checking this invoice against SQL Account",
    "noneLabel": "Not sent",
    "noneBody": "Groot has not sent this invoice to SQL Account yet.",
    "succeededNoDocNoBody": "SQL Account reported this invoice as saved but sent back no document number, so there is nothing to reconcile against. Open SQL Account and check what is there before you do anything else.",
    "docNo": "SQL Account document {docNo}",
    "totalMismatchHeading": "SQL Account saved a different document total",
    "attempts": "{count, plural, =1 {# attempt so far} other {# attempts so far}}",
    "updatedAt": "last change {at}",
    "openBridge": "Open SQL Bridge settings",
    "refusalHeading": "Groot did not send this invoice.",
    "refusalLines": "Affects line {lines}.",
    "blocked": "Send stays off until this invoice can be sent safely. The state above says why.",
    "send": {
      "action": "Send to SQL Account",
      "again": "Send to SQL Account again",
      "sending": "Sending"
    },
    "stateLabel": {
      "queued": "Waiting",
      "retrying": "Checking again",
      "leased": "Picked up",
      "writing": "Writing",
      "succeeded": "Saved",
      "failed": "Failed",
      "ambiguous": "Needs checking"
    },
    "stateBody": {
      "queued": "Groot has this invoice queued. Your Bridge picks it up the next time it checks in.",
      "retrying": "Groot is checking automatically whether SQL Account already has this invoice, and will not save it a second time if it does.",
      "leased": "Your Bridge has taken this invoice and is about to write it. Nothing has reached SQL Account yet.",
      "writing": "Your Bridge is writing this invoice into SQL Account right now. Leave it alone until it finishes.",
      "succeeded": "SQL Account saved this invoice as document {docNo}. That is the number to reconcile against.",
      "failed": "SQL Account did not save this invoice. See the reason below. You can send it again once that is fixed.",
      "ambiguous": "Groot never learned whether SQL Account saved this invoice, even after checking again automatically, so it may or may not be in your books. Search SQL Account for the reference under Technical details before you do anything else, then record what you found under Settings > Integrations > SQL Accounting. Do not send it again first."
    },
    "technical": {
      "toggle": "Technical details",
      "reference": "Reference written to SQL Account (Reference 4): {key}"
    },
    "totalCheck": {
      "unknown": "SQL Account saved this invoice, but Groot could not read back the total SQL Account recorded, so the two amounts have not been compared.",
      "agrees": "The total on SQL Account document {docNo} matches the amount Groot sent.",
      "disagrees": "Groot sent {expected} for this invoice, but the total on SQL Account document {docNo} is {posted}. These are document totals, not payments, so a part payment does not explain the difference. Nothing in Groot has changed. Open that document in SQL Account and check it before this invoice is paid or reconciled."
    },
    "refusal": {
      "not_an_ap_invoice": "This document is not a supplier invoice, so there is nothing to post to SQL Account.",
      "not_posted_in_groot": "Post this invoice in Groot first. SQL Account only receives invoices that are already in your Groot books.",
      "post_disabled": "Posting to SQL Account is switched off. Turn it on under Settings > Integrations > SQL Accounting.",
      "itemized_mode_unsupported": "Your business exports itemized purchase invoices, and the Bridge posts expense lines only for now. Switch the purchase invoice mode to Expense in Settings > Integrations > SQL Accounting > File import & export, or export this invoice by file.",
      "review_pending": "Review and confirm this invoice's extracted details first, or resolve the open review. Then send it.",
      "companion_unavailable": "The Bridge is not connected right now, so a send would wait with nothing to pick it up. Start the Bridge on the Windows PC and check Settings > Integrations > SQL Accounting.",
      "company_unconfirmed": "Nobody has confirmed which SQL Account company the Bridge posts into. Confirm it under Settings > Integrations > SQL Accounting, then send.",
      "company_changed": "The Bridge now reports a different SQL Account company than the one you confirmed, so posting is paused. Check the company and confirm it again under Settings > Integrations > SQL Accounting.",
      "supplier_code_missing": "We found no creditor code for this supplier. If it isn't in SQL Account yet, add it there and read the chart from SQL Bridge again. If its name is spelled differently, map it on the Import & Export page (SQL Accounting (AP Invoice) template, Map Codes step). Then send again.",
      "account_code_missing": "At least one line has no SQL Account account. Map the line’s account on the Import & Export page (Map Codes step), or set the default expense account in Settings > Integrations > SQL Accounting > File import & export, then send again.",
      "tax_code_missing": "A taxed line has no SQL Account tax code mapped for its rate. Map the tax code on the Import & Export page (Map Codes step), then send again.",
      "currency_unsupported": "This invoice's currency cannot be posted through the Bridge yet. Use the file export for this invoice.",
      "invoice_incomplete": "This invoice is missing a usable date, its lines, or an exact total. Correct the extracted details, then send again.",
      "supplier_invoice_no_too_long": "This supplier invoice number is longer than the 40 characters SQL Account keeps, and SQL Account would cut it short without telling anyone. We did not send this bill. Check that the number was read correctly in the extracted details. If it is right, enter the bill in SQL Account yourself.",
      "already_queued": "This invoice is already waiting to be sent. The state above shows where it is.",
      "already_posted": "SQL Account already holds this invoice, so Groot will not post it a second time.",
      "ambiguous_unresolved": "A previous attempt may or may not have reached SQL Account. Search SQL Account for it, and record what you found under Settings > Integrations > SQL Accounting, before sending again.",
      "duplicate_supplier_invoice": "Another invoice in Groot has the same supplier and supplier invoice number. Open that one instead of sending a duplicate.",
      "not_entitled": "This feature is not switched on for your workspace. Contact support@hellogroot.com."
    },
    "errors": {
      "sendFailed": "Groot could not send this invoice. Nothing was queued. Please try again.",
      "unknownRefusal": "Groot did not send this invoice, and this version could not name the reason. Refresh the page and try again, or contact Groot support."
    },
    "toasts": {
      "queued": "Queued for SQL Account."
    },
    "automaticOnConfirm": "Sent automatically when you confirmed."
  },
  "accounting": {
    "chartReview": {
      "title": "Review before you import",
      "description": "Nothing is written until you confirm. Check what changes, answer what we ask, then confirm.",
      "reviewAndImport": "Review and import",
      "sections": {
        "replaces": "Replaces directly",
        "decision": "Needs your decision",
        "confirm": "Confirm"
      },
      "kind": {
        "empty": "Your chart has no accounts yet, so the {source} chart can come straight in.",
        "starter_untouched": "Your chart is still Groot’s sample chart and nothing has been posted to it.",
        "starter_in_use": "{count, plural, one {# account in your chart holds postings.} other {# accounts in your chart hold postings.}} Posted entries are never changed.",
        "own_chart": "Your chart has accounts that you or your team added.",
        "same_provider": "This chart came from {source} before. Refresh brings in what changed."
      },
      "finalizeLater": "To retire Groot’s chart later, you will be able to finalize onto {source}’s chart.",
      "replaces": {
        "applies": "These changes are made when you confirm.",
        "nothing": "Nothing is written.",
        "keepsChart": "Nothing in your chart is replaced. Your {count, plural, one {# account stays} other {# accounts stay}} as {count, plural, one {it is} other {they are}}.",
        "creates": "Added",
        "updates": "Updated",
        "archives": "Archived",
        "keeps": "Kept",
        "incoming": "Coming in from {source}: {count, plural, one {# account} other {# accounts}}",
        "incomingSample": "For example",
        "archiveSample": "Archived accounts include",
        "keptSample": "Kept because something uses them",
        "referencesTitle": "Used elsewhere",
        "referencesNote": "{count, plural, one {# account is} other {# accounts are}} used by a posting role, bank link, rule or posted entry. {count, plural, one {It stays} other {They stay}} active and posted entries never change.",
        "more": "and {count} more"
      },
      "decision": {
        "choose": "What should Groot do?",
        "recommended": "Recommended",
        "pickAccount": "Choose an account",
        "roles": {
          "title": "Payment & posting",
          "help": "Choose a {source} account for each posting role, or keep Groot’s account for it.",
          "keep": "Keep Groot’s account for this role",
          "suggestion": {
            "suggested": "Suggested: {code} {name}",
            "used": "Suggestion used",
            "use": "Use this account",
            "useAll": "Use all confident suggestions",
            "needsDecision": "Needs your decision. Groot keeps its own account until you choose one.",
            "groupConfident": "Confident suggestions",
            "groupCheck": "Please check these",
            "reason": {
              "default_code": "The account Groot uses by default",
              "name_match": "Its name matches this role",
              "ambiguous": "More than one account could fit",
              "type_mismatch": "The matching account is the wrong kind of account",
              "no_match": "Nothing in your chart matches"
            }
          }
        },
        "categories": {
          "title": "Expense categories",
          "helpMap": "Match each category to a {source} account, or keep it as it is. Matches you made earlier are kept.",
          "helpChoose": "Choose the account each category will use, or keep it as it is.",
          "keep": "Keep this category as it is",
          "suggested": "Suggested: {code} {name}",
          "useSuggestion": "Use suggestion",
          "suggestionUsed": "Suggestion used"
        }
      },
      "options": {
        "import": {
          "title": "Import the {source} chart",
          "description": "Add the {source} accounts to Groot."
        },
        "replace": {
          "title": "Replace Groot’s sample chart",
          "description": "Use {source}’s chart. Sample accounts nobody uses are archived. Accounts kept for a role, category or other reference stay active and keep their history."
        },
        "replaceOwn": {
          "title": "Replace your accounts with the {source} chart",
          "description": "Use {source}’s chart. Your accounts of the imported types that nothing uses are archived. Accounts kept for a posting, role, category or other reference stay active and keep their history."
        },
        "keep_and_map": {
          "title": "Keep Groot’s chart and map",
          "description": "Keep Groot’s accounts and match your expense categories to {source} accounts. No second chart or category set is created."
        },
        "refresh": {
          "title": "Refresh the {source} chart",
          "description": "Add new accounts and update the ones {source} owns. Your edits, and accounts no longer in {source}, are kept."
        },
        "cancel": {
          "title": "Cancel",
          "description": "Nothing is imported."
        }
      },
      "types": {
        "Asset": "Assets",
        "Liability": "Liabilities",
        "Equity": "Equity",
        "Revenue": "Revenue",
        "Expense": "Expenses and cost of sales",
        "other": "Other accounts"
      },
      "reasons": {
        "posted_history": "posted history",
        "posting_target": "posting role",
        "gl_target": "bank link",
        "has_child_account": "child accounts",
        "bank_suggestion": "bank suggestion",
        "bank_recon_rule": "bank rule",
        "solo_category_rule": "category rule",
        "fee_classification_rule": "fee rule",
        "catalog_item_gl": "catalogue item",
        "category_mapping": "expense category",
        "draft_history": "journal draft",
        "party_account": "customer or supplier account",
        "fixed_asset": "fixed asset",
        "income_assignment": "income account setting",
        "recurring_expense": "recurring bill",
        "cash_sale_draft": "draft cash sale",
        "connector_gateway": "store payment method",
        "payment_source": "payment source",
        "not_starter": "added by you",
        "edited": "edited by you",
        "referenced": "in use",
        "other": "in use"
      },
      "confirm": {
        "button": "Confirm and import",
        "working": "Importing…",
        "cancel": "Cancel",
        "retry": "Try again",
        "sentence": {
          "import": "Groot will add the {incoming, plural, one {# account} other {# accounts}} from {source} to your chart.",
          "replace": "Groot will replace its sample chart with {incoming, plural, one {# account} other {# accounts}} from {source}, archive {archives, plural, one {# unused sample account} other {# unused sample accounts}}, and keep {keeps, plural, one {# account} other {# accounts}} that something still uses.",
          "replaceOwn": "Groot will bring in {incoming, plural, one {# account} other {# accounts}} from {source}, archive {archives, plural, one {# account of yours that nothing uses} other {# accounts of yours that nothing uses}}, and keep {keeps, plural, one {# account} other {# accounts}} that something still uses.",
          "keep_and_map": "{mapped, plural, =0 {Groot will keep your chart exactly as it is.} one {Groot will keep your chart as it is and match # category to its {source} account.} other {Groot will keep your chart as it is and match # categories to their {source} accounts.}}",
          "refresh": "Groot will add {creates, plural, one {# new account} other {# new accounts}} from {source} and update {updates, plural, one {# account} other {# accounts}} that {source} owns.",
          "cancel": "Nothing will be imported."
        },
        "blocked": {
          "answers": "{count, plural, one {# answer is still needed above.} other {# answers are still needed above.}}",
          "checking": "Checking your answers…",
          "unavailable": "That option is not available any more. Choose another one."
        }
      }
    },
    "chartArrival": {
      "title": "Choose your chart of accounts",
      "compare": "Compare charts",
      "grootTab": "Groot chart",
      "providerTab": "SQL Account chart",
      "grootTitle": "Your Groot chart ({count} accounts)",
      "postedCount": "{count} accounts hold postings",
      "providerTitle": "From SQL Account ({count} accounts)",
      "choose": "What should Groot use?",
      "options": {
        "import": {
          "title": "Import SQL Account chart",
          "description": "Use SQL Account accounts in Groot. Suppliers and customers are imported only when selected."
        },
        "replace": {
          "title": "Replace Groot’s sample chart",
          "description": "Use SQL Account’s chart. Unused sample accounts are archived. Accounts kept for a role, category or other reference stay active and retain their history."
        },
        "keep_and_map": {
          "title": "Keep Groot’s chart and map",
          "description": "Keep Groot’s accounts. Import the selected records and map expense categories to their SQL Account accounts. No second chart or category set is created."
        },
        "refresh": {
          "title": "Refresh SQL Account chart",
          "description": "Add new accounts and refresh import-owned accounts. Your edits and accounts no longer in SQL Account are kept."
        },
        "cancel": {
          "title": "Cancel",
          "description": "Nothing is imported."
        }
      },
      "consequences": "With these answers: {creates} accounts added, {archives} sample accounts archived, {keeps} kept.",
      "finalizeLater": "To retire Groot’s chart later, you will be able to Finalize onto SQL Account’s chart.",
      "roleList": "Payment & posting",
      "roleHelp": "Choose a SQL Account account for each posting role, or explicitly keep its Groot account.",
      "pickAccount": "Choose an account",
      "keepRole": "Keep Groot’s account for this role",
      "keepCategory": "Keep this category as it is",
      "categoryList": "Expense categories",
      "mapHelp": "Map each category to its SQL Account account, or explicitly keep it as it is. Existing manual mappings are preserved.",
      "categoryHelp": "Choose the account each category will use. A paired SQL account does not create a second category.",
      "historyList": "References and history",
      "historyHelp": "{count} accounts have other references. Referenced accounts stay active; posted entries are never changed.",
      "sampleOnly": "Showing a sample of 40. The total above includes every referenced account.",
      "apply": "Apply selected choice",
      "previewLoading": "Checking your chart and its references…",
      "previewFailed": "We could not check your chart. Try again before importing.",
      "preservedMappings": "{count} manual mappings were kept. Review Map codes before sending to SQL Account.",
      "types": {
        "Asset": "Assets",
        "Liability": "Liabilities",
        "Equity": "Equity",
        "Revenue": "Revenue",
        "Expense": "Expenses and cost of sales"
      },
      "references": {
        "posted_history": "posted history",
        "posting_target": "posting role",
        "gl_target": "bank link",
        "has_child_account": "child accounts",
        "bank_suggestion": "bank suggestion",
        "bank_recon_rule": "bank rule",
        "solo_category_rule": "category rule",
        "fee_classification_rule": "fee rule",
        "catalog_item_gl": "catalogue item",
        "category_mapping": "expense category",
        "draft_history": "journal draft",
        "fixed_asset": "fixed asset",
        "income_assignment": "income account setting",
        "recurring_expense": "recurring bill",
        "cash_sale_draft": "draft cash sale",
        "connector_gateway": "store payment method",
        "payment_source": "payment source"
      },
      "errors": {
        "choiceRequired": "Choose how to use the SQL Account chart before importing.",
        "choiceUnavailable": "This choice is unavailable because your chart is already in use. Keep and map, or cancel.",
        "planStale": "Your chart changed. Review the latest chart and choose again.",
        "decisionsRequired": "Answer each posting role and category before applying.",
        "accountsConflict": "Some incoming accounts conflict with your chart. Review them in Chart of Accounts before importing.",
        "mappingInvalid": "Choose an account of the right type for each category.",
        "postingInvalid": "Choose a compatible account in Payment & posting.",
        "postingHeading": "That account has other accounts under it, so it can't take postings itself. Choose one that takes postings directly in Payment & posting."
      }
    }
  },
  "weighbridgeTicket": {
    "open": "Read a ticket",
    "title": "Read a weighbridge ticket",
    "description": "Choose a photo of the ticket, cover the driver's details, then check every field the reader proposes. Nothing is posted and nothing is billed.",
    "pick": {
      "description": "Choose a photo of the weighbridge ticket. Next you cover the driver's name and I/C number on this device, and the covered photo is what gets read. The photo is not stored.",
      "choose": "Choose a photo of the ticket",
      "formats": "PNG or JPEG. A PDF or HEIC file cannot be read here: type the values from the slip instead.",
      "typeByHand": "Type a ticket by hand"
    },
    "cover": {
      "title": "Cover the driver's details before the photo is read",
      "help": "Some slips print the driver's name and I/C number. Drag over those lines to cover them. The covering is painted into the photo on this device, and only the covered photo is sent to be read.",
      "surfaceLabel": "The ticket photo. Drag to cover an area.",
      "noneYet": "Nothing covered yet.",
      "count": "{count, plural, one {# area covered.} other {# areas covered.}}",
      "turnLeft": "Turn left",
      "turnRight": "Turn right",
      "undo": "Undo last cover",
      "clear": "Clear covers",
      "turnClears": "Turning the photo clears the covered areas, so cover them again after turning.",
      "answerLabel": "Driver details on this slip",
      "answer": {
        "covered": "I covered the driver's name and I/C number",
        "none": "This slip shows no driver name or I/C number"
      },
      "read": "Read ticket",
      "back": "Choose another photo",
      "readHint": "Choose one of the two answers above to continue.",
      "preparing": "Preparing the photo. You can cover areas once it appears.",
      "drawHint": "Drag over the driver's name and I/C number on the photo to cover them, then press Read ticket.",
      "drawingOff": "Drawing is off because you said the slip shows no driver details. Choose \"I covered the driver's name and I/C number\" to draw areas again."
    },
    "reading": "Reading the ticket...",
    "review": {
      "title": "Check every field",
      "help": "Nothing is accepted for you. Check each field against the photo and correct what is wrong. A field the reader could not read is left empty.",
      "zoom": "Zoom the photo",
      "closeZoom": "Close",
      "photoAlt": "The covered ticket photo that was read",
      "photoNote": "This is the covered photo that was read. It is not stored.",
      "readAgain": "Read again",
      "readAgainHelp": "If the text looks sideways, turn the photo and read it again. This replaces the fields with the new reading, and you can do it once.",
      "readAgainUsed": "You have used the one re-read for this photo. Correct the fields by hand.",
      "confirm": "Confirm ticket",
      "startOver": "Start over",
      "confirmBlocked": "Fix the fields marked above to confirm."
    },
    "sections": {
      "slip": "The slip",
      "weighings": "The two weighings",
      "printed": "Lines printed on the slip"
    },
    "weighingsHelp": "List the two weights in the order the slip prints them. The heavier weight is the loaded lorry, whichever came first.",
    "notRead": "Not read: type it from the photo.",
    "dateInWords": "Ticket date: {date}",
    "fields": {
      "slipNumber": "Ticket number",
      "issuerName": "Weighbridge name",
      "issuerRegistration": "Weighbridge registration number (optional)",
      "vehicle": "Vehicle number (optional)",
      "unit": "Unit printed on the slip (optional)",
      "weight1": "First weight listed",
      "weight2": "Second weight listed",
      "date1": "Date",
      "date2": "Second date (only if the slip prints one on each weighing)",
      "time1": "Time of the first weighing (optional)",
      "time2": "Time of the second weighing (optional)",
      "nett": "Nett weight printed (optional)",
      "deduct": "Deduct printed",
      "final": "Final weight printed (optional)",
      "deductLine": "Does this slip print a deduct line?",
      "issuerNotPrinted": "The weighbridge name is not printed on this slip"
    },
    "deductLine": {
      "printed": "Yes, it prints a deduct line",
      "none": "No deduct line on this slip"
    },
    "result": {
      "title": "What the slip works out to",
      "gross": "Heavier weight (gross)",
      "tare": "Lighter weight (tare)",
      "nett": "Nett (heavier minus lighter)",
      "billable": "Billable weight",
      "pending": "Complete the fields above",
      "needWeights": "Enter both weights to see the nett.",
      "heavyFirst": "The heavier weight was weighed first on this slip.",
      "heavySecond": "The heavier weight was weighed second on this slip.",
      "billingBasis": "The billable weight is the nett minus any deduct. It is the weight that will be billed."
    },
    "blocks": {
      "SLIP_NUMBER_REQUIRED": "Type the ticket number printed on the slip.",
      "ISSUER_REQUIRED": "Type the weighbridge's name from the top of the slip, or tick that it is not printed on this slip.",
      "FIELD_LOOKS_LIKE_ID_NUMBER": "That looks like a personal I/C number. Do not enter it here.",
      "DATE_REQUIRED": "Type the date printed on the slip.",
      "DATE_INVALID": "This is not a real date. Dates are read day first, so 08/09/26 is 8 September 2026.",
      "DATE_IN_FUTURE": "This date is in the future for your business.",
      "WEIGHT_REQUIRED": "Type this weight from the slip.",
      "WEIGHT_INVALID": "This is not a weight. Use digits, for example 16,200 or 16,200 kg.",
      "WEIGHT_UNIT_UNKNOWN": "The unit is not clear. Add kg or MT, or type a whole number of kilograms.",
      "WEIGHT_NOT_WHOLE_KG": "A weight must be a whole number of kilograms.",
      "WEIGHT_NOT_POSITIVE": "A weight must be more than zero.",
      "DEDUCT_LINE_UNANSWERED": "Say whether this slip prints a deduct line.",
      "DEDUCT_REQUIRED": "This slip prints a deduct line. Type the deduct, or 0 if it shows 0.",
      "DEDUCT_INVALID": "The deduct must be a whole number of kilograms, 0 or more.",
      "DEDUCT_LINE_CONFLICT": "The slip has no deduct line, but a deduct is typed. Clear it.",
      "NETT_INVALID": "The printed nett is not a weight.",
      "NETT_MISMATCH": "The printed nett is not the heavier weight minus the lighter one. Check both weights and the nett against the photo.",
      "FINAL_INVALID": "The printed final weight is not a weight.",
      "FINAL_MISMATCH": "The printed final weight is not the nett minus the deduct. Check the deduct and the final weight against the photo.",
      "BILLABLE_NOT_POSITIVE": "The billable weight must be more than zero. Check the two weights and the deduct.",
      "WEIGHT_UNIT_UNSUPPORTED": "This unit is not supported here. Use kg or MT, or type the weights in kilograms by hand.",
      "WEIGHT_UNIT_AMBIGUOUS": "A bare ton can mean different weights, so it cannot be read. Use MT (metric tons) or kg, or type the weights in kilograms by hand.",
      "NETT_REQUIRED": "This line is printed on the slip but was not read. Type the nett weight from the photo so it can be checked.",
      "FINAL_REQUIRED": "This line is printed on the slip but was not read. Type the final weight from the photo so it can be checked."
    },
    "notices": {
      "BILLABLE_ABOVE_CEILING": "This is a very heavy load for one vehicle. Check the digits against the photo.",
      "TIME_OUT_BEFORE_IN": "The second time is earlier than the first. This can be an overnight stay or a wrong clock. Check it.",
      "TIME_AMBIGUOUS_12H": "One time has no AM or PM. Check which it is.",
      "ROW_DATES_APART": "The two dates are more than a day apart. Check them.",
      "TIME_UNREADABLE": "This time could not be read. It is for reference only."
    },
    "unavailable": {
      "unsupported": "This file type cannot be read here. Type the values from the slip below.",
      "too_large": "This file is over 10 MB. Choose a smaller photo, or type the values below.",
      "too_many_pixels": "This photo has too many pixels to open safely. Take it at a lower resolution, or type the values below.",
      "too_small": "This photo is too small or empty to read. Take a closer photo, or type the values below.",
      "blank": "This photo is too small or empty to read. Take a closer photo, or type the values below.",
      "unreadable": "This photo could not be opened. Choose another file, or type the values below.",
      "timeout": "Reading took too long. Nothing was saved. Try once more, or type the values from the photo below.",
      "provider_unavailable": "The reader is not available right now. Nothing was saved. Type the values from the photo below, or try again later.",
      "invalid_shape": "The reader's answer could not be used. Nothing was saved. Type the values from the photo below.",
      "generic": "The ticket could not be read. Nothing was saved. Type the values from the photo below."
    },
    "lowConfidence": {
      "title": "The reader is not sure about this ticket. Check every field with care.",
      "not_recognised": "This does not look like a weighbridge ticket the reader knows. Type the values from the photo.",
      "checks_failed": "The numbers the reader found do not add up. Check each weight against the photo.",
      "unreadable_fields": "Some lines were seen but could not be read. They are left empty.",
      "photo_quality": "The photo is blurred, dark, cut off or has glare. A clearer photo reads better."
    },
    "errors": {
      "photoOpen": "This photo could not be prepared. Choose another photo, or type the values.",
      "notAuthorized": "You do not have access to read tickets for this business.",
      "network": "Could not reach the server. Nothing was saved. Check your connection and try again.",
      "checksFailed": "The ticket did not pass the checks. Fix the fields marked above.",
      "confirmFailed": "The ticket was not saved. Please try again.",
      "coverStale": "The photo changed after the areas were covered, so nothing was sent. Cover the areas again on the photo shown, then press Read ticket."
    },
    "duplicate": {
      "exact": "Ticket {number} dated {date} is already confirmed. It is waiting for a delivery.",
      "lookalike": "This looks like ticket {number} dated {date}: same weighbridge, day, weights and vehicle. Check that it is not the same load.",
      "show": "Show that ticket",
      "hide": "Hide that ticket",
      "loading": "Loading that ticket...",
      "missing": "That ticket could not be shown."
    },
    "done": {
      "message": "Ticket {number} dated {date} is confirmed. It is waiting for a delivery. Nothing was posted or billed.",
      "another": "Read another ticket",
      "close": "Close"
    },
    "list": {
      "title": "Confirmed tickets",
      "loading": "Loading tickets...",
      "empty": "No tickets confirmed yet.",
      "columns": {
        "ticket": "Ticket",
        "date": "Date",
        "vehicle": "Vehicle",
        "gross": "Gross (kg)",
        "tare": "Tare (kg)",
        "nett": "Nett (kg)",
        "deduct": "Deduct (kg)",
        "billable": "Billable (kg)",
        "status": "Status"
      },
      "status": {
        "confirmed": "Waiting for a delivery"
      },
      "provenance": {
        "read": "Read from a photo (reader {version}, {model}).",
        "typed": "Typed by hand."
      },
      "edits": {
        "none": "You changed no field.",
        "some": "You changed: {fields}."
      },
      "cover": {
        "covered": "Covered before reading.",
        "none_to_cover": "Nothing to cover."
      },
      "confirmedBy": "Confirmed by {name}, {when}",
      "issuerNotPrinted": "Weighbridge name not printed on the slip",
      "loadMore": "Load more",
      "loadingMore": "Loading more tickets..."
    },
    "access": {
      "denied": "Weighbridge tickets are not available to you in this business right now (your access changed, or the plan that includes them is off). Ask the business owner."
    }
  },
  "convertDeliveryNotice": {
    "title": "This order already has deliveries",
    "line": "{delivered} of {ordered} delivered.",
    "lineNamed": "{description}: {delivered} of {ordered} delivered.",
    "moreLines": "And more lines.",
    "billsWhole": "Convert invoices the whole order ({whole}), not the delivered part ({part}).",
    "billsWholeNoPart": "Convert invoices the whole order ({whole}), not only what was delivered.",
    "createFromDeliveries": "Create invoice from deliveries"
  },
  "deliveredNotInvoicedCard": {
    "columns": {
      "delivery": "Delivery",
      "date": "Date",
      "customer": "Customer",
      "order": "Order",
      "po": "Your PO",
      "estimate": "Estimate"
    }
  },
  "myinvoisConnection": {
    "title": "Let Groot file your e-invoices",
    "intro": "Groot sends your e-invoices to LHDN as your intermediary. A company director allows this once, inside MyInvois. Groot never sees your MyTax password.",
    "badge": {
      "notChecked": "Not checked",
      "checking": "Checking",
      "connected": "Connected",
      "notAuthorized": "Not connected yet",
      "grootProblem": "Problem on our side",
      "lhdnUnavailable": "MyInvois not answering",
      "notSwitchedOn": "Not switched on yet",
      "tinMissing": "TIN needed",
      "busy": "Try again soon",
      "notAllowed": "No access",
      "demo": "Demo workspace",
      "checkFailed": "Not checked",
      "tinNotConfirmed": "Waiting for Groot"
    },
    "openMyinvois": "Open MyInvois",
    "fieldTin": "TIN",
    "fieldBrn": "BRN",
    "fieldName": "Name",
    "copy": "Copy",
    "copyField": "Copy {label}",
    "copied": "Copied",
    "checkButton": "Check connection",
    "checkingButton": "Checking",
    "copyStepsButton": "Copy steps for your director",
    "copyStepsDone": "Steps copied",
    "showSteps": "Show the setup steps",
    "hideSteps": "Hide the setup steps",
    "cooldown": "You can check again in a few seconds.",
    "environment": {
      "production": "MyInvois",
      "practice": "the MyInvois practice site"
    },
    "result": {
      "notChecked": "When the director has added Groot, check the connection here.",
      "connected": "Connected. Groot can file e-invoices for TIN {tin} on {environment}.",
      "notAuthorized": "MyInvois has not let Groot in for TIN {tin} yet. Finish the steps above. If the director added Groot just now, wait a minute and check again.",
      "grootProblem": "Groot could not sign in to MyInvois on our side, and our team has been alerted. Your MyInvois setup may already be correct.",
      "lhdnUnavailable": "MyInvois did not answer. Try again in a few minutes.",
      "notSwitchedOn": "Groot has not switched on e-invoice filing yet. You can do these steps now; the check works once filing is on.",
      "tinMissing": "Add your LHDN TIN above and save, then check again.",
      "busy": "Too many checks in a short time. Try again in a minute.",
      "notAllowed": "Only an owner, finance admin or manager can check the connection.",
      "demo": "This check is not available in a demonstration workspace.",
      "checkFailed": "We could not check the connection. Try again.",
      "tinNotConfirmed": "Groot confirms each business's LHDN TIN before it files or checks the connection on the live MyInvois. You can do the steps above now. To have your TIN confirmed, email support@hellogroot.com."
    },
    "directorMessage": "Please add Groot as our intermediary in MyInvois. It takes about 2 minutes and a company director has to do it.\n1. Sign in at {portal} with your MyTax login.\n2. Click your initials at the top right and choose {viewTaxpayerProfile}. If it is not our company, choose {switchTaxpayer} first.\n3. Scroll to {representatives}, open {intermediaries} and click {addIntermediary}.\n4. Enter TIN {tin}, BRN {brn} and name {name}, click the search button, then {continue}.\n5. Set {representationFrom} to today, leave {representationTo} empty, switch on every permission and click {addIntermediary}.\nThank you!",
    "guide": {
      "navLabel": "Setup steps",
      "jumpTo": "Step {n}: {title}",
      "stepOf": "Step {n} of {total}",
      "back": "Back",
      "next": "Next",
      "drawnNote": "A drawing of the MyInvois screen. Click the circled button; the numbers show the order.",
      "afterLast": "When MyInvois shows {savedSuccessfully}, come back to this page. Groot checks the connection by itself.",
      "steps": {
        "signIn": {
          "title": "Sign in to MyInvois as a company director",
          "body": "Only a director, or the owner of a sole proprietorship, can add an intermediary. Open MyInvois and sign in with your own MyTax login. Your password goes to LHDN only; Groot never sees it."
        },
        "profile": {
          "title": "Open {viewTaxpayerProfile}",
          "body": "Click your initials at the top right (1), then {viewTaxpayerProfile} (2). If the company shown under it is not this one, choose {switchTaxpayer} first and pick it."
        },
        "representatives": {
          "title": "Open {intermediaries}, then {addIntermediary}",
          "body": "Scroll down to {representatives}. Open the {intermediaries} tab (1), then click {addIntermediary} (2)."
        },
        "lookup": {
          "title": "Enter Groot's details, then {continue}",
          "body": "Type the TIN, BRN and name below; each has a copy button. Click the search button (1). MyInvois should show {isRegisteredAsIntermediary}: Yes. Then click {continue} (2)."
        },
        "permissions": {
          "title": "Switch on the permissions, then {addIntermediary}",
          "body": "Set {representationFrom} to today. Leave {representationTo} empty so the permission never ends; if MyInvois has filled in a date, clear it. Switch on every permission, then click {addIntermediary}."
        }
      }
    }
  },
  "mySales": {
    "page": {
      "title": "Customers",
      "subtitle": "Who you sell to, and where their invoices stand."
    },
    "loading": "Loading...",
    "refused": {
      "SALES_ACCESS_OFF": "Sales access is turned off for you. Ask the business owner or a finance admin to turn it back on.",
      "NOT_A_SALES_EMPLOYEE": "This page is only for team members who have Sales access.",
      "NOT_AVAILABLE": "This is not available for this business right now."
    },
    "customers": {
      "title": "My customers",
      "empty": "No customers are assigned to you yet. Ask the business owner or a finance admin to assign customers to you. A customer you add on a sales order is assigned to you automatically.",
      "partialEmpty": "Your customer list could not be read completely, so nothing is shown here. Reload the page to try again.",
      "truncated": "Showing {count} of your customers. There may be more.",
      "columns": {
        "name": "Name",
        "code": "Code",
        "contact": "Contact",
        "phone": "Phone",
        "email": "Email",
        "terms": "Payment terms"
      }
    },
    "invoices": {
      "title": "Invoices of my customers",
      "subtitle": "Status only. Finance issues and manages invoices.",
      "empty": "None of your customers has an invoice yet.",
      "partialEmpty": "Your invoice list could not be read completely, so nothing is shown here. Reload the page to try again.",
      "truncated": "Showing the newest {count} invoices. There may be older ones.",
      "columns": {
        "number": "Invoice",
        "customer": "Customer",
        "date": "Date",
        "due": "Due date",
        "total": "Total",
        "amountDue": "Amount due",
        "status": "Status"
      }
    },
    "invoiceStatus": {
      "sent": "Sent",
      "partially_paid": "Partly paid",
      "paid": "Paid",
      "overdue": "Overdue",
      "voided": "Voided"
    },
    "home": {
      "title": "My sales",
      "subtitle": "Where your quotations, orders and your customers' invoices stand.",
      "openQuotations": "Open quotations",
      "openOrders": "Open sales orders",
      "awaitingInvoice": "Accepted, waiting for an invoice",
      "invoicesTitle": "Invoices of my customers",
      "partial": "A number with a + may be higher: it counts only your newest documents."
    },
    "company": {
      "customers": {
        "title": "Customers",
        "empty": "This business has no customers yet.",
        "partialEmpty": "The customer list could not be read completely, so nothing is shown here. Reload the page to try again.",
        "truncated": "Showing {count} customers. There may be more."
      },
      "invoices": {
        "title": "Invoices",
        "empty": "No invoice has been issued yet.",
        "partialEmpty": "The invoice list could not be read completely, so nothing is shown here. Reload the page to try again.",
        "truncated": "Showing the newest {count} invoices. There may be older ones."
      }
    }
  },
  "sqlBridgeConnect": {
    "title": "Connect a SQL book to Groot",
    "description": "Choose the Groot business this SQL book belongs to. Bills for that business will go into this book.",
    "invalid": {
      "title": "Open this page from the Groot SQL Bridge on your PC",
      "body": "This link did not come from the Bridge, or part of it is missing. On the Windows PC, open the Groot SQL Bridge, choose the book and press Connect."
    },
    "book": {
      "company": "Company",
      "title": "Name inside the book",
      "titleUnknown": "Not read yet",
      "file": "File",
      "pc": "Windows PC",
      "reportedBy": "Reported by the Bridge on your PC"
    },
    "loading": "Loading your businesses",
    "loadFailed": "We could not load your businesses. Try again, and if it keeps happening, contact support.",
    "retry": "Try again",
    "noBusinesses": "You are not an owner or finance admin of any business, so you cannot connect a SQL book. Ask the business owner to connect it, or to make you a finance admin.",
    "choose": {
      "label": "Which Groot business is this?",
      "placeholder": "Choose a business",
      "notSwitchedOn": "{name} (SQL not switched on)",
      "staffSwitchOn": "A business marked not switched on needs Groot staff to switch SQL on for it first. Contact support to ask.",
      "truncated": "Showing the first {count} businesses."
    },
    "moves": {
      "from": "This moves {business} from {book} on {pc}. The other PC stops sending.",
      "fromUnknown": "This moves {business} from the PC it is connected to now. That PC stops sending.",
      "fromBook": "This moves {business} from {book} on {pc} to this book. Bills stop going to {book}.",
      "again": "{business} is already connected to {book} on {pc}. Connecting again replaces that link."
    },
    "confirmNote": {
      "withTitle": "Connecting also confirms this is the right company: Groot may post into the book named above. Connecting does not switch posting on. You control that in Groot.",
      "withoutTitle": "The Bridge could not read the name inside this book yet, so Groot will ask you to confirm the company once the Bridge reports it."
    },
    "connect": "Connect",
    "connecting": "Connecting",
    "refusals": {
      "not_entitled": "This feature is not switched on for your workspace. Contact support@hellogroot.com.",
      "autocount_bridge_enrolled": "An AutoCount Bridge is already set up for this business, and a business posts to one accounting program only. Revoke the AutoCount Bridge first if you want to switch to SQL Account.",
      "invalid_request": "This link is not valid any more. Go back to the Bridge and press Connect again.",
      "too_many_links": "Too many links are waiting for this business. Wait a few minutes and try again.",
      "generic": "We could not connect the book. Try again, and if it keeps happening, contact support."
    },
    "done": {
      "title": "Connected. Go back to the Bridge.",
      "body": "The Bridge on {pc} is finishing the link.",
      "fallback": "If the Bridge does not respond within a few seconds, open its window on {pc} and press Connect again."
    },
    "matchCode": "Check this code matches the one in the Bridge window: {code}. If you didn't press Connect in the Bridge, close this page."
  },
  "customerEmails": {
    "title": "Sent to the customer",
    "truncated": "Only some of the sends are shown.",
    "by": "by {name}",
    "kind": {
      "commercial_invoice": "Invoice",
      "lhdn_validated": "Validated e-invoice",
      "lhdn_lifecycle_notice": "E-invoice notice",
      "official_receipt": "Receipt",
      "other": "Email"
    },
    "state": {
      "queued": "Sending",
      "attempting": "Sending",
      "accepted": "Sent",
      "failed": "Not sent (failed)",
      "unknown": "Not confirmed",
      "reconciliation_required": "Needs checking"
    },
    "problem": {
      "notDelivered": "Not delivered",
      "notDeliveredSeveral": "Not delivered to at least one address",
      "notSent": "Not sent: this address bounced or reported spam before",
      "notSentSeveral": "Not sent to at least one address, which bounced or reported spam before",
      "spam": "Marked as spam by the recipient"
    }
  }
}
