# BlackLang I18n

BlackLang i18n separates generated UI text from storage field names.

## Syntax

```black
i18n {
  default tr
  locales tr, en
}

label Product.name {
  tr "Ürün Adı"
  en "Product Name"
}
```

## Rules

- Use one `i18n` block per project.
- `default` declares the locale used by generated web output today.
- `locales` declares every locale accepted by translation blocks.
- The default locale must also be listed in `locales`.
- Top-level `label` blocks currently target entity fields with `Entity.field`.
- Generated web UI uses the default locale translation first.
- If no translation exists, generated UI falls back to the field `label "Text"` modifier.
- If no field label modifier exists, generated UI falls back to title-cased field name.

## Current Scope

Draft v0.2 uses label translations for generated field labels in:

- table filter labels
- column visibility labels
- table headers
- detail panel labels
- form labels
- frontend form validation labels

Runtime language switching, date format, number format, currency format, and RTL support are later extensions.

## Diagnostics

```text
INVALID_I18N_DECLARATION
DUPLICATE_I18N
INVALID_I18N_DEFAULT
DUPLICATE_I18N_DEFAULT
MISSING_I18N_DEFAULT
INVALID_I18N_LOCALES
DUPLICATE_I18N_LOCALES
MISSING_I18N_LOCALES
INVALID_LOCALE
DUPLICATE_LOCALE
UNKNOWN_DEFAULT_LOCALE
INVALID_LABEL_DECLARATION
INVALID_LABEL_TRANSLATION
UNCLOSED_LABEL
MISSING_I18N
DUPLICATE_LABEL_TARGET
INVALID_LABEL_TARGET
UNKNOWN_LABEL_TARGET
MISSING_LABEL_TRANSLATION
UNKNOWN_LABEL_LOCALE
DUPLICATE_LABEL_LOCALE
MISSING_DEFAULT_LABEL_TRANSLATION
```
