+
Related items
{related.map((item) => (
- {item.title}
- {item.set}
+ {item.title}
+ {item.set}
-
+
))}
From b551f2924c20813bd7467d46c792ec3cd46de295 Mon Sep 17 00:00:00 2001
From: BigSimmo <87357024+BigSimmo@users.noreply.github.com>
Date: Sat, 25 Jul 2026 23:06:05 +0800
Subject: [PATCH 2/6] fix(theme): salvage dark-mode audit delta without
clinical regressions
Cherry-pick the intentional dark-mode commit from PR #1190 onto current main,
keep trustGatedAnswerForClinicalNotes, drop unused manifest theme imports, and
normalize the no-hardcoded-hex ESLint rule export.
---
docs/branch-review-ledger.md | 1 +
eslint-rules/no-hardcoded-hex.mjs | 16 +++++++++++++---
src/app/manifest.ts | 6 +++---
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md
index c551d0591..23d8cffc2 100644
--- a/docs/branch-review-ledger.md
+++ b/docs/branch-review-ledger.md
@@ -957,3 +957,4 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-25 | execute-audit-code-remediation (PR #1162) | 1de1b32f562c0a972997750a5dc97a02ab1a9c15 | Production UI fix | Fixed ui-tools services referral header test (H1/quick-filters contract). Prior tip 09c6eb2d had Static/Safety/Unit/Migration green; only Production UI failed. | Local Playwright chromium services referral test PASS; no provider-backed checks. |
| 2026-07-25 | execute-audit-code-remediation (PR #1162) | b9b56c140eb14cbba5a2c2230e3fa28d3a791add | CI unblock after bot sync | Tip 96188eca had PR required SUCCESS (Static/Safety/Unit/Build/Migration/Production UI). Hosted pr-branch-sync then merged main (a420b86b/b9b56c14), leaving CI action_required for bot-authored runs. Pushing agent commit to re-trigger non-bot CI. | Prior tip 96188eca hosted CI green; local services referral Playwright PASS; no provider-backed checks. |
| 2026-07-25 | `cursor/ledger-066-067-519b` | f04392a408eceee14215c15169cbd6b70ac2041c | Close stale ledger #066/#067 (+ drop resolved #030/#075 from queue) | READY. #066 proven on main via #1174; #067 already fixed in #1191 in-process preflight. Docs-only ledger sync; no code change. | Local proof: `git show`/`log` for #1174/#1191; preflight test already in-process on main; ledger integrity asserts. No providers. |
+| 2026-07-25 | PR #1190 / `remediate-dark-mode-audit` | `00eca49b9b0d7e5fbfa5703a15e9e930963984a6` | Cursor review+Bugbot+prlanded+debug (fresh pass, same HEAD) | DO NOT MERGE; NOT LANDED (OPEN, mergeable=CONFLICTING/DIRTY, 468 behind / 2 ahead). Reconfirmed P0: conflict resolution deleted `trustGatedAnswerForClinicalNotes` (0 hits on head; main L584/632/659/1075) — Clinical Notes consumes ungated answer. P1: `src/app/api/answer/route.ts:6` imports nonexistent `@/lib/rag` (tsc TS2307; stream correctly uses `@/lib/rag/rag`). P1: merge-tree conflicts on answer/upload/evidence-panels + 10 paths; literal `<<<<<<<` in docs audit plan; migration timestamp collision risk vs main. Intentional dark-mode delta is only commit `363672602` (~10 files). Salvage: `cursor/pr1190-dark-mode-salvage-f453` cherry-picks that commit onto current main, restores unused-manifest-import cleanup, keeps clinical gate. Close #1190 after salvage lands. | Bugbot; `git grep` gate/import/markers; merge-tree; `tsc` TS2307 proof; gh pr view/checks (PR policy fail). Salvage: tsc clean; visual-evidence+overlay tests 13/13; eslint on changed files. No provider/UI matrix. |
diff --git a/eslint-rules/no-hardcoded-hex.mjs b/eslint-rules/no-hardcoded-hex.mjs
index 7ccfda7e5..2c7a5309f 100644
--- a/eslint-rules/no-hardcoded-hex.mjs
+++ b/eslint-rules/no-hardcoded-hex.mjs
@@ -1,4 +1,10 @@
-export default {
+/**
+ * Local ESLint rule: forbid hardcoded hex Tailwind colour utilities such as
+ * `bg-[#…]`, `text-[#…]`, and `border-[#…]` so themes must use semantic CSS
+ * variables (e.g. `var(--surface)`).
+ */
+
+const rule = {
meta: {
type: "problem",
docs: {
@@ -14,7 +20,8 @@ export default {
if (typeof node.value === "string" && hexPattern.test(node.value)) {
context.report({
node,
- message: "Hardcoded hex color utilities (bg-[#...], text-[#...], border-[#...]) are forbidden. Use semantic CSS variables (e.g. var(--surface)) to support theming.",
+ message:
+ "Hardcoded hex color utilities (bg-[#...], text-[#...], border-[#...]) are forbidden. Use semantic CSS variables (e.g. var(--surface)) to support theming.",
});
}
},
@@ -22,10 +29,13 @@ export default {
if (node.value && node.value.raw && hexPattern.test(node.value.raw)) {
context.report({
node,
- message: "Hardcoded hex color utilities (bg-[#...], text-[#...], border-[#...]) are forbidden. Use semantic CSS variables (e.g. var(--surface)) to support theming.",
+ message:
+ "Hardcoded hex color utilities (bg-[#...], text-[#...], border-[#...]) are forbidden. Use semantic CSS variables (e.g. var(--surface)) to support theming.",
});
}
},
};
},
};
+
+export default rule;
diff --git a/src/app/manifest.ts b/src/app/manifest.ts
index 0c1992a74..a0f096697 100644
--- a/src/app/manifest.ts
+++ b/src/app/manifest.ts
@@ -1,10 +1,10 @@
import type { MetadataRoute } from "next";
-import { APP_THEME_COLORS, DEFAULT_THEME } from "@/lib/theme";
// PWA manifest — makes the app installable with a proper icon. Icons derive from
// the single brand-mark source: the SVG for modern browsers, plus generated PNG
-// "any" and "maskable" sets from app/icons/[variant]. Colours match the light
-// default of viewport.themeColor in app/layout.tsx.
+// "any" and "maskable" sets from app/icons/[variant]. Theme colours stay on
+// viewport.themeColor / meta theme-color (see app/layout.tsx and use-theme.ts)
+// so light/dark can update without a static PWA manifest colour lock.
export default function manifest(): MetadataRoute.Manifest {
return {
name: "Clinical KB",
From e702c6c92d08232c1b3f498ec84d540144aeb0fa Mon Sep 17 00:00:00 2001
From: BigSimmo <87357024+BigSimmo@users.noreply.github.com>
Date: Sat, 25 Jul 2026 23:09:07 +0800
Subject: [PATCH 3/6] style: prettier-format dark-mode salvage files
---
.../clinical-dashboard/use-theme.ts | 2 +-
.../favourites-library-redesign-page.tsx | 103 +++++++++++++-----
2 files changed, 77 insertions(+), 28 deletions(-)
diff --git a/src/components/clinical-dashboard/use-theme.ts b/src/components/clinical-dashboard/use-theme.ts
index 1315c1f16..b5d5562d8 100644
--- a/src/components/clinical-dashboard/use-theme.ts
+++ b/src/components/clinical-dashboard/use-theme.ts
@@ -84,7 +84,7 @@ function syncThemeColorMetadata(theme: ResolvedTheme) {
function applyResolvedTheme(theme: ResolvedTheme) {
const isCurrentlyDark = document.documentElement.classList.contains("dark");
const willBeDark = theme === "dark";
-
+
if (isCurrentlyDark !== willBeDark) {
document.documentElement.classList.add("theme-transitioning");
document.documentElement.classList.toggle("dark", willBeDark);
diff --git a/src/components/favourites-page-mockups/favourites-library-redesign-page.tsx b/src/components/favourites-page-mockups/favourites-library-redesign-page.tsx
index 3ce6728d9..b56c61f25 100644
--- a/src/components/favourites-page-mockups/favourites-library-redesign-page.tsx
+++ b/src/components/favourites-page-mockups/favourites-library-redesign-page.tsx
@@ -185,7 +185,8 @@ const variants: Record<
selectedId: "acamprosate-renal-screen",
accent: "#007c89",
pageClassName: "bg-[color:var(--surface-lux)] text-[color:var(--text-heading)]",
- commandClassName: "bg-[color:var(--clinical-accent)] text-white shadow-[0_14px_34px_rgba(0,124,137,0.24)] hover:bg-[color:var(--clinical-accent-hover)]",
+ commandClassName:
+ "bg-[color:var(--clinical-accent)] text-white shadow-[0_14px_34px_rgba(0,124,137,0.24)] hover:bg-[color:var(--clinical-accent-hover)]",
resumeTitle: "Resume Acamprosate renal screen",
resumeBody: "Open the ward-round renal caution page with source count, set context, and next action visible.",
primaryFilter: "Recent",
@@ -198,7 +199,8 @@ const variants: Record<
selectedId: "lithium-monitoring-guideline",
accent: "#1d4ed8",
pageClassName: "bg-[color:var(--surface-raised)] text-[color:var(--text-heading)]",
- commandClassName: "bg-[color:var(--primary)] text-white shadow-[0_14px_34px_rgba(29,78,216,0.22)] hover:bg-[color:var(--primary-hover)]",
+ commandClassName:
+ "bg-[color:var(--primary)] text-white shadow-[0_14px_34px_rgba(29,78,216,0.22)] hover:bg-[color:var(--primary-hover)]",
resumeTitle: "Review lithium monitoring guideline",
resumeBody: "Check pages 4-9, mark the PDF as reviewed, then ask against the document if needed.",
primaryFilter: "Review due",
@@ -211,7 +213,8 @@ const variants: Record<
selectedId: "renal-dose-search",
accent: "#047857",
pageClassName: "bg-[color:var(--surface-lux)] text-[color:var(--text-heading)]",
- commandClassName: "bg-[color:var(--success)] text-white shadow-[0_14px_34px_rgba(4,120,87,0.24)] hover:bg-[color:var(--success-hover)]",
+ commandClassName:
+ "bg-[color:var(--success)] text-white shadow-[0_14px_34px_rgba(4,120,87,0.24)] hover:bg-[color:var(--success-hover)]",
resumeTitle: "Run renal dose saved search",
resumeBody: "Restart the ward-round saved query across medicines and documents before opening individual items.",
primaryFilter: "Ward round",
@@ -225,15 +228,20 @@ const variantRoutes: Array<{ id: FavouritesLibraryRedesignVariant; href: string
];
function statusClassName(state: ReviewState) {
- if (state === "review-due") return "border-[color:var(--warning-border)] bg-[color:var(--warning-soft)] text-[color:var(--warning)]";
- if (state === "recent") return "border-[color:var(--type-document-border)] bg-[color:var(--type-document-soft)] text-[color:var(--type-document)]";
+ if (state === "review-due")
+ return "border-[color:var(--warning-border)] bg-[color:var(--warning-soft)] text-[color:var(--warning)]";
+ if (state === "recent")
+ return "border-[color:var(--type-document-border)] bg-[color:var(--type-document-soft)] text-[color:var(--type-document)]";
return "border-[color:var(--success-border)] bg-[color:var(--success-soft)] text-[color:var(--success)]";
}
function kindClassName(kind: FavouriteKind) {
- if (kind === "Medication") return "border-[color:var(--success-border)] bg-[color:var(--success-soft)] text-[color:var(--success)]";
- if (kind === "Document") return "border-[color:var(--type-document-border)] bg-[color:var(--type-document-soft)] text-[color:var(--type-document)]";
- if (kind === "Source") return "border-[color:var(--type-source-border)] bg-[color:var(--type-source-soft)] text-[color:var(--type-source)]";
+ if (kind === "Medication")
+ return "border-[color:var(--success-border)] bg-[color:var(--success-soft)] text-[color:var(--success)]";
+ if (kind === "Document")
+ return "border-[color:var(--type-document-border)] bg-[color:var(--type-document-soft)] text-[color:var(--type-document)]";
+ if (kind === "Source")
+ return "border-[color:var(--type-source-border)] bg-[color:var(--type-source-soft)] text-[color:var(--type-source)]";
return "border-[color:var(--border)] bg-[color:var(--surface-subtle)] text-[color:var(--text-muted)]";
}
@@ -250,7 +258,9 @@ function ShellPill({
{Icon ? : null}
@@ -264,7 +274,9 @@ function IconTile({ icon: Icon, active = false }: { icon: LucideIcon; active?: b
@@ -329,11 +341,15 @@ function PageHeader({ variant, selected }: { variant: FavouritesLibraryRedesignV
-
{config.eyebrow}
+
+ {config.eyebrow}
+
{config.title}
-
{config.description}
+
+ {config.description}
+