feat(insights): rename "Muster" + lift section tabs above the hero

Two related polishing changes for the Insights surface:

a) Correlation row title rename. "Muster" / "Patterns" reads as a
   loose grouping; the row actually shows pre-defined statistical
   relationships between two metrics. Rename to "Zusammenhänge" /
   "Relationships" so the title carries the same conceptual weight as
   the surrounding "Trends" / "Daily Briefing" headers without
   borrowing the "Trends" word from the row above it. Picked
   "Zusammenhänge" over "Trends" because the Trends row already uses
   that word and a correlation is conceptually a relationship between
   two series rather than a single-series trend.

b) Section tabs lift above the hero strip. `<InsightsSectionNav>` was
   mounted below the advisor card so the user had to scroll past the
   hero before discovering the metric-tab nav. Lift it to the top of
   the page so the tabs are the first thing visible — the hero +
   daily briefing render directly below, and clicking a tab still
   scrolls to the matching section. Sticky scroll-anchored behaviour
   preserved (incremental over a full SPA-tab rewrite) so today's
   reactive surface keeps working.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-10 20:52:07 +02:00
1 parent 36b9db34c5
commit 4d3b12936a
5 files changed
+19 -12

No files matched your search

+11 -4
View File
@@ -949,6 +949,15 @@ export default function InsightsPage() {
return (
<div className="space-y-8">
{/* v1.4.22 A5 — section tabs lift above the hero strip so the
user sees the metric-tab nav before scrolling. The nav itself
remains a sticky scroll-anchored strip — clicking a tab
scrolls to the matching section, scrolling highlights the
active tab. Hero + Daily Briefing always render below the
nav; the metric tabs control which sub-sections are visible
in the user's viewport. */}
<InsightsSectionNav />
<HeroStrip
briefing={briefingPayload}
updatedAt={heroStripUpdatedAt}
@@ -983,8 +992,8 @@ export default function InsightsPage() {
{/* v1.4.20 phase B3 — Correlation discovery row. Three pre-defined
hypotheses (BP × compliance, mood × pulse, weight × weekday) gated
on n >= 14 + p < 0.05; cards below the bar render a per-card
empty-state. The row-level disclaimer ("Patterns are observational,
not causal …") sits below the grid once. */}
empty-state. The row-level disclaimer ("Relationships are
observational, not causal …") sits below the grid once. */}
{analytics?.correlations && (
<CorrelationRow results={analytics.correlations} />
)}
@@ -1008,8 +1017,6 @@ export default function InsightsPage() {
legacyPayload={advisor.payload?.legacyPayload ?? false}
/>
<InsightsSectionNav />
<section id="section-general" className="scroll-mt-28 space-y-2">
<div className="flex items-center gap-2">
<h2 className="text-lg font-semibold">
@@ -88,7 +88,7 @@ describe("<CorrelationCard>", () => {
it("renders the empty-state when status=insufficient", () => {
const html = render(<CorrelationCard result={insufficient} />);
expect(html).toContain("Need more data to see this pattern");
expect(html).toContain("Need more data to see this relationship");
expect(html).not.toContain("Try a 7-day experiment");
});
@@ -100,7 +100,7 @@ describe("<CorrelationRow>", () => {
);
const matches = html.match(/data-slot="correlation-row-disclaimer"/g) ?? [];
expect(matches.length).toBe(1);
expect(html).toContain("Patterns are observational, not causal");
expect(html).toContain("Relationships are observational, not causal");
});
it("applies the 2-up grid on >= md when 2+ ok cards render", () => {