diff --git a/public/offline.html b/public/offline.html
index 5d6c50012d..9a628a723c 100644
--- a/public/offline.html
+++ b/public/offline.html
@@ -34,11 +34,11 @@
--page-text: #1b2533; /* --text */
--page-heading: #0a1220; /* --text-heading */
--page-muted: #55627a; /* --text-muted */
- --page-accent: #1a66a8; /* --command */
- --page-accent-hover: #185c99; /* --command-hover */
+ --page-accent: #111827; /* --command */
+ --page-accent-hover: #0b1220; /* --command-hover */
--page-accent-contrast: #ffffff; /* --command-contrast */
--page-focus: var(--page-accent); /* --focus command channel */
- --page-glow: rgb(26 102 168 / 10%); /* command at low alpha */
+ --page-glow: rgb(17 24 39 / 10%); /* command at low alpha */
--page-shadow: 0 4px 8px rgb(13 40 71 / 5%), 0 32px 56px -20px rgb(13 40 71 / 15%); /* --e4 */
background: var(--page-background);
color: var(--page-text);
@@ -135,10 +135,10 @@
--page-text: #f4f6f8; /* dark --text */
--page-heading: #fbfcfd; /* dark --text-heading */
--page-muted: #a8b2bd; /* dark --text-muted */
- --page-accent: #3a80c0; /* dark --command */
- --page-accent-hover: #4a91d2; /* dark --command-hover */
- --page-accent-contrast: #06121e; /* dark --command-contrast */
- --page-glow: rgb(58 128 192 / 10%);
+ --page-accent: #f5f7f7; /* dark --command */
+ --page-accent-hover: #e6e9e8; /* dark --command-hover */
+ --page-accent-contrast: #0a0c0e; /* dark --command-contrast */
+ --page-glow: rgb(245 247 247 / 10%);
--page-shadow: inset 0 1px 0 rgb(255 255 255 / 7%), 0 32px 56px -20px rgb(0 0 0 / 64%); /* dark --e4 */
}
}
diff --git a/public/sw.js b/public/sw.js
index 07b1b32b9a..4e0733a46a 100644
--- a/public/sw.js
+++ b/public/sw.js
@@ -7,7 +7,7 @@
*/
const CACHE_PREFIX = "clinical-kb-pwa-";
-const CACHE_VERSION = "2026-08-05-v2";
+const CACHE_VERSION = "2026-08-05-v3";
const SHELL_CACHE = `${CACHE_PREFIX}shell-${CACHE_VERSION}`;
const STATIC_CACHE = `${CACHE_PREFIX}static-${CACHE_VERSION}`;
const STATIC_CACHE_PREFIX = `${CACHE_PREFIX}static-`;
diff --git a/src/app/ckb-v2-tokens.css b/src/app/ckb-v2-tokens.css
index f7d086b28f..c5597ec376 100644
--- a/src/app/ckb-v2-tokens.css
+++ b/src/app/ckb-v2-tokens.css
@@ -194,7 +194,11 @@
}
}
-/* Crisp white light shell (#10, #24) + blue command colour (#1, #12).
+/* Crisp white light shell (#10, #24). Command stays graphite, matching the
+ live compatibility layer and docs/redesign/permanent-colour-direction.md —
+ command (CTA) and clinical-accent (evidence/selected/send) are deliberately
+ different roles; a blue command briefly shipped here and collapsed that
+ distinction (reverted per design-system review, 2026-08-05).
Light is the default on .ckb-v2 itself - never :not(.dark), which matched a
subtree inside html.dark and overrode the inherited dark values (DS-01). */
.ckb-v2.ckb-v2 {
@@ -233,9 +237,9 @@
--decoration-soft: #8894a6;
--disabled: #9aa5b5;
- --command: #1a66a8;
- --command-hover: #185c99;
- --command-active: #164a7a;
+ --command: #111827;
+ --command-hover: #0b1220;
+ --command-active: #080b0f;
--command-contrast: #ffffff;
--danger-solid: #a3190f;
--danger-solid-hover: #85140d;
@@ -334,10 +338,10 @@
--decoration-soft: #7d8792;
--border-dashed: #454e57;
- --command: #3a80c0;
- --command-hover: #4a91d2;
- --command-active: #1d6fb8;
- --command-contrast: #06121e;
+ --command: #f5f7f7;
+ --command-hover: #e6e9e8;
+ --command-active: #cbd1d8;
+ --command-contrast: #0a0c0e;
--danger-solid: #b42318;
--danger-solid-hover: #d92d20;
--danger-solid-active: #912018;
diff --git a/tests/pwa-manifest.test.ts b/tests/pwa-manifest.test.ts
index a789999dbb..d63531cf29 100644
--- a/tests/pwa-manifest.test.ts
+++ b/tests/pwa-manifest.test.ts
@@ -87,9 +87,16 @@ describe("PWA manifest and public bootstrap resources", () => {
);
expect(offlineHtml).toContain('');
expect(offlineHtml).toContain("--page-background: #ffffff; /* --background */");
- expect(offlineHtml).toContain("--page-accent: #1a66a8; /* --command */");
+ expect(offlineHtml).toContain("--page-accent: #111827; /* --command */");
+ expect(offlineHtml).toContain("--page-accent-hover: #0b1220; /* --command-hover */");
+ expect(offlineHtml).toContain("--page-accent-contrast: #ffffff; /* --command-contrast */");
+ expect(offlineHtml).toContain("--page-glow: rgb(17 24 39 / 10%); /* command at low alpha */");
expect(offlineHtml).toContain("--page-background: #0b0e11; /* dark --background */");
expect(offlineHtml).toContain("--page-surface: #1c2126; /* dark --surface-raised */");
+ expect(offlineHtml).toContain("--page-accent: #f5f7f7; /* dark --command */");
+ expect(offlineHtml).toContain("--page-accent-hover: #e6e9e8; /* dark --command-hover */");
+ expect(offlineHtml).toContain("--page-accent-contrast: #0a0c0e; /* dark --command-contrast */");
+ expect(offlineHtml).toContain("--page-glow: rgb(245 247 247 / 10%);");
expect(offlineHtml).not.toContain("#060708");
});
@@ -101,8 +108,8 @@ describe("PWA manifest and public bootstrap resources", () => {
// value (never reuse a previous one, even for rollbacks) and record the
// new offline.html hash here.
const expectedPairing = {
- cacheVersion: "2026-08-05-v2",
- offlineHtmlSha256: "ce5e4b73faccfaa69a43d7e29cf13c41f948b6fe6b364797ae321506368cd86c",
+ cacheVersion: "2026-08-05-v3",
+ offlineHtmlSha256: "a681b26a0cbe0c046dc6f694d9f9990946614a11338fd38ec14527cd693f93eb",
};
const workerSource = readFileSync(join(process.cwd(), "public", "sw.js"), "utf8");