diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md
index 5cc5472fa4..a2b01a774a 100644
--- a/docs/branch-review-ledger.md
+++ b/docs/branch-review-ledger.md
@@ -1164,6 +1164,7 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-27 | PR #1280 / `claude/top-search-design-mockups-w53znc` | `980b4298` | Implemented review follow-up | Synced main; rail overflow observes childList mutations. Temporarily disabled auto-merge to land polish without squash race. | Focused band Vitest 9/9; no provider checks. |
| 2026-07-27 | PR #1281 / `claude/safety-planning-tools-page-tsq4vs` | `f7e616d1` | Implemented review polish | StepBuilderCard filled uses `isStepComplete`; clipboard DRAFT assertion added. Auto-merge temporarily disabled to land polish. | Focused safety-plan Vitest 3/3; no provider checks. |
| 2026-07-27 | PR #1261/#1262/#1263 audit cluster | closed tips | Close without merge | Closed per review: unsafe lineage / tip markers / privacy+RAG P1s / parallel verify:cheap rewrite. Thin PDF exit-137 salvage opened separately. | Prior Bugbot + merge-tree evidence; no provider checks. |
+| 2026-07-28 | PR #1273 / `codex/create-mobile-navigation-mockups` | `c8af3d1ab830` | CI babysit + Codex thread closeout | MERGEABLE; 0 behind main; merge-tree CLEAN. Fixed earlier Static type-scale failure; suppressed shared composer on phone nav mockup; resolved 4 Codex P2 threads (scroll, overflow More, progress clamp x2). Bugbot: no cursor[bot] findings. | check:type-scale --strict PASS; hosted Static/Build/Unit/Advisory PASS on tip; Production UI pending; no provider checks. |
| 2026-07-27 | PR #1286 / `fix-test-run-lock` | `d2219a8be89e6c218c4412fe40d4eb4b86fd79bf` | Merge-conflict repair + Bugbot + CI fix | FIXED. Resolved CONFLICTING merge vs main by keeping main soft-glass phone chrome, shared test-run-lock coordinator, tokenized document-nav mockups, and accessible-name Playwright contract; preserved PR forced-colors:border and literalShadowClasses 0 ratchet. Bugbot found no remaining P0-P2 on unique product delta. Removed 9 exact duplicate ledger rows introduced by merge=union. | Focused design-system + knip + mobile-chrome-paint + test-runner-safety PASS; ledger guard PASS after dedupe; hosted Static PR re-run pending; no provider-backed checks. |
| 2026-07-27 | PR #1286 / `fix-test-run-lock` | `bef2377d477a03b7b8bbb50ad7caf99eda258be5` | Ledger dedupe follow-up after conflict merge | APPROVE pending exact-head hosted required checks. Supersedes the `d2219a8b` row for CI readiness: exact duplicate ledger rows removed; unique product delta remains forced-colors:border, literalShadowClasses 0, and diagnosis-map shadow token. No unresolved review threads; Bugbot found no remaining P0-P2. | `check:branch-review-ledger` PASS (1084 records); design-system / knip / mobile-chrome-paint / test-runner-safety PASS; `verify:cheap` rerunning; no provider-backed checks. |
| 2026-07-27 | PR #1286 / | `b9ac1621a3993338a242d520bdc2d1a1dc29934c` | Post-conflict CI green + Bugbot closeout | APPROVE. Conflicts resolved; hosted required aggregate green (Static PR, Unit coverage, Build, Safety, Production UI, PR required). No unresolved review threads. Bugbot: no remaining P0-P2 on unique product delta (forced-colors:border, literalShadowClasses 0, diagnosis-map shadow token). Residual: NodeDetails phone sheet now uses downward --shadow-elevated instead of old upward literal cast (visual only). | Hosted PR required PASS; Production UI PASS (11m41s); Advisory UI PASS; local verify:cheap PASS (396 files / 3558 passed); focused design-system/knip/mobile-chrome-paint/test-runner-safety PASS; no provider-backed checks. |
@@ -1175,6 +1176,7 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-28 | PR #1289 / `codex/rag-reliability-final` | `a1ca6a016490e4d4b564edd3d553d87fed3071df` | Protected-main RAG reliability, clinical-governance and release review | APPROVE. Independent retrieval, governance and fallback reviews found and fixed three merge blockers: global chunk-query alias overreach was narrowed to the measured clozapine blood-count action shape; legacy private source reviews remain on the deployed v1 RPC while unapplied-v2 paths fail explicitly; and source-backed review fallback is now a zero-tolerance blocking metric with reconciled evidence. Final rereviews found no P0-P2. PR #1288 was superseded without force-push after GitGuardian correctly rejected a token-shaped fake fixture; the clean replacement tree is byte-identical to the reviewed tree and both secret scanners pass. The additive BMJ attestation migration remains unapplied and BMJ stays unverified pending qualified human action. | Exact application tree `verify:pr-local` PASS: format, zero-warning lint, typecheck, 403 files and 4,101 tests passed with 2 skipped, production build/client-secret scan, and 36 offline RAG fixtures. Live 36-case canary PASS with document/content recall 1.0, zero failed cases and zero per-case document/content RR regressions; three cache-bypassed affected-path answer probes PASS with zero provider requests and zero generation cost. Earlier coverage PASS: 399 files, 4,062 passed and 2 skipped, RAG 86.83% statements and 90.79% lines. Hosted build, static, unit coverage, migration replay, Supabase Preview, Production UI, policy, Semgrep, Gitleaks and GitGuardian passed on the implementation tree; final evidence-only head requires the normal hosted rerun. |
| 2026-07-28 | PR #1289 / `codex/rag-reliability-final` | `d49af8acb42ccedbfe6c8b3f03d30769ba906ec7` | Bugbot review (exact head) | APPROVE. No high-confidence P0–P2. Application `src/`/`supabase/`/`tests/`/`scripts/` trees are unchanged vs prior APPROVE tip `a1ca6a01`; tip delta is docs evidence + clean merge from `main`. No unresolved `cursor[bot]` Bugbot threads. Residual risk: unapplied BMJ attestation migration (`#022`) correctly fails closed with `503 source_review_v2_unavailable` until qualified hosted apply. | Focused high-risk Vitest 358 + 1502 passed; merge-tree CLEAN vs `origin/main`; no provider-backed checks; no PR comment mutations. |
| 2026-07-28 | PR #1289 / `codex/rag-reliability-final` | `ab6ca036937bff1acaefbda8a5581d6d75f489b3` | Final current-main sync review | APPROVE pending fresh exact-head required checks. Merged current `origin/main` without conflict after its already-reviewed document-search and focus-path changes; no protected RAG, evaluation, migration, or RAG fixture surface changed from the live-canary application tree, and no P0-P2 finding remains. | `git merge-tree --write-tree` CLEAN before sync; branch-ledger guard and `git diff --check` PASS; prior exact application-tree `verify:pr-local` and live 36-case canary remain applicable; fresh hosted checks required. |
+| 2026-07-28 | PR #1273 / `codex/create-mobile-navigation-mockups` | `af9a957b` | Babysit recheck | Hosted CI green on prior tip; GitHub DIRTY was staleness (merge-tree CLEAN). Merged origin/main cleanly. Unresolved threads 0. Bugbot: no cursor[bot] findings. | merge origin/main; check:type-scale --strict PASS; no provider checks. |
| 2026-07-27 | PR #1275 / `codex/identify-and-fix-performance-issues-during-mode-switch` | `82c17f76` | Mode-switch prefetch review + merge restore | Prefetch mode homes on menu open; later reconciled with main per-option prefetch. Ledger restored append-only from main after mojibake rewrite. | Focused nav tests; check:branch-review-ledger; no provider checks. |
| 2026-07-27 | PR #1275 / `codex/identify-and-fix-performance-issues-during-mode-switch` | `bc5b51c2` | CodeRabbit duplicate-ledger disposition | DISPOSITIONED / not actionable as a PR product delete. Near-duplicates already exist on origin/main as non-identical historical records; check:branch-review-ledger passes on main. Removing main-owned history from a feature PR would violate append-only. | substring counts on origin/main; ledger guard PASS; no provider checks. |
| 2026-07-27 | PR #1275 / `codex/identify-and-fix-performance-issues-during-mode-switch` | `191707ee` | CodeRabbit malformed-ledger-row disposition | DISPOSITIONED / not actionable on this PR. MD056 cell-count warnings on ~700-722 are identical on origin/main. Fix belongs in dedicated main ledger hygiene if desired. | cell-count scan main vs tip; check:branch-review-ledger PASS; no provider checks. |
diff --git a/docs/site-map.md b/docs/site-map.md
index 832698cbbf..f957fc9462 100644
--- a/docs/site-map.md
+++ b/docs/site-map.md
@@ -1005,6 +1005,7 @@ This file is generated by `npm run sitemap:update`. Run `npm run sitemap:check`
- `/mockups/favourites-set-navigator` - Route discovered from app directory Source: `src/app/mockups/favourites-set-navigator/page.tsx`.
- `/mockups/medication-prescribing` - Route discovered from app directory Source: `src/app/mockups/medication-prescribing/page.tsx`.
- `/mockups/mode-dropdown` - Route discovered from app directory Source: `src/app/mockups/mode-dropdown/page.tsx`.
+- `/mockups/phone-inpage-navigation` - Route discovered from app directory Source: `src/app/mockups/phone-inpage-navigation/page.tsx`.
- `/mockups/recent-searches-bottom` - Route discovered from app directory Source: `src/app/mockups/recent-searches-bottom/page.tsx`.
- `/mockups/search-heading` - Route discovered from app directory Source: `src/app/mockups/search-heading/page.tsx`.
- `/mockups/settings-search-clinical` - Route discovered from app directory Source: `src/app/mockups/settings-search-clinical/page.tsx`.
diff --git a/src/app/mockups/mockups-layout-client.tsx b/src/app/mockups/mockups-layout-client.tsx
index f16044ffe6..a30dc493b3 100644
--- a/src/app/mockups/mockups-layout-client.tsx
+++ b/src/app/mockups/mockups-layout-client.tsx
@@ -15,6 +15,7 @@ export function MockupsLayoutClient({ children }: { children: ReactNode }) {
const isStandaloneDocumentFlow = pathname === "/mockups/document-search";
const isUniversalSearchRedesignMockup = pathname === "/mockups/universal-search-redesign";
const isSearchHeadingMockup = pathname === "/mockups/search-heading";
+ const isPhoneInPageNavigationMockup = pathname === "/mockups/phone-inpage-navigation";
// The calculators search page owns its own search input (top on desktop, docked
// at the bottom on phones), so the shared universal composer is suppressed here
// to avoid a second, floating search bar.
@@ -37,9 +38,10 @@ export function MockupsLayoutClient({ children }: { children: ReactNode }) {
!isStandaloneDocumentFlow &&
!isDocumentTopNavigationMockup &&
!isUniversalSearchRedesignMockup &&
- !isCalculatorsSearchPageMockup
+ !isCalculatorsSearchPageMockup &&
+ !isPhoneInPageNavigationMockup
}
- chromeVisible={!isSourceOverlayRedesignMockup && !isSearchHeadingMockup}
+ chromeVisible={!isSourceOverlayRedesignMockup && !isSearchHeadingMockup && !isPhoneInPageNavigationMockup}
>
{children}
diff --git a/src/app/mockups/phone-inpage-navigation/page.tsx b/src/app/mockups/phone-inpage-navigation/page.tsx
new file mode 100644
index 0000000000..1e13fe63d6
--- /dev/null
+++ b/src/app/mockups/phone-inpage-navigation/page.tsx
@@ -0,0 +1,507 @@
+"use client";
+
+import {
+ Activity,
+ Bookmark,
+ Check,
+ ChevronDown,
+ ChevronRight,
+ Clock3,
+ Compass,
+ FileText,
+ HeartPulse,
+ Home,
+ Menu,
+ MoreHorizontal,
+ Search,
+ Sparkles,
+} from "lucide-react";
+import { useState } from "react";
+
+const sections = [
+ { label: "Overview", icon: Home },
+ { label: "Why matched", icon: Sparkles },
+ { label: "Safety", icon: HeartPulse },
+ { label: "Best fit", icon: Compass },
+ { label: "Protocol", icon: Activity },
+ { label: "Patient sheet", icon: FileText },
+] as const;
+
+type SectionLabel = (typeof sections)[number]["label"];
+
+function PhoneHeader() {
+ return (
+ <>
+
+ 11:41
+
+ ▮▮▮
+ ◒
+ 77
+
+
+
+ undefined}
+ >
+
+
+ undefined}
+ >
+
+
+
+ Therapy
+
+
+ undefined}
+ >
+
+
+
+ >
+ );
+}
+
+function ClinicalContent({ active }: { active: SectionLabel }) {
+ const contentMap: Record<
+ SectionLabel,
+ Array<{ icon: typeof Sparkles; label: string; copy: string; variant: "default" | "warning" | "muted" }>
+ > = {
+ Overview: [
+ {
+ icon: Sparkles,
+ label: "Why matched",
+ copy: "Best for adults receiving continuing support after an episode, with a clear focus on triggers and practical problem-solving.",
+ variant: "default",
+ },
+ {
+ icon: HeartPulse,
+ label: "Safety first",
+ copy: "Assess immediate risk, capacity, safeguarding, psychosis, mania and current supports before continuing.",
+ variant: "warning",
+ },
+ {
+ icon: Clock3,
+ label: "Best fit",
+ copy: "Self-harm urges, emotional dysregulation, hopelessness and identifiable high-risk moments.",
+ variant: "muted",
+ },
+ ],
+ "Why matched": [
+ {
+ icon: Compass,
+ label: "Evidence base",
+ copy: "CBT shows strong outcomes in relapse prevention for adults with recurrent depression, particularly when combined with medication.",
+ variant: "default",
+ },
+ {
+ icon: Activity,
+ label: "Key features",
+ copy: "Structured sessions targeting negative thought patterns, behavioral activation, and practical skills for managing early warning signs.",
+ variant: "warning",
+ },
+ {
+ icon: Check,
+ label: "Match criteria",
+ copy: "Patient history indicates recurrent episodes, willingness to engage in homework, and capacity for collaborative goal-setting.",
+ variant: "muted",
+ },
+ ],
+ Safety: [
+ {
+ icon: HeartPulse,
+ label: "Risk assessment",
+ copy: "Check for active suicidal ideation, self-harm urges, acute psychosis, and safeguarding concerns before proceeding.",
+ variant: "default",
+ },
+ {
+ icon: Activity,
+ label: "Capacity check",
+ copy: "Confirm patient can consent to treatment, understands the approach, and has support systems in place.",
+ variant: "warning",
+ },
+ {
+ icon: Bookmark,
+ label: "Crisis plan",
+ copy: "Ensure patient has access to emergency contacts, crisis services, and knows when to seek immediate help.",
+ variant: "muted",
+ },
+ ],
+ "Best fit": [
+ {
+ icon: Compass,
+ label: "Core targets",
+ copy: "Rumination, avoidance behaviors, disrupted routines, social withdrawal, and negative thought cycles.",
+ variant: "default",
+ },
+ {
+ icon: Sparkles,
+ label: "Strengths needed",
+ copy: "Ability to identify thoughts, willingness to try new behaviors, and capacity to engage between sessions.",
+ variant: "warning",
+ },
+ {
+ icon: Clock3,
+ label: "Typical duration",
+ copy: "12-16 sessions over 3-4 months, with possible booster sessions for relapse prevention.",
+ variant: "muted",
+ },
+ ],
+ Protocol: [
+ {
+ icon: Activity,
+ label: "Session structure",
+ copy: "Weekly 50-minute sessions: agenda setting, homework review, new skill teaching, and between-session task planning.",
+ variant: "default",
+ },
+ {
+ icon: FileText,
+ label: "Core components",
+ copy: "Psychoeducation, thought records, behavioral experiments, activity scheduling, and relapse prevention planning.",
+ variant: "warning",
+ },
+ {
+ icon: Check,
+ label: "Progress tracking",
+ copy: "Regular monitoring with validated measures (PHQ-9, GAD-7) and collaborative review of therapy goals.",
+ variant: "muted",
+ },
+ ],
+ "Patient sheet": [
+ {
+ icon: FileText,
+ label: "What to expect",
+ copy: "Active collaboration, homework between sessions, focus on current problems, and learning practical skills you can use long-term.",
+ variant: "default",
+ },
+ {
+ icon: Home,
+ label: "Your role",
+ copy: "Bring specific examples, try new strategies between sessions, give feedback on what works, and practice skills regularly.",
+ variant: "warning",
+ },
+ {
+ icon: Bookmark,
+ label: "Resources",
+ copy: "Session handouts, thought record templates, activity logs, and a personalized relapse prevention plan.",
+ variant: "muted",
+ },
+ ],
+ };
+
+ const blocks = contentMap[active];
+
+ return (
+
+
+
+
CBT · clinical guide
+
{active}
+
+
+ 8 min
+
+
+
+
+
+ {(() => {
+ const Icon = blocks[0].icon;
+ return ;
+ })()}{" "}
+ {blocks[0].label}
+
+
{blocks[0].copy}
+
+
+
+ {(() => {
+ const Icon = blocks[1].icon;
+ return ;
+ })()}{" "}
+ {blocks[1].label}
+
+
{blocks[1].copy}
+
+
+
+ {(() => {
+ const Icon = blocks[2].icon;
+ return ;
+ })()}{" "}
+ {blocks[2].label}
+
+
{blocks[2].copy}
+
+
+
undefined}
+ className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-[#55d5d9] text-sm font-bold text-[#073438]"
+ >
+ Open clinical record
+
+
+ );
+}
+
+function PhoneFrame({ children, title, kicker }: { children: React.ReactNode; title: string; kicker: string }) {
+ return (
+
+
+
+
+ );
+}
+
+function ScrollRail() {
+ const [active, setActive] = useState("Why matched");
+ return (
+ <>
+
+
+ {sections.map(({ label, icon: Icon }) => (
+ setActive(label)}
+ aria-current={active === label ? "page" : undefined}
+ className={`flex min-h-11 shrink-0 snap-start items-center gap-2 rounded-full px-3.5 text-xs font-semibold transition ${active === label ? "bg-[#173b3e] text-[#6de1e4] ring-1 ring-[#34787d]" : "text-[#9ca6a4]"}`}
+ >
+
+ {label}
+
+ ))}
+
+
+
+
+ >
+ );
+}
+
+function DropdownNavigator() {
+ const [active, setActive] = useState("Safety");
+ const [open, setOpen] = useState(true);
+ const ActiveIcon = sections.find((item) => item.label === active)?.icon ?? Home;
+ return (
+ <>
+
+
setOpen((value) => !value)}
+ className="flex min-h-12 w-full items-center gap-3 rounded-2xl border border-[#335053] bg-[#152224] px-3 text-left"
+ >
+
+
+
+
+ Jump to section
+ {active}
+
+
+
+ {open ? (
+
+
On this page
+
+ {sections.map(({ label, icon: Icon }) => (
+ {
+ setActive(label);
+ setOpen(false);
+ }}
+ className={`flex min-h-12 items-center gap-2 rounded-xl px-2.5 text-left text-xs font-semibold ${active === label ? "bg-[#173b3e] text-[#6de1e4]" : "text-[#b3bcba] hover:bg-white/5"}`}
+ >
+
+ {label}
+ {active === label ? : null}
+
+ ))}
+
+
+ ) : null}
+
+
+ >
+ );
+}
+
+function PriorityDock() {
+ const [active, setActive] = useState("Overview");
+ const [more, setMore] = useState(false);
+ const primary = sections.slice(0, 4);
+ const overflow = sections.slice(4);
+ const overflowActive = overflow.some(({ label }) => label === active);
+ return (
+ <>
+
+ {primary.map(({ label, icon: Icon }) => (
+ {
+ setActive(label);
+ setMore(false);
+ }}
+ aria-current={active === label ? "page" : undefined}
+ className={`flex min-h-[52px] flex-col items-center justify-center gap-1 rounded-xl text-4xs font-semibold ${active === label ? "bg-[#173b3e] text-[#6de1e4]" : "text-[#8f9997]"}`}
+ >
+
+ {label === "Why matched" ? "Matched" : label}
+
+ ))}
+ setMore((value) => !value)}
+ aria-expanded={more}
+ aria-current={overflowActive ? "page" : undefined}
+ className={`flex min-h-[52px] flex-col items-center justify-center gap-1 rounded-xl text-4xs font-semibold ${more || overflowActive ? "bg-[#173b3e] text-[#6de1e4]" : "text-[#8f9997]"}`}
+ >
+
+ More
+
+ {more ? (
+
+ {overflow.map(({ label, icon: Icon }) => (
+ {
+ setActive(label);
+ setMore(false);
+ }}
+ aria-current={active === label ? "page" : undefined}
+ className={`flex min-h-12 w-full items-center gap-3 rounded-xl px-3 text-xs font-semibold ${active === label ? "bg-[#173b3e] text-[#6de1e4]" : "text-[#c0c8c6] hover:bg-white/5"}`}
+ >
+
+ {label}
+
+ ))}
+
+ ) : null}
+
+
+ >
+ );
+}
+
+function ProgressNavigator() {
+ const [index, setIndex] = useState(1);
+ const active = sections[index];
+ const ActiveIcon = active.icon;
+ return (
+ <>
+
+
+
setIndex((value) => Math.max(0, value - 1))}
+ disabled={index === 0}
+ aria-label="Previous section"
+ className="grid size-11 shrink-0 place-items-center rounded-full border border-[#30393b] text-[#9aa5a3] disabled:opacity-30"
+ >
+
+
+
setIndex((value) => Math.min(sections.length - 1, value + 1))}
+ disabled={index === sections.length - 1}
+ className="min-w-0 flex-1 text-left disabled:opacity-50"
+ >
+
+
+ Section {index + 1} of {sections.length}
+
+ {Math.round(((index + 1) / sections.length) * 100)}%
+
+
+
+ {active.label}
+
+
+ {sections.map((section, itemIndex) => (
+
+ ))}
+
+
+
setIndex((value) => Math.min(sections.length - 1, value + 1))}
+ disabled={index === sections.length - 1}
+ aria-label="Next section"
+ className="grid size-11 shrink-0 place-items-center rounded-full bg-[#55d5d9] text-[#073438] disabled:opacity-30"
+ >
+
+
+
+
+
+ >
+ );
+}
+
+export default function PhoneInPageNavigationMockup() {
+ return (
+
+
+
+ Mobile navigation study · 04 directions
+
+
+ In-page navigation, refined for one thumb.
+
+
+ Four anchored treatments shown in realistic context. Each sits immediately below the Therapy header, preserves
+ content width and uses a minimum 44px interaction target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clinical KB · design exploration
+
+ Phone-first, 390px canvas
+
+
+
+ );
+}