From 3ee107694c59d55da38da2916b8e89451f9b6204 Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Thu, 20 Aug 2026 16:33:42 +0200 Subject: [PATCH] address code review: POI order matches plan, self-documenting height reserve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorders the Verbrannte Straße POIs to plan §8's authored sequence (hunt, investigate, search, then the scout) — purely a keyboard tab-order fix, since hotspots are placed by percentage, not list order. Rewrites the location page's viewport-height reserve as a calc() over the same rem values the top bar and footer already declare as their own min-block-size, with file:line pointers to both, instead of an opaque 191px constant. Doesn't remove the underlying coupling (still no ResizeObserver / shared token), but a future edit to either component's minimum height now has a documented, unit-matching term to update instead of an unexplained magic number. Co-Authored-By: Claude Opus 5 --- .../database/seeds/local-location.content.ts | 26 +++++++++---------- .../seeds/vertical-slice.seed.spec.ts | 4 +-- .../world/current-location.fixture.ts | 20 +++++++------- .../location-page.component.scss | 15 ++++++++--- .../location-page.component.spec.ts | 2 +- .../location-sidebar.component.spec.ts | 2 +- 6 files changed, 39 insertions(+), 30 deletions(-) diff --git a/apps/api/src/database/seeds/local-location.content.ts b/apps/api/src/database/seeds/local-location.content.ts index 44881b4..1a18927 100644 --- a/apps/api/src/database/seeds/local-location.content.ts +++ b/apps/api/src/database/seeds/local-location.content.ts @@ -45,19 +45,6 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = { yPercent: 33, enabled: true, }, - { - key: 'wounded-scout', - title: 'Verwundeter Kundschafter', - actionLabel: 'Sprechen', - type: 'NPC', - iconKey: 'speak', - xPercent: 17, - yPercent: 62, - enabled: true, - resultTitle: 'Verwundeter Kundschafter', - resultText: - '„Die Straße ist nicht mehr sicher. Die Plünderer kommen aus Richtung des alten Wachtpostens. Wenn du weitergehst, halte die Augen offen."', - }, { key: 'inspect-tracks', title: 'Verdächtige Spuren', @@ -84,6 +71,19 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = { resultText: 'Der Wagen wurde gründlich geplündert. Zwischen verbrannten Brettern findest du nur leere Kisten und Spuren eines hastigen Aufbruchs.', }, + { + key: 'wounded-scout', + title: 'Verwundeter Kundschafter', + actionLabel: 'Sprechen', + type: 'NPC', + iconKey: 'speak', + xPercent: 17, + yPercent: 62, + enabled: true, + resultTitle: 'Verwundeter Kundschafter', + resultText: + '„Die Straße ist nicht mehr sicher. Die Plünderer kommen aus Richtung des alten Wachtpostens. Wenn du weitergehst, halte die Augen offen."', + }, ], localPrimaryActions: [ { diff --git a/apps/api/src/database/seeds/vertical-slice.seed.spec.ts b/apps/api/src/database/seeds/vertical-slice.seed.spec.ts index 6cba730..4628510 100644 --- a/apps/api/src/database/seeds/vertical-slice.seed.spec.ts +++ b/apps/api/src/database/seeds/vertical-slice.seed.spec.ts @@ -262,15 +262,15 @@ describe('seedVisibleVerticalSlice', () => { }[]; expect(pointsOfInterest.map((poi) => poi.key)).toEqual([ 'hunt-area', - 'wounded-scout', 'inspect-tracks', 'search-abandoned-wagon', + 'wounded-scout', ]); expect(pointsOfInterest.map((poi) => poi.type)).toEqual([ 'HUNT', - 'NPC', 'INVESTIGATE', 'SEARCH', + 'NPC', ]); const primaryActions = burnedRoad.localPrimaryActions as { diff --git a/apps/web/src/app/features/world/current-location.fixture.ts b/apps/web/src/app/features/world/current-location.fixture.ts index aab7246..c05d603 100644 --- a/apps/web/src/app/features/world/current-location.fixture.ts +++ b/apps/web/src/app/features/world/current-location.fixture.ts @@ -23,16 +23,6 @@ export const BURNED_ROAD_POIS: LocationPointOfInterest[] = [ yPercent: 44, enabled: true, }, - { - key: 'wounded-scout', - title: 'Verwundeter Kundschafter', - actionLabel: 'Sprechen', - type: 'NPC', - iconKey: 'speak', - xPercent: 20, - yPercent: 60, - enabled: true, - }, { key: 'inspect-tracks', title: 'Verdächtige Spuren', @@ -53,6 +43,16 @@ export const BURNED_ROAD_POIS: LocationPointOfInterest[] = [ yPercent: 68, enabled: true, }, + { + key: 'wounded-scout', + title: 'Verwundeter Kundschafter', + actionLabel: 'Sprechen', + type: 'NPC', + iconKey: 'speak', + xPercent: 20, + yPercent: 60, + enabled: true, + }, ]; export const BURNED_ROAD_ACTIONS: LocationPrimaryAction[] = [ diff --git a/apps/web/src/app/features/world/location-page/location-page.component.scss b/apps/web/src/app/features/world/location-page/location-page.component.scss index 7d690a0..aa58052 100644 --- a/apps/web/src/app/features/world/location-page/location-page.component.scss +++ b/apps/web/src/app/features/world/location-page/location-page.component.scss @@ -5,9 +5,18 @@ // size instead of clamping, letting the artwork push the action bar off // screen. Giving this page its own definite, viewport-bounded height fixes // that without touching the shell, which other screens still size freely. -// Reserve = top bar (~90px) + footer (~53px) + this page's own padding -// (2 × var(--ar-space-5) = 48px), both stable across breakpoints. -$app-shell-chrome-reserve: 191px; +// +// Reserve terms are the shell chrome's own `min-block-size` values plus this +// page's own padding, so the number tracks its sources rather than sitting as +// an opaque constant — if the top bar or footer ever needs more room than its +// current floor (a longer name, a wrapped nav row), bump the matching term +// here too: +// apps/web/src/app/layout/top-bar/top-bar.component.scss (5.6rem) +// + apps/web/src/app/layout/game-footer/game-footer.component.scss (3.3rem) +// + this page's own padding, 2 × var(--ar-space-5) (3rem) +// A small safety margin (0.5rem) absorbs sub-pixel/line-height drift so a +// few px of unplanned growth doesn't immediately reopen the clipping bug. +$app-shell-chrome-reserve: calc(5.6rem + 3.3rem + 3rem + 0.5rem); :host { display: block; diff --git a/apps/web/src/app/features/world/location-page/location-page.component.spec.ts b/apps/web/src/app/features/world/location-page/location-page.component.spec.ts index 0633b21..555f3c4 100644 --- a/apps/web/src/app/features/world/location-page/location-page.component.spec.ts +++ b/apps/web/src/app/features/world/location-page/location-page.component.spec.ts @@ -85,9 +85,9 @@ describe('LocationPageComponent', () => { expect(hotspots).toHaveLength(4); expect([...hotspots].map((poi) => poi.querySelector('button')?.dataset['poi'])).toEqual([ 'hunt-area', - 'wounded-scout', 'inspect-tracks', 'search-abandoned-wagon', + 'wounded-scout', ]); }); diff --git a/apps/web/src/app/features/world/location-sidebar/location-sidebar.component.spec.ts b/apps/web/src/app/features/world/location-sidebar/location-sidebar.component.spec.ts index 719814e..0c7c39d 100644 --- a/apps/web/src/app/features/world/location-sidebar/location-sidebar.component.spec.ts +++ b/apps/web/src/app/features/world/location-sidebar/location-sidebar.component.spec.ts @@ -56,9 +56,9 @@ describe('LocationSidebarComponent', () => { expect([...interactions].map((item) => item.textContent?.trim())).toEqual([ 'Jagd beginnen', - 'Sprechen', 'Untersuchen', 'Durchsuchen', + 'Sprechen', ]); });