feat: add complete German localization

Add Deutsch across all card surfaces and backend flows, backed by the language registry introduced in #62. German loads as a fingerprint-checked page-shared locale chunk so EN/RU remain synchronous and the initial View budget stays intact. Root render gates prevent mixed-language flashes, retry once, and fail open to English. Extend parity, runtime, bundle, browser and visual coverage, plus contributor and user documentation.

Issue: #348
User-Visible: yes
This commit is contained in:
Matysh
2026-08-28 11:58:46 +03:00
parent 7a0702adea
commit 12cd8a1af3
50 changed files with 2265 additions and 524 deletions
+7
View File
@@ -135,6 +135,13 @@ the same profiler available between stable promotions.
affordance exists only when both its localized body and complete accessible
label are non-empty; the card factory and `hp-help` enforce this independently,
so incomplete content cannot leave a dead focus target or a layout gap.
English and Russian dictionaries remain in the synchronous graph. German is
a fingerprint-checked lazy locale shared page-wide: every root card/editor
uses the same render gate, keeps a previously committed frame stable during
a language switch, and shows a language-neutral busy frame on a German cold
start. Two failed content-hashed attempts settle on English rather than
leaving an inert surface. The bundle manifest classifies this graph as
`lazyLocaleFiles`, separate from editor and onboarding graphs.
8. **One four-phase environment resolver.** `resolveDayCycle()` in `src/sun.ts`
atomically chooses a strict real `sun.sun` sample or browser-local clock
fallback and returns only phase/source/light tokens. `src/day-cycle-render.ts`
+5
View File
@@ -2,6 +2,11 @@
## Unreleased
- House Plan now has a complete German interface. `Deutsch` can be selected
explicitly and is chosen automatically for German Home Assistant profiles;
the locale loads on demand without making the ordinary View bundle larger
([#348](https://github.com/Matysh/houseplan-card/issues/348)).
- View now starts without downloading the three editors; their shared runtime
is loaded on first use and protected by one retry and a build-version check.
Release and test tooling now verify the complete multi-file frontend asset
+5
View File
@@ -8,6 +8,11 @@
## Не выпущено
- В House Plan появилась полная немецкая локализация. `Deutsch` можно выбрать
вручную, а для немецкого профиля Home Assistant она включается автоматически;
словарь загружается по требованию и не утяжеляет обычный режим просмотра
([#348](https://github.com/Matysh/houseplan-card/issues/348)).
- Режим просмотра теперь запускается без загрузки трёх редакторов: их общий
runtime подгружается при первом обращении и защищён повторной попыткой и
проверкой версии сборки. Релизные и тестовые инструменты проверяют всё дерево
+12 -1
View File
@@ -781,7 +781,18 @@ separately promised workflows:
- [ ] Tablet in kiosk/panel mode — View/kiosk, landscape, touch gestures
- [ ] Phone portrait, narrow ≤400 px — View and View dialogs/actions
- [ ] Dark theme and light theme (badges, dialogs, plan contrast)
- [ ] RU profile locale and EN profile locale (+ `language:` card option forcing each)
- [ ] RU, EN and DE profile locales (+ `language:` card option forcing each);
`de-DE`, `de-AT` and `de-CH` resolve to German, while an unknown locale
falls back to English [unit: i18n, i18n-runtime]
- [ ] German cold start requests exactly one locale chunk, shows only a neutral
busy frame before commit and never flashes English; a second card reuses
the page cache. EN/RU request no locale chunk [auto: German locale smoke]
- [ ] German locale download failure retries the content-hashed asset once and
then unblocks the card in English with one warning [unit: i18n-runtime;
auto: German locale smoke fault injection]
- [ ] German View and a representative settings/device dialog fit at desktop
and 390 px without horizontal overflow or clipped actions [golden: German
desktop/mobile scenarios]
## Installation / upgrade / removal
+7 -1
View File
@@ -131,7 +131,7 @@ title: House plan
| `title` | empty | Card title |
| `default_floor` | first/last opened | Initial/fallback space for an unpinned card |
| `floor` | not pinned | Keep this card on one stable space ID or zero-based YAML index |
| `language` | HA language | `auto`, `ru` or `en` |
| `language` | HA language | `auto`, `en`, `ru` or `de` |
| `icon_size` | `2.5` | Base marker size, 1–6% of plan width |
| `show_temperature` | `true` | Compact temperature and humidity values |
| `live_states` | `true` | Work/open/unavailable presentation and activity; alarms remain visible |
@@ -141,6 +141,12 @@ title: House plan
The legacy card-level `tap_action` is ignored. Each marker owns its action.
`auto` recognizes the primary Home Assistant locale: `de`, `de-DE`, `de-AT`
and `de-CH` use German. German is downloaded once on first use and shared by
all House Plan cards on the page. Until it is ready, a neutral busy surface is
shown instead of briefly flashing English; if both bounded download attempts
fail, the card becomes usable in English.
<!-- docs-section: first-run -->
## 4. Quick start
+8 -1
View File
@@ -135,7 +135,7 @@ title: План дома
| `title` | пусто | Заголовок карточки |
| `default_floor` | первое/последнее открытое | Стартовое/резервное пространство незакреплённой карточки |
| `floor` | не закреплено | Всегда показывать один stable ID пространства или числовой индекс YAML с нуля |
| `language` | язык HA | `auto`, `ru` или `en` |
| `language` | язык HA | `auto`, `en`, `ru` или `de` |
| `icon_size` | `2.5` | Базовый размер маркеров, 1–6% ширины плана |
| `show_temperature` | `true` | Показывает компактные значения температуры **и влажности** у подходящих устройств |
| `live_states` | `true` | Включает рабочие/открытые/недоступные состояния, смену иконок и активность; аварии остаются видимыми всегда |
@@ -145,6 +145,13 @@ title: План дома
Карточечный `tap_action` из старых конфигураций игнорируется. Действие задаётся отдельно для каждого устройства.
`auto` учитывает основной язык профиля Home Assistant: `de`, `de-DE`,
`de-AT` и `de-CH` включают немецкий интерфейс. Немецкий словарь один раз
загружается при первом использовании и разделяется всеми карточками House Plan
на странице. До готовности показывается нейтральный индикатор без краткой
вспышки английского текста; если обе ограниченные попытки загрузки не удались,
карточка остаётся работоспособной на английском.
<!-- docs-section: first-run -->
## 4. Быстрый старт
+11 -11
View File
@@ -3,7 +3,7 @@
"fixture": "synthetic-only",
"chromium": "151.0.7922.34",
"oxipng": "oxipng 10.2.0",
"sourceFingerprint": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceFingerprint": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"captureScriptSha256": "fe76c8e2e27501e9a377d7aa15dd6cba6a018d55c07deb602dbee097f0a0a5ba",
"command": "npm run build && node demo/docs/capture.mjs",
"scenarios": {
@@ -15,7 +15,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "f8c9541c9d7fde462d0efba63dff70944dc03df76ce988eecaf2b269e2863a96"
},
"view-touch": {
@@ -26,7 +26,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "69cc6aa03948282feab1c623da418487cb9b8ebc3e57175b031cc40e5f9a88af"
},
"space-create": {
@@ -37,7 +37,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "f6d190f0b2ac9125cea68aea2ebbcdf9a7081ae2a3565ff253fb1ed0c4a56483"
},
"room-contour-close": {
@@ -48,7 +48,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "ca8bb143d0d6679ff09f8e9c1f5ad68b2ca7cfd96a4740a4a650c251f55dfba5"
},
"plan-context-tray": {
@@ -59,7 +59,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "06b67c5108f9ee29a226cc2920484ccffe0c79840aec09721072b25b91ef8f03"
},
"device-editor": {
@@ -70,7 +70,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "0b84d425c14389fb3f04779a1f553ebab1b84f801b23b119b3810770500d171f"
},
"device-display-preview": {
@@ -81,7 +81,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "143bda35ac596ce6d72ad7399e5d26238cccae577f2d8cff398cd1efcaf1661f"
},
"background-editor": {
@@ -92,7 +92,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "7e308a2b105fa6a9f788449ca30b8183375a32f0d0f8726f4a131e4f35527f57"
},
"room-card": {
@@ -103,7 +103,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "f1bc10b478f7afc68e70cb4c37148f680b0bbd41d50a7d63a21067fc952ff134"
},
"device-info": {
@@ -114,7 +114,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9dd41c04c57da03c78b4f89b83081b4e8f6024fa958848c0b55380727834f55",
"sourceSha256": "14edbd86bf80d90c9d430a3ddf002c023553026d8cca15e476515aa7a001cba4",
"imageSha256": "2634cd7ead5720ce46ea4d6fa8f31006b740c520a73ddc97afe9a6d9d3b49778"
}
}
+1 -2
View File
@@ -2,7 +2,7 @@
- **Issue:** https://github.com/Matysh/houseplan-card/issues/348
- **Зависимость:** #62 — единый реестр языков и автоматические i18n-gates
- **Статус документа:** готово к ревью ТЗ
- **Статус документа:** реализовано, передано на код-ревью
- **Приоритет / тип:** P1 / feature
- **Трек:** полный: задача меняет публичный языковой контракт, несколько
frontend/backend-поверхностей, первый render и performance budget
@@ -382,4 +382,3 @@ config не нужны.
5. Добавить semantic/layout/network smoke и German golden scenarios.
6. Обновить docs/changelogs, собрать и синхронизировать bundle.
7. Прогнать gates, передать точный SHA на независимое code review.