fix(cards): retire banned p-5 shells and accent header icons

Bring the structural card-anatomy offenders onto the spacing scale. The
cycle wellness-tile family (ring tile, phase-education, insight summary,
cycle view) and the insights wellness-scores tile drop banned p-5/px-5
py-5 for p-4 md:p-6 and keep their premium hue surface; their header and
info glyphs move off text-primary to foreground, spinners to muted. The
onboarding hand-rolled shells (anamnesis card, baseline form,
getting-started checklist, tour tooltip) drop p-5/space-y-5/rounded-2xl
for p-4 md:p-6/space-y-4/rounded-xl. settings/anamnesis-section moves its
three raw Card+CardTitle shells onto SettingsCard + SettingsCardHeader.
This commit is contained in:
Marc-André Bombeck committed 2026-07-09 12:05:34 +02:00
1 parent de16da43fe
commit 9f21d9f20d
10 files changed
+43 -56

No files matched your search

@@ -114,7 +114,7 @@ export function CycleInsightSummaryCard() {
data-slot="cycle-insight-summary"
data-phase={phase ?? "none"}
style={{ "--tile-hue": hue } as React.CSSProperties}
className="wellness-tile wellness-tile-rise rounded-xl px-5 py-5"
className="wellness-tile wellness-tile-rise rounded-xl p-4 md:p-6"
>
{/* Zone 1 — the current phase / cycle-day read. */}
<div className="min-w-0">
+1 -1
View File
@@ -109,7 +109,7 @@ export function CycleRingTile({ className }: { className?: string }) {
// per-phase hue arc inside the ring is the only saturated thing.
style={{ "--tile-hue": hue } as React.CSSProperties}
className={cn(
"wellness-tile focus-visible:ring-ring flex flex-col gap-4 rounded-xl p-5 focus-visible:ring-2 focus-visible:outline-none",
"wellness-tile focus-visible:ring-ring flex flex-col gap-4 rounded-xl p-4 focus-visible:ring-2 focus-visible:outline-none md:p-6",
play && "wellness-tile-rise",
className,
)}
+4 -4
View File
@@ -219,13 +219,13 @@ export function CycleView() {
: undefined
}
className={cn(
"wellness-tile flex flex-col items-center gap-3 rounded-xl px-5 py-5",
"wellness-tile flex flex-col items-center gap-3 rounded-xl p-4 md:p-6",
play && "wellness-tile-rise",
)}
>
{loading ? (
<div className="flex h-[220px] items-center justify-center">
<Loader2 className="text-primary h-8 w-8 animate-spin motion-reduce:animate-none" />
<Loader2 className="text-muted-foreground h-8 w-8 animate-spin motion-reduce:animate-none" />
</div>
) : calendarError ? (
<div className="flex h-[220px] flex-col items-center justify-center gap-3 text-center">
@@ -347,7 +347,7 @@ export function CycleView() {
className="text-muted-foreground bg-muted/40 mb-3 flex items-start gap-2 rounded-lg p-3 text-sm"
>
<Sparkles
className="text-primary mt-0.5 h-4 w-4 shrink-0"
className="text-foreground mt-0.5 h-4 w-4 shrink-0"
aria-hidden="true"
/>
<span>{t("cycle.calendar.learning")}</span>
@@ -429,7 +429,7 @@ export function CycleView() {
</Card>
) : profileQuery.isLoading ? (
<div className="flex h-32 items-center justify-center">
<Loader2 className="text-primary h-6 w-6 animate-spin motion-reduce:animate-none" />
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin motion-reduce:animate-none" />
</div>
) : profileQuery.data ? (
<CycleSettings
@@ -119,7 +119,7 @@ export function PhaseEducationCard({
aria-label={t("cycle.phaseEducation.title")}
style={{ "--tile-hue": hue } as React.CSSProperties}
className={cn(
"wellness-tile rounded-xl px-5 py-5",
"wellness-tile rounded-xl p-4 md:p-6",
animate && "wellness-tile-rise",
className,
)}
@@ -127,8 +127,7 @@ export function PhaseEducationCard({
{/* Zone 1 — eyebrow + phase name with a hue dot (never colour-only). */}
<div className="flex items-center gap-2">
<Sparkles
className="h-4 w-4 shrink-0"
style={{ color: hue }}
className="text-foreground h-4 w-4 shrink-0"
aria-hidden="true"
/>
<span className="text-muted-foreground text-xs font-medium tracking-wide uppercase">
@@ -133,7 +133,7 @@ function RingTile({
} as React.CSSProperties
}
className={cn(
"wellness-tile focus-visible:ring-ring flex flex-col gap-4 rounded-xl p-5 focus-visible:ring-2 focus-visible:outline-none",
"wellness-tile focus-visible:ring-ring flex flex-col gap-4 rounded-xl p-4 focus-visible:ring-2 focus-visible:outline-none md:p-6",
animate && "wellness-tile-rise",
)}
>
+2 -2
View File
@@ -81,7 +81,7 @@ export function AnamnesisCard({
onClick={() => setExpanded((v) => !v)}
aria-expanded={expanded}
aria-controls={panelId}
className="flex w-full items-center gap-3 rounded-xl p-5 text-left"
className="flex w-full items-center gap-3 rounded-xl p-4 text-left md:p-6"
>
<span
aria-hidden="true"
@@ -107,7 +107,7 @@ export function AnamnesisCard({
</button>
{expanded ? (
<div id={panelId} className="space-y-5 px-5 pb-5">
<div id={panelId} className="space-y-4 px-4 pb-4 md:px-6 md:pb-6">
<p className="text-muted-foreground text-xs leading-relaxed">
{t("onboarding.anamnesis.intro")}
</p>
+1 -1
View File
@@ -167,7 +167,7 @@ export function BaselineForm() {
</p>
</header>
<fieldset className="bg-card border-border space-y-5 rounded-xl border p-5">
<fieldset className="bg-card border-border space-y-4 rounded-xl border p-4 md:p-6">
<legend className="sr-only">{t("onboarding.baseline.title")}</legend>
<FieldGroup
@@ -311,7 +311,7 @@ export function GettingStartedChecklist() {
<section
data-testid="onboarding-card"
aria-labelledby="getting-started-title"
className="bg-card border-border space-y-4 rounded-2xl border p-5 sm:p-6"
className="bg-card border-border space-y-4 rounded-xl border p-4 md:p-6"
>
{/* v1.4.27 MB7 / CF-44 — `flex-wrap` on the header lets the
dismiss button drop to its own row when the German title +
+2 -2
View File
@@ -643,8 +643,8 @@ export function OnboardingTour({
// centred above the bottom edge on wide ones (`mx-auto` +
// `max-w`). Used on EVERY viewport when no anchored
// placement keeps the footer buttons inside the viewport.
"bg-card border-border pointer-events-auto absolute inset-x-2 bottom-2 mx-auto max-h-[70vh] max-w-[22rem] overflow-x-hidden overflow-y-auto rounded-xl border p-5 shadow-2xl"
: "bg-card border-border pointer-events-auto absolute max-w-[22rem] overflow-x-hidden overflow-y-auto rounded-xl border p-5 shadow-2xl"
"bg-card border-border pointer-events-auto absolute inset-x-2 bottom-2 mx-auto max-h-[70vh] max-w-[22rem] overflow-x-hidden overflow-y-auto rounded-xl border p-4 shadow-2xl md:p-6"
: "bg-card border-border pointer-events-auto absolute max-w-[22rem] overflow-x-hidden overflow-y-auto rounded-xl border p-4 shadow-2xl md:p-6"
}
style={
asSheet
+28 -40
View File
@@ -18,13 +18,10 @@
* record where it belongs.
*/
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { HeartPulse, ShieldAlert, Users } from "lucide-react";
import { SettingsCard } from "@/components/settings/settings-card";
import { SettingsCardHeader } from "@/components/settings/_card-header";
import { useTranslations } from "@/lib/i18n/context";
import { useModuleEnabled } from "@/hooks/use-module-enabled";
@@ -38,42 +35,33 @@ export function AnamnesisSection() {
return (
<div className="space-y-6">
{coachEnabled && (
<Card>
<CardHeader>
<CardTitle>{t("records.conditions.cardTitle")}</CardTitle>
<CardDescription>
{t("records.conditions.cardDescription")}
</CardDescription>
</CardHeader>
<CardContent>
<ConditionsManager />
</CardContent>
</Card>
<SettingsCard className="space-y-4">
<SettingsCardHeader
icon={HeartPulse}
title={t("records.conditions.cardTitle")}
description={t("records.conditions.cardDescription")}
/>
<ConditionsManager />
</SettingsCard>
)}
<Card>
<CardHeader>
<CardTitle>{t("records.allergies.cardTitle")}</CardTitle>
<CardDescription>
{t("records.allergies.cardDescription")}
</CardDescription>
</CardHeader>
<CardContent>
<AllergyManager />
</CardContent>
</Card>
<SettingsCard className="space-y-4">
<SettingsCardHeader
icon={ShieldAlert}
title={t("records.allergies.cardTitle")}
description={t("records.allergies.cardDescription")}
/>
<AllergyManager />
</SettingsCard>
<Card>
<CardHeader>
<CardTitle>{t("records.family.cardTitle")}</CardTitle>
<CardDescription>
{t("records.family.cardDescription")}
</CardDescription>
</CardHeader>
<CardContent>
<FamilyHistoryManager />
</CardContent>
</Card>
<SettingsCard className="space-y-4">
<SettingsCardHeader
icon={Users}
title={t("records.family.cardTitle")}
description={t("records.family.cardDescription")}
/>
<FamilyHistoryManager />
</SettingsCard>
<p className="text-muted-foreground text-xs">{t("records.disclaimer")}</p>
</div>