feat: add hunt page, combat placeholder, and Jagd navigation

Wires up Slice 0.2 end-to-end: HuntPageComponent renders the
hunting-unavailable/ready/loading/encounters-found states off
HuntingStore and WorldStore, Angreifen hands the HuntEncounter id to a
new inert CombatPlaceholderPageComponent via /combat/new, the Jagd nav
entry is enabled with router-driven active state (matching Karte's),
and the context panel now lists possible encounters for hunting-enabled
locations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-19 14:06:57 +02:00
parent 784bd3ce3a
commit 4e684dc45e
11 changed files with 664 additions and 24 deletions

View File

@@ -0,0 +1,127 @@
:host {
display: block;
min-block-size: 100%;
}
.hunt-page {
position: relative;
min-block-size: 100%;
}
.hunt-page__unavailable,
.hunt-page__ready,
.hunt-page__results {
padding: var(--ar-space-5);
border: 1px solid var(--ar-border);
background: var(--ar-panel);
box-shadow: var(--ar-shadow-raised);
}
.hunt-page__unavailable h2,
.hunt-page__ready h2 {
margin: 0 0 var(--ar-space-3);
font-family: Georgia, 'Times New Roman', serif;
font-size: 1.6rem;
font-weight: 400;
}
.hunt-page__unavailable p,
.hunt-page__ready p {
margin: 0 0 var(--ar-space-4);
color: var(--ar-text-muted);
line-height: 1.55;
}
.hunt-page__hint {
font-style: italic;
}
.hunt-page__results-heading {
margin: 0 0 var(--ar-space-4);
color: var(--ar-gold);
font-family: Georgia, 'Times New Roman', serif;
font-size: 1.3rem;
}
.hunt-page__encounters {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: var(--ar-space-4);
margin-block-end: var(--ar-space-5);
}
.hunt-page__actions {
display: flex;
flex-wrap: wrap;
gap: var(--ar-space-3);
}
.hunt-page__unavailable button,
.hunt-page__ready button,
.hunt-page__actions button {
padding: var(--ar-space-2) var(--ar-space-4);
border: 1px solid var(--ar-border-highlight);
border-radius: var(--ar-radius-sm);
color: var(--ar-text);
background: linear-gradient(180deg, #263b4b, #17232d);
cursor: pointer;
font-family: Georgia, 'Times New Roman', serif;
font-size: 1rem;
}
.hunt-page__unavailable button:hover,
.hunt-page__ready button:not(:disabled):hover,
.hunt-page__actions button:not(:disabled):hover {
border-color: #d6b26b;
background: linear-gradient(180deg, #315067, #1a2c3a);
}
.hunt-page__ready button:disabled,
.hunt-page__actions button:disabled {
cursor: not-allowed;
opacity: 0.52;
}
.hunt-page__loading,
.hunt-page__error,
.hunt-page__empty {
margin: var(--ar-space-4) 0 0;
border: 1px solid var(--ar-border);
background: var(--ar-panel);
box-shadow: var(--ar-shadow-raised);
}
.hunt-page__loading,
.hunt-page__empty {
padding: var(--ar-space-4);
color: var(--ar-text-muted);
}
.hunt-page__error {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--ar-space-4);
padding: var(--ar-space-3) var(--ar-space-4);
border-color: var(--ar-danger);
}
.hunt-page__error p {
margin: 0;
}
.hunt-page__error button {
flex: 0 0 auto;
padding: var(--ar-space-2) var(--ar-space-3);
border: 1px solid var(--ar-border-highlight);
border-radius: var(--ar-radius-sm);
color: var(--ar-text);
background: #1a2023;
cursor: pointer;
}
@media (width < 720px) {
.hunt-page__encounters {
grid-template-columns: 1fr;
}
}