fix(web): use the German "Ansehen" for Renown in the Topbar

The Topbar rendered the English word "Renown", replacing the German
"Stufe" it showed before. That contradicted the slice's own global
constraint that all user-facing copy is German, and it was the single
English string in a component visible on every screen -- next to
"Silber", "Lebenspunkte" and "Charakterdaten werden geladen".

This was a spec defect, not an implementation one: the design doc and
the task brief both prescribed "Renown" literally. The document's
working language leaked into a copy-locked line.

"Ruf" is not available as the German term -- this project already uses
it for the separate per-faction Reputation system, and the two are
deliberately kept distinct. "Ansehen" (standing/prestige) is unclaimed
and matches the spec's own definition of Renown as the character's
overall significance in the world.

Records the decision as R17 in the design doc so later Renown UI does
not reintroduce the English term, and renames the now-inaccurate
top-bar__level class to top-bar__renown (nothing else referenced it).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-21 14:59:01 +02:00
parent cea1d2ecf5
commit df4c0c5527
4 changed files with 7 additions and 5 deletions

View File

@@ -4,7 +4,7 @@
@if (character(); as character) { @if (character(); as character) {
<div class="top-bar__identity"> <div class="top-bar__identity">
<span class="top-bar__name">{{ character.name }}</span> <span class="top-bar__name">{{ character.name }}</span>
<span class="top-bar__level">Renown {{ character.renown }}</span> <span class="top-bar__renown">Ansehen {{ character.renown }}</span>
</div> </div>
<div class="top-bar__health" aria-label="Lebenspunkte"> <div class="top-bar__health" aria-label="Lebenspunkte">
<span>{{ character.currentHp }} / {{ character.maxHp }}</span> <span>{{ character.currentHp }} / {{ character.maxHp }}</span>

View File

@@ -53,7 +53,7 @@
font-size: 1.1rem; font-size: 1.1rem;
} }
.top-bar__level, .top-bar__renown,
.top-bar__loading { .top-bar__loading {
color: var(--ar-text-muted); color: var(--ar-text-muted);
font-size: var(--ar-font-sm); font-size: var(--ar-font-sm);

View File

@@ -37,10 +37,10 @@ describe('TopBarComponent', () => {
expect(element.querySelector('[data-top-bar-silver]')?.textContent).toContain('120'); expect(element.querySelector('[data-top-bar-silver]')?.textContent).toContain('120');
}); });
it('shows Renown instead of Level, and displays no XP value', async () => { it('shows Ansehen instead of Level, and displays no XP value', async () => {
const element = await render(characterFixture({ renown: 3 })); const element = await render(characterFixture({ renown: 3 }));
expect(element.textContent).toContain('Renown 3'); expect(element.textContent).toContain('Ansehen 3');
expect(element.querySelector('[data-top-bar-experience]')).toBeNull(); expect(element.querySelector('[data-top-bar-experience]')).toBeNull();
}); });

View File

@@ -259,7 +259,9 @@ POST /api/turn-ins → { turnInKey: string; quantity: number } → TurnInR
## 11. Frontend changes ## 11. Frontend changes
- **`game-api.models.ts`**: `CharacterResponse.level`/`.experience``.renown: number`. New `ReputationEntry`/`TurnInResult` interfaces mirroring the API DTOs. `InventoryItem.item.type` (if surfaced) reflects the new `ItemType` values; `requiredLevel` removed if present anywhere in the web model. - **`game-api.models.ts`**: `CharacterResponse.level`/`.experience``.renown: number`. New `ReputationEntry`/`TurnInResult` interfaces mirroring the API DTOs. `InventoryItem.item.type` (if surfaced) reflects the new `ItemType` values; `requiredLevel` removed if present anywhere in the web model.
- **Topbar** (`top-bar.component.html`): `Stufe {{ character.level }}``Renown {{ character.renown }}`; `data-top-bar-experience` XP block deleted entirely. - **Topbar** (`top-bar.component.html`): `Stufe {{ character.level }}``Ansehen {{ character.renown }}`; `data-top-bar-experience` XP block deleted entirely. The wrapping span's class is renamed `top-bar__level``top-bar__renown` to match.
**R17 — the German display term for Renown is "Ansehen", not "Renown" and not "Ruf".** Earlier drafts of this line said `Renown`, which contradicted the global constraint that all user-facing copy is German — the working language of this document leaking into copy-locked text. `Ruf` is unavailable: it is the German term this project already uses for the separate per-faction *Reputation* system (see the reputation display's `factionName + ' Ruf'`), and the two systems are deliberately kept distinct. `Ansehen` (standing/prestige) is unclaimed and matches §2.2's definition of Renown as the character's overall significance in the world.
- **Combat victory screen** (`combat-page.component.html`/`.spec.ts`): `data-reward-experience` block and its three referencing tests deleted (R16); `rewards.silver` block stays. - **Combat victory screen** (`combat-page.component.html`/`.spec.ts`): `data-reward-experience` block and its three referencing tests deleted (R16); `rewards.silver` block stays.
- **New `ReputationDisplayComponent`** (`apps/web/src/app/shared/reputation-display/`): standalone component, input `entry: ReputationEntry`, renders faction name, rank label, `current / nextThreshold` (or just current if `nextThreshold` is null, at Esteemed), a progress bar. Built and unit-tested; not wired into any page (R15). - **New `ReputationDisplayComponent`** (`apps/web/src/app/shared/reputation-display/`): standalone component, input `entry: ReputationEntry`, renders faction name, rank label, `current / nextThreshold` (or just current if `nextThreshold` is null, at Esteemed), a progress bar. Built and unit-tested; not wired into any page (R15).