From 038be6ac571dba609fbb7f32417da80c08f7148d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 5 Jun 2026 18:42:18 +0200 Subject: [PATCH] =?UTF-8?q?chore(release):=20v1.12.11=20=E2=80=94=20unify?= =?UTF-8?q?=20settings=20notice=20colours=20and=20callout=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Route every Settings callout, badge and status note through the semantic colour tokens (success / warning / info / primary) instead of raw palette classes, so the same meaning reads identically across cards and stays legible in light mode. Add a single SettingsInfoTile primitive — icon + tone + text on one fixed surface — and adopt it for the threshold-override caution note, replacing a bespoke box. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 6 ++ docs/api/openapi.yaml | 2 +- package.json | 2 +- src/components/settings/_info-tile.tsx | 90 +++++++++++++++++++ src/components/settings/advanced-section.tsx | 6 +- src/components/settings/ai-section.tsx | 6 +- .../settings/health-record-export-panel.tsx | 2 +- .../settings/notification-status-card.tsx | 4 +- .../settings/test-connection-button.tsx | 2 +- .../settings/thresholds-editor-section.tsx | 8 +- 10 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 src/components/settings/_info-tile.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index f85d0d5ac..b927ae7b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [1.12.11] — 2026-06-05 — settings notices read the same everywhere + +### Changed + +- **Settings notices and status colours are unified.** Every callout, badge and status note in Settings now draws from the same set of meaning-based colours — success, caution, info — so a green "connected" or an amber "needs attention" looks identical from one card to the next and stays legible in both light and dark themes. Caution notes share one consistent boxed style with a leading icon. + ## [1.12.10] — 2026-06-05 — a "taken" tap no longer back-fills the wrong dose ### Fixed diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 2300119bf..43e433df7 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: HealthLog API - version: 1.12.10 + version: 1.12.11 description: >- Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest. diff --git a/package.json b/package.json index 444c5b722..7551d7932 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "healthlog", - "version": "1.12.10", + "version": "1.12.11", "description": "Self-hosted personal-health-tracking PWA with Withings integration, AI insights, and doctor-report PDF export.", "license": "AGPL-3.0-only", "homepage": "https://healthlog.dev", diff --git a/src/components/settings/_info-tile.tsx b/src/components/settings/_info-tile.tsx new file mode 100644 index 000000000..8fa89f6c1 --- /dev/null +++ b/src/components/settings/_info-tile.tsx @@ -0,0 +1,90 @@ +"use client"; + +/** + * `` — the one callout shape for Settings. + * + * Before this primitive, every section hand-rolled its own notice box: + * `border-l-2`/`border-l-4`, `rounded-md`/`rounded-lg`, mismatched + * border/background tone intensities, and raw palette colours used as + * text (which fail AA in light mode). The tile fixes the surface to a + * single contract — icon left, short text right, a tone-coloured left + * border — and routes every tone through the semantic tokens so the + * same notice reads identically in light and dark. + * + * Tones map to the project's semantic colour tokens: + * - `info` → `--info` (neutral guidance) + * - `warning` → `--warning` (caution / override / reconnect) + * - `success` → `--success` (confirmation) + * - `primary` → `--primary` (brand-accented instruction) + * - `neutral` → muted surface (low-emphasis aside) + */ + +import * as React from "react"; +import type { LucideIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +export type SettingsInfoTileTone = + | "info" + | "warning" + | "success" + | "primary" + | "neutral"; + +const TONE_SURFACE: Record = { + info: "border-info/40 bg-info/10", + warning: "border-warning/40 bg-warning/10", + success: "border-success/40 bg-success/10", + primary: "border-primary/40 bg-primary/10", + neutral: "border-border bg-muted/30", +}; + +const TONE_ICON: Record = { + info: "text-info", + warning: "text-warning", + success: "text-success", + primary: "text-primary", + neutral: "text-muted-foreground", +}; + +export interface SettingsInfoTileProps { + /** Lucide icon component; rendered in the tone colour. */ + icon: LucideIcon; + /** Visual tone — routes through the semantic colour tokens. */ + tone?: SettingsInfoTileTone; + /** Optional emphasised first line. */ + title?: React.ReactNode; + /** Body content — muted text. */ + children?: React.ReactNode; + /** Optional extra classes on the outer wrapper. */ + className?: string; +} + +export function SettingsInfoTile({ + icon: Icon, + tone = "info", + title, + children, + className, +}: SettingsInfoTileProps) { + return ( +
+
+ ); +} diff --git a/src/components/settings/advanced-section.tsx b/src/components/settings/advanced-section.tsx index ef993b414..e1802e895 100644 --- a/src/components/settings/advanced-section.tsx +++ b/src/components/settings/advanced-section.tsx @@ -156,7 +156,7 @@ function ResearchModeCard() { data-slot="settings-research-mode-card" >
- +

{t("settings.researchMode.sectionTitle")}

@@ -349,7 +349,7 @@ function DataResetCard() { {msg && (

{msg}

@@ -493,7 +493,7 @@ function AccountDeleteCard() { {msg && (

{msg}

diff --git a/src/components/settings/ai-section.tsx b/src/components/settings/ai-section.tsx index 4e1cfb54e..feff839c2 100644 --- a/src/components/settings/ai-section.tsx +++ b/src/components/settings/ai-section.tsx @@ -520,7 +520,7 @@ function ProviderStatusBadges({ {settings?.codexStatus !== "connected" && settings?.hasAdminKey && activeProvider !== "codex" && ( - + {t("settings.ai.adminAiActiveBadge")} )} @@ -837,7 +837,7 @@ function CodexProviderForm({ {t("settings.ai.codex.disconnectButton")} ) : deviceCode ? ( -
+

{t("settings.ai.deviceCodeHeading")}

@@ -848,7 +848,7 @@ function CodexProviderForm({ href={deviceCode.verificationUrl} target="_blank" rel="noopener noreferrer" - className="text-dracula-purple font-medium underline" + className="text-primary font-medium underline" > {deviceCode.verificationUrl} diff --git a/src/components/settings/health-record-export-panel.tsx b/src/components/settings/health-record-export-panel.tsx index 9bfdbcb58..cefedf981 100644 --- a/src/components/settings/health-record-export-panel.tsx +++ b/src/components/settings/health-record-export-panel.tsx @@ -201,7 +201,7 @@ export function HealthRecordExportPanel() { >