mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
style(ui): pull off-scale spacing and micro-labels onto the scale
Sweep the spacing rests that sat off the 1/1.5/2/3/4/6/8/10 scale: the health-score panels and their skeleton, the recommendation ask-Coach gutter, the onboarding tour footer, the vaccination row, the danger-zone alert margins, the recovery-codes action wrapper, and the chart-tooltip tile. Move the last hand-written micro-sizes (coach counters, the personal-record badge, the score-ring label, the dose-history and cycle-calendar headers, the mood tag chips) onto the text-2xs token, and give the documents upload buttons the mobile tap floor their peers set.
This commit is contained in:
1 parent
b6332a96d9
commit
7f6eae8425
15 files changed
+29
-23
No files matched your search
@@ -282,7 +282,7 @@ function CoachConversationsBody() {
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{(c.attachments?.length ?? 0) > 1 ? (
|
||||
<span className="text-[10px] font-semibold tabular-nums">
|
||||
<span className="text-2xs font-semibold tabular-nums">
|
||||
{c.attachments?.length}
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -73,7 +73,7 @@ export function RichChartTooltip({
|
||||
return (
|
||||
<div
|
||||
data-slot="rich-chart-tooltip"
|
||||
className="bg-card border-border min-w-[140px] rounded-xl border p-2.5 text-xs shadow-lg"
|
||||
className="bg-card border-border min-w-[140px] rounded-xl border p-3 text-xs shadow-lg"
|
||||
style={{
|
||||
// The card itself is layered above the chart's own SVG; without
|
||||
// an explicit background the gradient bleeds through the
|
||||
|
||||
@@ -177,7 +177,7 @@ export function CycleCalendar({
|
||||
<div
|
||||
key={i}
|
||||
role="columnheader"
|
||||
className="text-muted-foreground pb-1 text-center text-[11px] font-medium uppercase"
|
||||
className="text-muted-foreground text-2xs pb-1 text-center font-medium uppercase"
|
||||
>
|
||||
{wk}
|
||||
</div>
|
||||
|
||||
@@ -883,7 +883,10 @@ export function DocumentsView() {
|
||||
description={t("documents.subtitle")}
|
||||
actions={
|
||||
canManage ? (
|
||||
<Button onClick={() => uploadInputRef.current?.click()}>
|
||||
<Button
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => uploadInputRef.current?.click()}
|
||||
>
|
||||
<Upload className="size-4" aria-hidden />
|
||||
{t("documents.pageUpload")}
|
||||
</Button>
|
||||
@@ -940,7 +943,10 @@ export function DocumentsView() {
|
||||
ctaSize="lg"
|
||||
action={
|
||||
canManage ? (
|
||||
<Button onClick={() => uploadInputRef.current?.click()}>
|
||||
<Button
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => uploadInputRef.current?.click()}
|
||||
>
|
||||
<Upload className="size-4" aria-hidden />
|
||||
{t("documents.empty.action")}
|
||||
</Button>
|
||||
|
||||
@@ -234,7 +234,7 @@ export function HistoryRail({
|
||||
>
|
||||
<Paperclip className="size-3.5" aria-hidden="true" />
|
||||
{(c.attachments?.length ?? 0) > 1 ? (
|
||||
<span className="text-[10px] font-semibold tabular-nums">
|
||||
<span className="text-2xs font-semibold tabular-nums">
|
||||
{c.attachments?.length}
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -56,7 +56,7 @@ const SIZE: Record<
|
||||
NonNullable<ScoreRingProps["size"]>,
|
||||
{ px: number; numberClass: string; labelClass: string }
|
||||
> = {
|
||||
sm: { px: 120, numberClass: "text-3xl", labelClass: "text-[11px]" },
|
||||
sm: { px: 120, numberClass: "text-3xl", labelClass: "text-2xs" },
|
||||
md: { px: 168, numberClass: "text-5xl", labelClass: "text-xs" },
|
||||
lg: { px: 232, numberClass: "text-7xl", labelClass: "text-sm" },
|
||||
};
|
||||
@@ -284,7 +284,7 @@ export function ScoreRing({
|
||||
{!hasScore && (
|
||||
<span
|
||||
data-slot="score-ring-provisional"
|
||||
className="text-muted-foreground absolute inset-x-0 bottom-0 line-clamp-1 px-1 text-center text-[10px] leading-tight"
|
||||
className="text-muted-foreground text-2xs absolute inset-x-0 bottom-0 line-clamp-1 px-1 text-center leading-tight"
|
||||
>
|
||||
{t("insights.derived.scoreRing.provisionalCaption")}
|
||||
</span>
|
||||
|
||||
@@ -310,7 +310,7 @@ export function HealthScoreCard({
|
||||
PANEL_COLUMN_CLASS,
|
||||
// `h-full` lets the hero band's `items-stretch` equalise the column
|
||||
// against the greeting; `mt-auto` on the foot collects the slack.
|
||||
"flex h-full flex-col gap-3.5",
|
||||
"flex h-full flex-col gap-3",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
@@ -827,7 +827,7 @@ export function HealthScoreCardSkeleton({ className }: { className?: string }) {
|
||||
PANEL_CHROME_CLASS,
|
||||
"border-border/60",
|
||||
PANEL_COLUMN_CLASS,
|
||||
"flex h-full flex-col gap-3.5",
|
||||
"flex h-full flex-col gap-3",
|
||||
PANEL_RESERVE_CLASS,
|
||||
className,
|
||||
)}
|
||||
@@ -838,7 +838,7 @@ export function HealthScoreCardSkeleton({ className }: { className?: string }) {
|
||||
keeps these blocks under the minimum above, so the minimum is the
|
||||
thing that decides the height. */}
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-15 w-28" />
|
||||
<Skeleton className="h-14 w-28" />
|
||||
<Skeleton className="h-2 w-full rounded-full" />
|
||||
<div className="space-y-1">
|
||||
<Skeleton className="h-4 w-40" />
|
||||
|
||||
@@ -120,7 +120,7 @@ export function PersonalRecordBadge({
|
||||
// green on the dark card (#50fa7b). Both clear 4.5:1 against
|
||||
// their card background — the previous `text-success` on
|
||||
// `bg-success/10` measured ~2.6:1 in dark mode.
|
||||
"border-success/40 bg-success/15 text-success inline-flex shrink-0 items-center rounded-full border px-1.5 py-0.5 text-[10px] leading-none font-semibold tracking-wide uppercase tabular-nums",
|
||||
"border-success/40 bg-success/15 text-success text-2xs inline-flex shrink-0 items-center rounded-full border px-1.5 py-0.5 leading-none font-semibold tracking-wide uppercase tabular-nums",
|
||||
className,
|
||||
)}
|
||||
aria-label={t("insights.personalRecord.badge")}
|
||||
|
||||
@@ -443,7 +443,7 @@ export function RecommendationCard({
|
||||
|
||||
{/* v1.21.0 (C4 H2) — discreet "ask the Coach about this rec" link,
|
||||
aligned under the rec text (the number gutter is `ml-6`). */}
|
||||
<div className="mt-1 ml-5">
|
||||
<div className="mt-1 ml-6">
|
||||
<AskCoachAction
|
||||
question={coachQuestion}
|
||||
scope={coachScopeSource ? { metric: coachScopeSource } : undefined}
|
||||
|
||||
@@ -184,7 +184,7 @@ export function MoodTagPicker({
|
||||
}`}
|
||||
>
|
||||
<TagIcon className="h-5 w-5" aria-hidden="true" />
|
||||
<span className="text-[11px] leading-tight">{label}</span>
|
||||
<span className="text-2xs leading-tight">{label}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
@@ -337,7 +337,7 @@ function AddTagTile({
|
||||
className="border-border/70 text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring focus-visible:ring-offset-background flex min-h-16 w-[4.5rem] flex-col items-center justify-center gap-1 rounded-xl border border-dashed p-2 text-center transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
|
||||
>
|
||||
<Plus className="h-5 w-5" aria-hidden="true" />
|
||||
<span className="text-[11px] leading-tight">{label}</span>
|
||||
<span className="text-2xs leading-tight">{label}</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -695,7 +695,7 @@ export function OnboardingTour({
|
||||
{/* `flex-wrap` keeps long localised labels (Skip / Back / Next) from
|
||||
forcing a horizontal scrollbar inside the card — the row wraps
|
||||
instead, so the primary action is always reachable. */}
|
||||
<footer className="mt-5 flex flex-wrap items-center justify-between gap-2">
|
||||
<footer className="mt-4 flex flex-wrap items-center justify-between gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
|
||||
@@ -108,7 +108,7 @@ function DataResetCard() {
|
||||
{msg && (
|
||||
<p
|
||||
role="alert"
|
||||
className={`mt-3 text-sm ${msgType === "success" ? "text-success" : "text-destructive"}`}
|
||||
className={`text-sm ${msgType === "success" ? "text-success" : "text-destructive"}`}
|
||||
>
|
||||
{msg}
|
||||
</p>
|
||||
@@ -246,7 +246,7 @@ function AccountDeleteCard() {
|
||||
{msg && (
|
||||
<p
|
||||
role="alert"
|
||||
className={`mt-3 text-sm ${msgType === "success" ? "text-success" : "text-destructive"}`}
|
||||
className={`text-sm ${msgType === "success" ? "text-success" : "text-destructive"}`}
|
||||
>
|
||||
{msg}
|
||||
</p>
|
||||
|
||||
@@ -72,13 +72,13 @@ export function DoseHistoryColumnRulings() {
|
||||
<dt className="text-foreground flex flex-wrap items-baseline gap-x-2 text-xs">
|
||||
<code className="font-mono">{ruling.column}</code>
|
||||
<span
|
||||
className="text-muted-foreground text-[0.6875rem] uppercase"
|
||||
className="text-muted-foreground text-2xs uppercase"
|
||||
data-verdict={ruling.verdict}
|
||||
>
|
||||
{verdictFor(ruling.verdict)}
|
||||
</span>
|
||||
{ruling.jsonOnly && (
|
||||
<span className="text-muted-foreground text-[0.6875rem]">
|
||||
<span className="text-muted-foreground text-2xs">
|
||||
{t("settings.sections.export.import.doseHistory.jsonOnly")}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -325,9 +325,9 @@ export function TotpCard({
|
||||
|
||||
{/* ── Fresh recovery codes (post-confirm or post-regen) ── */}
|
||||
{freshCodes && (
|
||||
<div>
|
||||
<div className="space-y-3">
|
||||
<RecoveryCodesPanel codes={freshCodes} />
|
||||
<SettingsCardActions className="mt-3">
|
||||
<SettingsCardActions>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
|
||||
@@ -172,7 +172,7 @@ function DoseRow({
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<CardContent className="flex items-center justify-between gap-3 px-4 py-2.5">
|
||||
<CardContent className="flex items-center justify-between gap-3 px-4 py-3">
|
||||
<div className="min-w-0 space-y-0.5">
|
||||
<div className="flex flex-wrap items-center gap-x-2 text-sm">
|
||||
{series ? (
|
||||
|
||||
Reference in new issue
Block a user