Introduces a reusable core detail-drawer primitive that slides in from the
right and loads any view via a `*-fragment(none).phtml` endpoint. Bundles the
address book list overhaul that is its first consumer.
Core additions:
- `app-detail-drawer.js` — generic drawer with stepper, focus trap, body
scroll-lock, URL-hash deep-linking, session-expiry detection
- `app-fragment-init.js` — auto-wires tabs/lookups/confirm/file-upload/
fslightbox inside injected HTML; consumers do not re-initialize components
- `app-focus-trap.js` — shared focus-trap + refcounted scroll-lock, used by
both filter-drawer and detail-drawer
- `getHtml()` in `app-http.js` + `SessionExpiredError`; drawer reloads the
page on auth redirect instead of rendering the login form in the panel
- `DetailDrawerFragmentContractTest` enforces that every `initDetailDrawer`
consumer ships matching `*-fragment($id).php` + `*-fragment(none).phtml`
Address book list:
- Grid collapses from 9 columns to 4 (identity / context / phone / actions)
with a two-line identity cell (avatar + name + email)
- Tenant register tabs above the grid using the `app-list-tabs` partial;
tenant filter wired via hidden toolbar field so grid.js forwards it on
every data fetch
- Profile body extracted to a shared partial so the full-page view and the
new drawer fragment share the same markup
- New i18n keys for the drawer/list labels
Also refactors `app-filter-drawer` to reuse the shared focus-trap and
scroll-lock instead of maintaining its own copy, and documents the
detail-drawer convention in CLAUDE.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each module can now ship its own i18n/ directory with translation files
(default_de.json, default_en.json). At boot time, ModuleI18nLoader
preloads core translations then merges module translations on top via
Reflection into I18n::$strings — the t() helper stays unchanged.
- Add i18nPath property to ModuleManifest
- Add ModuleI18nLoader with Reflection-based preload
- Extract 59 module-exclusive keys from core i18n into module files
(notifications: 8, bookmarks: 41, addressbook: 10)
- Expand TranslationKeysTest to scan modules/ and validate against
merged core + module translations
- Add ModuleI18nContractTest for per-module de/en parity and completeness
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>