diff --git a/gerbil-manager-web/e2e/stammbaum.spec.ts b/gerbil-manager-web/e2e/stammbaum.spec.ts
index cfdf83a..e9d6ecf 100644
--- a/gerbil-manager-web/e2e/stammbaum.spec.ts
+++ b/gerbil-manager-web/e2e/stammbaum.spec.ts
@@ -145,3 +145,12 @@ test('Knoten-Karte zeigt volles Geburtsdatum (STAMMBAUM-FULLDATE)', async ({ pag
await expect(page.locator('.pedigree-card').first()).toBeVisible()
await expect(page.locator('.pedigree-card__year').first()).toContainText('12.03.2025')
})
+
+test('Gencode-Chip zeigt Genotyp statt Farbname (STAMMBAUM-GENCODE)', async ({ page }) => {
+ skipUnlessMock()
+ // Fridolin ist Vater von Krümel — genotype 'aa CC DD EE GG PP spsp rere'
+ await page.goto('/rennmaeuse/kruemel/stammbaum')
+ await expect(page.locator('.pedigree-card').first()).toBeVisible()
+ const fridolinCard = page.locator('.pedigree-card').filter({ hasText: 'Fridolin' })
+ await expect(fridolinCard.locator('.pedigree-chip')).toContainText('aa CC')
+})
diff --git a/gerbil-manager-web/src/components/AppShell.tsx b/gerbil-manager-web/src/components/AppShell.tsx
index 043260f..06b2c93 100644
--- a/gerbil-manager-web/src/components/AppShell.tsx
+++ b/gerbil-manager-web/src/components/AppShell.tsx
@@ -1,19 +1,21 @@
import { useState } from 'react'
+import type { ReactNode } from 'react'
import { NavLink, Outlet } from 'react-router-dom'
import { de } from '../strings/de'
+import GerbilIcon from './GerbilIcon'
import './appShell.css'
interface NavItem {
to: string
label: string
- icon: string
+ icon: ReactNode
end?: boolean
}
// Primary items are always visible in the phone bottom bar; secondary items
// move into the "Mehr" sheet on phones and appear inline in the desktop sidebar.
const PRIMARY: NavItem[] = [
- { to: '/rennmaeuse', label: de.nav.gerbils, icon: '🐭' },
+ { to: '/rennmaeuse', label: de.nav.gerbils, icon: },
{ to: '/wuerfe', label: de.nav.litters, icon: '🍼' },
{ to: '/genetik', label: de.nav.genetics, icon: '🧬' },
]
@@ -46,7 +48,7 @@ export default function AppShell() {
return (
diff --git a/gerbil-manager-web/src/components/GerbilIcon.tsx b/gerbil-manager-web/src/components/GerbilIcon.tsx
new file mode 100644
index 0000000..7209852
--- /dev/null
+++ b/gerbil-manager-web/src/components/GerbilIcon.tsx
@@ -0,0 +1,35 @@
+import type { CSSProperties } from 'react'
+
+interface Props {
+ size?: string | number
+ style?: CSSProperties
+ className?: string
+}
+
+/** Reusable gerbil silhouette icon — upright sitting pose, long tail with tuft. fill=currentColor. */
+export default function GerbilIcon({ size = '1em', style, className }: Props) {
+ return (
+
+ )
+}
diff --git a/gerbil-manager-web/src/pages/StammbaumPage.tsx b/gerbil-manager-web/src/pages/StammbaumPage.tsx
index a09240a..a450599 100644
--- a/gerbil-manager-web/src/pages/StammbaumPage.tsx
+++ b/gerbil-manager-web/src/pages/StammbaumPage.tsx
@@ -28,6 +28,7 @@ import { getInbreedingCoefficient } from '../api/pedigree'
import type { Gender, Gerbil, Litter } from '../api/types'
import { useApi } from '../hooks/useApi'
import { formatDate, genderLabel } from '../format/labels'
+import GerbilIcon from '../components/GerbilIcon'
import { UNKNOWN_FARBSCHLAG, fromDisplayString, genotypeToFarbschlag, toDisplayString } from '../genetics'
import {
DEFAULT_GENERATIONS,
@@ -389,7 +390,7 @@ function PedigreeCard({
>
{/* Foto-Platzhalter — echte Fotos kommen mit FEAT-6. */}
- 🐭
+
@@ -406,8 +407,9 @@ function PedigreeCard({
- {farbschlag}
+ {g.genotype || farbschlag}
)}
{dob && * {dob}}
diff --git a/gerbil-manager-web/src/pages/stammbaum.css b/gerbil-manager-web/src/pages/stammbaum.css
index 4814943..13f5836 100644
--- a/gerbil-manager-web/src/pages/stammbaum.css
+++ b/gerbil-manager-web/src/pages/stammbaum.css
@@ -285,14 +285,15 @@
.pedigree-chip {
align-self: flex-start;
max-width: 100%;
- font-size: 0.68rem;
+ font-size: 0.62rem;
padding: 0.1rem 0.45rem;
border-radius: 1rem;
background: var(--color-accent-soft);
color: var(--color-accent);
- white-space: nowrap;
+ white-space: normal;
+ word-break: break-word;
overflow: hidden;
- text-overflow: ellipsis;
+ line-height: 1.3;
}
.pedigree-card__year {