# Usage & credits strings (English) — dash/credits.js. key=value; merged into Resources/UiMessages.resx by tools/ui-strings.py.
# shared
ui.credits.sub=Credit pools, what's been used, and what each action costs — across every license.
ui.credits.unitDefault=credits
ui.credits.amount=Amount ({0})
ui.credits.amountInvalid=Enter a whole number greater than zero.
ui.credits.amountMax=That's more than the {0} available.
ui.credits.balance=Balance
ui.credits.balanceNow=Balance is now {0}.
ui.credits.policy=Policy
ui.credits.source=Source tag
ui.credits.sourceHint=Free text, e.g. purchased or promotional. The pool's burn order can spend one tag before another.
ui.credits.expiresOn=These credits expire on
ui.credits.advanced=Advanced: idempotency key
ui.credits.idem=Idempotency key
ui.credits.idemHint=Optional. Repeating a request with the same key applies it once — safe to retry after a timeout.
ui.credits.idemSkipped=Already applied — a request with this key was processed before.
ui.credits.newPool=New pool
ui.credits.searchPh=Search pools by name, license, product or unit
ui.credits.filterLicense=License {0}
ui.credits.noMatches=No pools match
ui.credits.openLicense=Open license
ui.credits.notFound=That credit pool doesn't exist (or belongs to another workspace).
ui.credits.unitIs=counted in {0}
ui.credits.licenseLink=license {0}
ui.credits.usedOf={0} used of {1} ever entitled
ui.credits.noEntitledYet=Nothing granted yet — grant or top up to give this pool a balance.
ui.credits.lowAt=Low-balance alert at {0}
ui.credits.generatedAt=as of {0}
ui.credits.col.pool=Pool
ui.credits.exhausted=Exhausted
ui.credits.low=Running low
ui.credits.healthy=Healthy
# sub-navigation
ui.credits.tab.overview=Overview
ui.credits.tab.pools=Pools
ui.credits.tab.events=Events
ui.credits.tab.pricing=Pricing
# policy vocabulary
ui.credits.overage.hard=Stops at zero
ui.credits.overage.soft=Warns and continues past zero
ui.credits.overage.auto=Asks your billing to top up at zero
ui.credits.cadence.never=Never resets
ui.credits.cadence.daily=Resets daily
ui.credits.cadence.monthly=Resets monthly
ui.credits.cadence.billing=Resets each billing cycle
ui.credits.status.ok=Done.
ui.credits.status.insufficient=Not enough credits.
ui.credits.status.notToppable=This pool doesn't accept top-ups.
ui.credits.pol.resets={0}
ui.credits.pol.noReset=never resets
ui.credits.pol.toppable=top-ups allowed
ui.credits.pol.quota=fixed quota (no top-ups)
ui.credits.pol.rollover=unused credits roll over
ui.credits.pol.expires=expires {0}
ui.credits.f.topups=Top-ups
ui.credits.f.allowed=Allowed
ui.credits.f.notAllowed=Not allowed — this pool is a fixed quota
ui.credits.f.rollover=Unused credits roll over
ui.credits.f.yes=Yes
ui.credits.f.no=No — unused credits are forfeited at reset
ui.credits.f.onLicenseExpiry=When the license expires
ui.credits.f.stops=Credits stop working
ui.credits.f.survives=Credits keep working (win-back)
ui.credits.f.burnDefault=Expiring soonest first (default)
# how it works
ui.credits.how.title=How credits work
ui.credits.how.body1=A credit pool is a balance on a license. Your app names an action ("image.generate"), Keyright prices it from the product's pricing table and deducts from the right pool — atomically, so two requests can never spend the same credit.
ui.credits.how.body2=When a pool runs low or out, Keyright raises an event (and a webhook) with a suggested top-up. Charging the customer stays in your billing system; Keyright never takes payment.
ui.credits.how.pricingLink=Set what each action costs
# overview
ui.credits.ov.entitled=Entitled
ui.credits.ov.consumed=Consumed
ui.credits.ov.balance=Available
ui.credits.ov.pools=Pools
ui.credits.ov.pctOfEntitled={0}% of everything entitled
ui.credits.ov.mixedUnits=mixed units — totals add pools with different units
ui.credits.ov.nExhausted={0} pool is exhausted|{0} pools are exhausted
ui.credits.ov.allHealthy=none exhausted
ui.credits.ov.byPool=By pool
ui.credits.ov.emptyTitle=No credit pools yet
ui.credits.ov.emptyProduct=No credit pools for this product
ui.credits.ov.emptyBody=Credits meter usage-based features: give a license a pool, price your actions, and let the app deduct as it works.
# pools list
ui.credits.pools.title=Credit pools
ui.credits.pools.sub=Every pool across your licenses. Open one to grant, top up, correct, transfer or issue offline blocks.
ui.credits.pools.emptyTitle=No credit pools yet
ui.credits.pools.emptyBody=A pool belongs to a license. Create one here or from the license's Credits tab.
# new pool drawer
ui.credits.np.lead=A pool is a named balance on one license. The settings below are the pool's policy — you can't change them later, but you can create another pool.
ui.credits.np.licenseHint=The license key this pool belongs to.
ui.credits.np.name=Pool name
ui.credits.np.namePh=e.g. tokens, images, api-calls
ui.credits.np.nameHint=What your app will ask for by name. Keep it short and stable.
ui.credits.np.unit=Unit
ui.credits.np.unitHint=Shown next to every number: "tokens", "images", "requests".
ui.credits.np.productAuto=Same as the license
ui.credits.np.productHint=Pricing tables are per product; leave as the license's product unless you know otherwise.
ui.credits.np.kind=Kind of pool
ui.credits.np.kindCredits=Credit pool
ui.credits.np.kindCreditsD=the customer buys and tops up credits; they expire on their own schedule.
ui.credits.np.kindQuota=Usage quota
ui.credits.np.kindQuotaD=a fixed allowance that resets on a schedule; no top-ups, no rollover.
ui.credits.np.toppable=Top-ups allowed
ui.credits.np.toppableD=off makes this a fixed quota — top-up requests are refused.
ui.credits.np.rollover=Roll over unused credits
ui.credits.np.rolloverD=off forfeits what's left at each reset.
ui.credits.np.cadence=Reset schedule
ui.credits.np.cadenceHint=When the balance starts over. "Never" for purchased credits.
ui.credits.np.expiry=Pool expires on
ui.credits.np.expiryHint=Optional. After this date the whole balance stops working, whatever the license says.
ui.credits.np.licInv=License expiry stops the credits
ui.credits.np.licInvD=off lets a lapsed customer keep spending what they bought — a win-back incentive.
ui.credits.np.overage=When the balance hits zero
ui.credits.np.overageHint="Asks your billing" raises an event; Keyright never charges a card.
ui.credits.np.low=Low-balance alert at
ui.credits.np.lowHint=Optional. Crossing below this raises a "running low" event with a suggested top-up.
ui.credits.np.lowInvalid=Enter a whole number, or leave it blank.
ui.credits.np.burn=Spend order
ui.credits.np.burnHint=Optional, comma-separated source tags to spend first, e.g. promotional, purchased. Blank = expiring soonest first.
ui.credits.np.done=Pool "{0}" created
# usage
ui.credits.usage.title=Usage
ui.credits.usage.lead=What came in, what went out, and what's left — as of the end of the range.
ui.credits.usage.range=Range
ui.credits.usage.days=Last {0} days
ui.credits.usage.capTitle=Your plan keeps {0} days of usage history.
ui.credits.usage.capBody=The last {0} days are shown as far back as your history goes.
ui.credits.usage.forfeited=Forfeited
ui.credits.usage.forfeitedHint=Credits that expired or were voided before they were used.
ui.credits.usage.noUsage=No usage in this range
ui.credits.usage.noUsageBody=Consumption shows up here as soon as the app deducts from this pool.
ui.credits.usage.chartTitle=Consumed per period ({0})
ui.credits.usage.chartCaption={0} consumed per {1}; the newest bar is highlighted.
ui.credits.usage.grantedN={0} granted
ui.credits.usage.anomalies=Anything unusual
ui.credits.usage.noAnomalies=Nothing unusual in this range.
ui.credits.usage.downloadCsv=Download ledger (CSV)
ui.credits.bucket.day=day
ui.credits.bucket.week=week
ui.credits.bucket.month=month
ui.credits.anom.spike=Consumption spike
ui.credits.anom.postExpiry=Usage after expiry
# offline blocks
ui.credits.blocks.title=Offline credit blocks
ui.credits.blocks.btn=Offline block
ui.credits.blocks.lead=For air-gapped machines: carve a signed, finite block out of this pool. The machine spends it offline; when it reconnects you reconcile what was actually used and the rest returns to the pool.
ui.credits.blocks.planCap=Your plan caps a single block at {0}.
ui.credits.blocks.planNoCap=No block size cap on this instance.
ui.credits.blocks.planSync=Blocks default to a {0}-hour sync window.
ui.credits.blocks.planNoSync=Blocks have no default sync window — set an expiry per block.
ui.credits.blocks.lockTitle=Offline credit blocks are part of a higher plan.
ui.credits.blocks.lockBody=You can see blocks issued before and reconcile them; issuing new ones needs an upgrade.
ui.credits.blocks.issue=Issue block
ui.credits.blocks.issueLead=The pool has {0} available. The block is deducted now and whatever isn't used comes back when you reconcile.
ui.credits.blocks.trustTitle=Offline credits are trust-extended, not live-enforced.
ui.credits.blocks.trustBody=A disconnected machine can overspend a single block between syncs; reconciliation trues up on reconnect. Keep blocks small and windows short.
ui.credits.blocks.amountHint=Whole number, up to the pool's balance.
ui.credits.blocks.amountHintCap=Whole number, up to the pool's balance and your plan's cap of {0}.
ui.credits.blocks.machineHint=Optional. Binds the block to one machine id so it can't be replayed elsewhere.
ui.credits.blocks.expiresHint=Optional. After this the block can't be spent; reconcile it to recover the remainder.
ui.credits.blocks.expiresHintSync=Leave blank for your plan's default {0}-hour window.
ui.credits.blocks.issued=Block issued
ui.credits.blocks.issuedTitle=A {0} block is ready.
ui.credits.blocks.issuedBody=Copy or download it now and hand it to the machine — it isn't shown again. Pool balance is now {0}.
ui.credits.blocks.copy=Copy block
ui.credits.blocks.download=Download .json
ui.credits.blocks.emptyTitle=No offline blocks
ui.credits.blocks.emptyBody=Blocks you issue for air-gapped machines appear here with their reconcile status.
ui.credits.blocks.col.block=Block
ui.credits.blocks.col.amount=Amount
ui.credits.blocks.col.issued=Issued
ui.credits.blocks.col.expires=Expires
ui.credits.blocks.boundTo=bound to {0}
ui.credits.blocks.anyMachine=any machine
ui.credits.blocks.reconciled=Reconciled
ui.credits.blocks.reconciledDetail={0} used, {1} returned · {2}
ui.credits.blocks.outstanding=Outstanding
ui.credits.blocks.overdue=Expired, not reconciled
ui.credits.blocks.reconcile=Reconcile
ui.credits.blocks.reconcileLead=This {0} block was issued for {1}. Enter what the machine actually used; the rest goes back to the pool.
ui.credits.blocks.consumed=Credits used offline
ui.credits.blocks.consumedHint=0 up to {0}. Take it from the machine's usage export.
ui.credits.blocks.consumedInvalid=Enter a whole number from 0 to {0}.
ui.credits.blocks.reconcileConfirm=Reconcile this block?
ui.credits.blocks.reconcileConfirmBody={0} will be recorded as used and {1} returned to the pool. This closes the block and can't be undone.
ui.credits.blocks.reconciledToast=Reconciled — {0} returned to the pool (balance {1}).
# grant
ui.credits.grant.btn=Grant
ui.credits.grant.title=Grant credits
ui.credits.grant.lead=Add credits regardless of the pool's top-up policy — for seeding, corrections and goodwill. Balance now: {0}.
ui.credits.grant.reason=Reason
ui.credits.grant.reasonPh=order #1234, goodwill, migration…
ui.credits.grant.reasonHint=Recorded in the ledger so support can see why.
ui.credits.grant.expiresHint=Optional. Blank follows the pool's expiry.
ui.credits.grant.do=Grant
ui.credits.grant.done=Granted {0}
# top up
ui.credits.topup.btn=Top up
ui.credits.topup.title=Top up
ui.credits.topup.lead=Add purchased, promotional or rolled-over credits mid-cycle. Balance now: {0}.
ui.credits.topup.sourceHint=Purchased credits are spent last by default; promotional and rollover first.
ui.credits.topup.expiresHint=Optional. When this top-up's credits stop working.
ui.credits.topup.do=Top up
ui.credits.topup.done=Topped up {0}
ui.credits.topup.notToppableShort=This pool is a fixed quota — it doesn't accept top-ups.
ui.credits.topup.notToppableBody=It was created with top-ups off, so it behaves like an allowance that resets on its schedule. The app's top-up requests are refused too.
ui.credits.topup.useGrant=Need to add credits anyway? Grant is the admin override: it bypasses the policy and is recorded as such.
ui.credits.src.purchased=Purchased
ui.credits.src.promotional=Promotional / free
ui.credits.src.rollover=Rollover
# correct / deduct
ui.credits.deduct.btn=Correct
ui.credits.deduct.title=Correct the balance
ui.credits.deduct.lead=Remove credits — to fix a mistaken grant or settle usage recorded elsewhere. Balance now: {0}; this pool {1}.
ui.credits.deduct.sourceHint=Why, in a word — shows in the ledger.
ui.credits.deduct.dry=Dry run
ui.credits.deduct.dryD=preview whether the deduction would succeed and the balance afterwards, without changing anything.
ui.credits.deduct.preview=Preview
ui.credits.deduct.apply=Deduct
ui.credits.deduct.confirm=Deduct credits?
ui.credits.deduct.confirmBody={0} will be removed from "{1}". The ledger records it; it can only be reversed by granting credits back.
ui.credits.deduct.wouldSucceed=Would succeed.
ui.credits.deduct.balanceAfter=Balance afterwards would be {0}.
ui.credits.deduct.applied=Deducted {0}
# transfer
ui.credits.transfer.btn=Transfer
ui.credits.transfer.title=Transfer credits
ui.credits.transfer.lead=Move part of this balance to another pool — the source is never overdrawn. Available: {0}.
ui.credits.transfer.to=To pool
ui.credits.transfer.toHint=Other pools on the same license.
ui.credits.transfer.noSiblings=No other pools on this license
ui.credits.transfer.noSiblingsHint=This license has only one pool. Paste another pool's id under Advanced to transfer across licenses.
ui.credits.transfer.other=Or another pool id
ui.credits.transfer.otherPh=Pool id from another license
ui.credits.transfer.otherHint=Overrides the selection above. Both pools must be in your workspace.
ui.credits.transfer.unitMismatch=The destination counts a different unit — credits move 1:1 regardless.
ui.credits.transfer.destExpires=Expire in the destination on
ui.credits.transfer.destExpiresHint=Optional. Blank keeps the destination pool's expiry.
ui.credits.transfer.do=Transfer
ui.credits.transfer.done=Transferred {0}
ui.credits.transfer.balances=Source now {0}; destination now {1}.
# events
ui.credits.ev.title=Credit events
ui.credits.ev.sub=Every time a pool ran low or out, with the top-up Keyright suggested. Your billing system gets the same events as webhooks.
ui.credits.ev.webhooks=Event webhooks
ui.credits.ev.type=Type
ui.credits.ev.allTypes=All events
ui.credits.ev.low=Running low
ui.credits.ev.exhausted=Exhausted
ui.credits.ev.licensePh=Filter by license key — press Enter
ui.credits.ev.when=When
ui.credits.ev.balanceAt=Balance then
ui.credits.ev.suggested=Suggested top-up
ui.credits.ev.suggestedLine=suggested top-up {0}
ui.credits.ev.emptyTitle=No credit events yet
ui.credits.ev.emptyBody=Set a low-balance alert on a pool and events appear here as customers approach zero.
# pricing (action costs)
ui.credits.pricing.title=Action pricing
ui.credits.pricing.sub=What each action costs in credits, per product. Change a ratio here — no redeploy needed.
ui.credits.pricing.needProduct=Create a product first — pricing tables belong to a product.
ui.credits.pricing.tableFor=Pricing for {0}
ui.credits.pricing.lead=Your app calls consume with an action name; Keyright looks the name up here, multiplies by the quantity and deducts from the pool.
ui.credits.pricing.action=Action
ui.credits.pricing.actionHint=The exact name your app sends, e.g. image.generate. Unknown names are refused, not charged.
ui.credits.pricing.cost=Credits per unit
ui.credits.pricing.costPerUnit=Credits per unit of this action
ui.credits.pricing.costHint=Whole number; 0 makes the action free but still counted.
ui.credits.pricing.costInvalid=Enter a whole number of zero or more.
ui.credits.pricing.nCredits={0} credit|{0} credits
ui.credits.pricing.pool=Pool
ui.credits.pricing.poolPh=e.g. output-tokens
ui.credits.pricing.poolHint=Optional pool name to deduct from. Blank uses the license's spend order.
ui.credits.pricing.poolDefault=license's spend order
ui.credits.pricing.updated=Updated
ui.credits.pricing.add=Add action
ui.credits.pricing.edit=Edit
ui.credits.pricing.editTitle=Edit "{0}"
ui.credits.pricing.dialogLead=One row per action your app meters. Editing takes effect on the next consume call.
ui.credits.pricing.saved="{0}" costs {1}
ui.credits.pricing.removeTitle=Remove "{0}" from pricing?
ui.credits.pricing.removeBody=The app's consume calls for "{0}" will be refused as an unknown action until you add it back.
ui.credits.pricing.removed="{0}" removed
ui.credits.pricing.emptyTitle=No actions priced yet
ui.credits.pricing.emptyBody=Add the actions your app meters and what each costs — "1 API call = 1 credit", "1 image = 15 credits".
ui.credits.pricing.howTitle=From your app
ui.credits.pricing.howBody1=Name the action and the license; Keyright prices it and deducts atomically. Pass an idempotency key so a retried request never double-charges.
ui.credits.pricing.howBody2=Add "dryRun": true to ask "would this succeed?" before expensive work.
# license page · Credits tab
ui.credits.lic.poolsTitle=Credit pools
ui.credits.lic.emptyTitle=This license has no credit pools
ui.credits.lic.emptyBody=Credits meter usage-based features: create a pool, give it a balance, price your actions, and the app deducts as it works. Nothing changes for this customer until you do.
ui.credits.lic.usageAndBlocks=Usage & offline blocks
ui.credits.lic.recentEvents=Recent credit events
ui.credits.lic.noEvents=No low-balance or exhausted events for this license.

ui.credits.np.create=Create pool
ui.credits.np.advanced=Advanced: limits, renewal and alerts
