diff --git a/src/app/globals.css b/src/app/globals.css index a3c70f988..3c594012b 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -55,6 +55,20 @@ --color-dracula-red: var(--dracula-red); --color-dracula-yellow: var(--dracula-yellow); --color-dracula-lavender: var(--dracula-lavender); + + /* + * Semantic feedback tokens — aliases over the Dracula palette so badges, + * banners, and status pills can stop hard-coding `text-dracula-green` / + * `bg-dracula-orange/15` and ask for the *meaning* instead. Each is a + * straight alias of the existing colour at the time of introduction so + * the visual stays pixel-identical to v1.4.6 — what changes is intent. + * - success → dracula-green (positive outcome, e.g. published) + * - warning → dracula-orange (caution / non-blocking attention) + * - info → dracula-cyan (neutral informational note) + */ + --color-success: var(--success); + --color-warning: var(--warning); + --color-info: var(--info); } /* @@ -78,6 +92,16 @@ --dracula-yellow: #f1fa8c; --dracula-lavender: #d6acff; + /* + * Semantic feedback tokens (see @theme `--color-success` / `--color-warning` + * / `--color-info` re-exports). Aliased over the Dracula palette so existing + * dark-mode visuals stay identical; light mode (Alucard) below provides the + * higher-contrast counterpart so AA contrast lands on the white card. + */ + --success: var(--dracula-green); + --warning: var(--dracula-orange); + --info: var(--dracula-cyan); + --radius: 0.625rem; } @@ -135,6 +159,14 @@ --accent: #dcdeef; --accent-foreground: #1f1f1f; --destructive: #cb3a2a; + /* + * Alucard light-mode overrides for the semantic tokens — straight Dracula + * green/orange/cyan would fail AA contrast on a white card. These match the + * darker palette already used for `--destructive`/`--chart-*` in light mode. + */ + --success: #14720a; + --warning: #a34d14; + --info: #036a96; --border: #cfcfde; --input: #cfcfde; --ring: #644ac9; diff --git a/src/components/admin/feedback-inbox-section.tsx b/src/components/admin/feedback-inbox-section.tsx index b187189b1..d1b86e116 100644 --- a/src/components/admin/feedback-inbox-section.tsx +++ b/src/components/admin/feedback-inbox-section.tsx @@ -206,7 +206,11 @@ function FeedbackCategoryBadge({ > = { BUG: { label: t("admin.feedback.categoryBug"), - className: "bg-dracula-red/15 text-dracula-red border-dracula-red/30", + // Bug = something that's broken → semantic `destructive` token instead + // of raw `dracula-red`. Visually identical in dark mode (both resolve + // to #ff5555); light mode now picks up the AA-contrast `#cb3a2a`. + className: + "bg-destructive/15 text-destructive border-destructive/30", }, FEATURE_REQUEST: { label: t("admin.feedback.categoryFeature"), @@ -500,7 +504,7 @@ function FeedbackDetailDialog({ )} {issueUrl && ( - + {t("admin.feedback.publishedToGithub")} )} diff --git a/src/components/medications/medication-card.tsx b/src/components/medications/medication-card.tsx index 974b6efe6..2e4ef50f8 100644 --- a/src/components/medications/medication-card.tsx +++ b/src/components/medications/medication-card.tsx @@ -416,10 +416,10 @@ export function MedicationCard({ medication, onEdit }: MedicationCardProps) { {currentWindowStatus.status === "in_window" diff --git a/src/components/settings/ai-section.tsx b/src/components/settings/ai-section.tsx index 043e4afb5..e38ded9d0 100644 --- a/src/components/settings/ai-section.tsx +++ b/src/components/settings/ai-section.tsx @@ -334,7 +334,7 @@ function InsightsSettingsCard({
{settings?.codexStatus === "connected" && ( - + {t("settings.ai.chatgptConnectedBadge")} )} @@ -344,7 +344,7 @@ function InsightsSettingsCard({ )} {settings?.codexStatus === "expired" && ( - + {t("settings.ai.connectionExpiredBadge")} )} @@ -493,7 +493,7 @@ function InsightsSettingsCard({ {msg && (

{msg}

@@ -518,7 +518,7 @@ function InsightsSettingsCard({
{settings?.privacyMode === "raw" && ( -
+
{t("settings.rawDataWarning")}
)} @@ -958,7 +958,7 @@ function UserAIProviderSubsection() { {saveMsg && (

{saveMsg} @@ -967,7 +967,7 @@ function UserAIProviderSubsection() { {testMsg && (

{testMsg}