Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
941fe19
fix(ui): design-review fixes for differentials, services, favourites
BigSimmo Jul 2, 2026
b60fd61
fix(ui): design-review fixes for service detail, search header, sideb…
BigSimmo Jul 2, 2026
f5cb693
feat(search): give services mode its own search/result kind
BigSimmo Jul 2, 2026
e0435a8
fix(build): avoid Node 24 WasmHash worker crash in webpack production…
BigSimmo Jul 2, 2026
d327732
chore: add llms.txt AI-crawler manifest
BigSimmo Jul 2, 2026
2cf4764
feat(mockups): add tools-page command-center/split-pane/workflow-boar…
BigSimmo Jul 2, 2026
d605e95
fix(db): cover storage_cleanup_jobs FK, tune embedding_fields autovac…
BigSimmo Jul 2, 2026
74ba909
refactor(ui): adopt type-scale tokens and design-review polish across…
BigSimmo Jul 2, 2026
46b433b
docs(redesign): add token-adoption audit and design-review prompt
BigSimmo Jul 2, 2026
6bbf3f2
feat(mockups): add favourites and task-directory concepts
BigSimmo Jul 2, 2026
dae41bb
fix(review): address tools mockup PR comments
BigSimmo Jul 3, 2026
55e0345
fix(review): address remaining tools mockup feedback
BigSimmo Jul 3, 2026
ca0c1d5
fix(review): address services and schema comments
BigSimmo Jul 3, 2026
21bfca1
Changes before error encountered
Copilot Jul 3, 2026
4e424de
Merge remote-tracking branch 'origin/main' into feature/tools-page-mo…
BigSimmo Jul 3, 2026
a90245b
merge: begin resolving conflicts with origin/main
Copilot Jul 3, 2026
c1e4944
Merge remote-tracking branch 'origin/feature/tools-page-mockups' into…
BigSimmo Jul 3, 2026
7498351
fix(merge): resolve conflict markers left in merge commit
Copilot Jul 3, 2026
de5c9fe
Merge remote-tracking branch 'origin/feature/tools-page-mockups' into…
BigSimmo Jul 3, 2026
952c2e7
style: apply prettier formatting
BigSimmo Jul 3, 2026
2ca4685
fix: restore ui smoke mode contracts
BigSimmo Jul 3, 2026
5b62320
fix(review): address latest PR 215 comments
BigSimmo Jul 3, 2026
8b2cd7f
fix(ui): tokenize remaining tap-target magic numbers (L6)
BigSimmo Jul 3, 2026
ba7f54d
fix(ui): complete L8 recipe state contract (tap size + disabled)
BigSimmo Jul 3, 2026
2288840
Merge origin/main into feature/tools-page-mockups (resolve #225 confl…
BigSimmo Jul 3, 2026
613c10e
Merge branch 'main' into feature/tools-page-mockups
BigSimmo Jul 3, 2026
72c4a6c
Merge branch 'main' into feature/tools-page-mockups
BigSimmo Jul 3, 2026
d1131e8
fix(#225): address 4 of the review-bot findings
BigSimmo Jul 3, 2026
17365b3
fix(#225): launch top tool match directly in tools run mode
BigSimmo Jul 3, 2026
4bc919e
fix(#225): address bot follow-ups on differentials gate & doc composer
BigSimmo Jul 3, 2026
80d1399
Merge branch 'main' into feature/tools-page-mockups
BigSimmo Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions docs/redesign/09-ui-primitives-recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ Values are tokens; the target sizes follow the `-11`/`-12` spacing scale (L6).
| `primaryControl` | Primary command button | ✅ | ✅ | ✅ | ✅ | ✅ |
| `floatingControl` | Secondary / floating button | `min-h-11` | ✅ | ❌ | ✅ | ✅ |
| `toolbarButton` | Square icon button | `h-11 w-11` | ✅ | ❌ | ✅ | ✅ |
| `navPill` | Nav / segmented pill | `min-h-11` | ✅ | ❌ | ✅ | |
| `chatMicroAction` | Small chat action (copy, retry…) | `min-h-11 min-w-11` | ✅ | ❌ | ✅ | |
| `navPill` | Nav / segmented pill | `min-h-11` | ✅ | ❌ | ✅ | |
| `chatMicroAction` | Small chat action (copy, retry…) | `min-h-11 min-w-11` | ✅ | ❌ | ✅ | |
| `sourceCapsule` | Inline citation capsule | `min-h-11` | ✅ | ❌ | ✅ (`focus-ring-premium`) | ❌ |
| `chatComposerIconButton` | Composer icon button | `h-11 w-11` | ✅ | ❌ | ✅ | |
| `chatComposerIconButton` | Composer icon button | `h-11 w-11` | ✅ | ❌ | ✅ | |
| `chatSendButton` | Composer send (accent) | `h-11 w-11` | ✅ | ❌ | ✅ | ✅ |
| `sidebarItem` | Sidebar nav row | `min-h-11` | ✅ | ❌ | ✅ | |
| `sidebarItem` | Sidebar nav row | `min-h-11` | ✅ | ❌ | ✅ | |
| `sidebarToolTile` | Sidebar tool tile | `min-h-[64px]` | ✅ | ❌ | ✅ | ❌ |
| `shellChip` | Filter / mode chip | `min-h-10` ⚠️ | ✅ | ❌ | ❌ | ❌ |
| `shellChip` | Filter / mode chip | `min-h-11` | ✅ | ❌ | ❌ | ❌ |

### Form fields

Expand Down Expand Up @@ -129,14 +129,16 @@ focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]` block
the primary buttons, matching the newer recipes (`chatSendButton`, etc.).
2. **`active:translate-y-px` only on the `controlBase` family** — other buttons
(`toolbarButton`, `chatSendButton`, icon buttons) have no press feedback.
3. **`disabled:` unhandled** on `navPill`, `chatMicroAction`,
`chatComposerIconButton`, `sidebarItem` — a disabled state renders identically
to enabled.
4. **`shellChip` is `min-h-10` (40px)** — below the 44px WCAG tap minimum used
everywhere else. Promote to `min-h-11` if it's a real tap target.
3. ✅ **FIXED (2026-07-03).** Added `disabled:cursor-not-allowed disabled:opacity-50`
to `navPill`, `chatMicroAction`, `chatComposerIconButton`, `sidebarItem` — they now
honour the documented disabled state.
4. ✅ **FIXED (2026-07-03).** `shellChip` bumped `min-h-10` → `min-h-11` (40→44px) to
meet the WCAG tap minimum. (It still lacks `focus-visible` — add if it's used as a
focusable control at its call sites.)
5. **Input focus uses `focus:` not `focus-visible:`** (`fieldControl`,
`commandInput`) — intentional for text fields (focus ring should show on
pointer focus too), but noted so it isn't "corrected" to `focus-visible:`.

Gap 1 (the highest-value one) is now closed. Gaps 2–5 remain — all low-risk
polish; gap 4 (`shellChip` tap size) is the next most worth doing.
Gaps 1, 3, and 4 are now closed. Remaining: **gap 2** (`active:` press feedback
beyond the `controlBase` family — an aesthetic/design-team call) and **gap 5**
(inputs intentionally use `focus:`, no change needed).
25 changes: 15 additions & 10 deletions src/components/ClinicalDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
answerSurface,
chatMicroAction,
clinicalDivider,
clinicalNotesRow,

Check warning on line 65 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'clinicalNotesRow' is defined but never used
cn,
evidenceRow,

Check warning on line 67 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'evidenceRow' is defined but never used
EmptyState,
fieldControlPlain,
fieldControlWithIcon,
Expand Down Expand Up @@ -255,9 +255,9 @@
import {
type AnswerEvidenceMapRow,
type AnswerViewMode,
buildAnswerEvidenceMap,

Check warning on line 258 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'buildAnswerEvidenceMap' is defined but never used
buildClinicalOutputSections,

Check warning on line 259 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'buildClinicalOutputSections' is defined but never used
buildHighYieldClinicalOutputSections,

Check warning on line 260 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'buildHighYieldClinicalOutputSections' is defined but never used
shouldPollForUpdates,
} from "@/lib/ward-output";

Expand Down Expand Up @@ -478,13 +478,13 @@
return navigationHashes.includes(hash as (typeof navigationHashes)[number]) ? hash : "#search";
}

function WhyThisMatchedPanel({ sources }: { sources: SearchResult[] }) {

Check warning on line 481 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'WhyThisMatchedPanel' is defined but never used
const visibleSources = sources.slice(0, 3);
if (visibleSources.length === 0) return null;

return (
<details data-testid="why-this-matched" className={cn("group rounded-lg", panelSubtle)}>
<summary className="flex min-h-[48px] cursor-pointer list-none items-center justify-between gap-3 px-3 py-2">
<summary className="flex min-h-12 cursor-pointer list-none items-center justify-between gap-3 px-3 py-2">
<span className="flex min-w-0 items-center gap-2">
<span className={cn(iconTilePremium, "h-8 w-8")}>
<Search className="h-4 w-4" />
Expand Down Expand Up @@ -679,7 +679,7 @@
</span>
)}
{!hasStructuredTable ? <QueryCoverageChips relevance={item.relevance} limit={2} /> : null}
<Link href={item.viewer_href} className={cn(floatingControl, "min-h-[44px] px-4 text-xs")}>
<Link href={item.viewer_href} className={cn(floatingControl, "min-h-11 px-4 text-xs")}>
<ExternalLink className="h-4 w-4" />
Open source
</Link>
Expand Down Expand Up @@ -1052,7 +1052,7 @@
function MobileEvidenceTabPanel({
tab,
renderModel,
query,

Check warning on line 1055 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'query' is defined but never used
visualEvidence,
answerEvidenceMapRows,
copiedQuotes,
Expand Down Expand Up @@ -1125,7 +1125,7 @@
return <EvidenceGapsPanel warnings={renderModel.warnings} />;
}

function UnifiedEvidenceDrawerContent({

Check warning on line 1128 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'UnifiedEvidenceDrawerContent' is defined but never used
answer,
renderModel,
query,
Expand Down Expand Up @@ -1282,7 +1282,7 @@
<div className="min-w-0">
<Link
href={`/documents/${document.document_id}?page=${document.best_pages[0] ?? 1}&chunk=${document.best_chunk_ids[0] ?? ""}`}
className="inline-flex min-h-[44px] items-center text-sm font-semibold text-[color:var(--text)] transition hover:text-[color:var(--primary)]"
className="inline-flex min-h-11 items-center text-sm font-semibold text-[color:var(--text)] transition hover:text-[color:var(--primary)]"
>
<span className="line-clamp-2">{documentDisplayTitle(document)}</span>
</Link>
Expand All @@ -1295,7 +1295,7 @@
<button
type="button"
onClick={() => onScopeDocument(document.document_id)}
className={cn(floatingControl, "min-h-[44px] px-3 text-xs")}
className={cn(floatingControl, "min-h-11 px-3 text-xs")}
>
Scope
</button>
Expand All @@ -1318,8 +1318,8 @@
query,
safeAnswerText,
bestSource,
currentRelevance,

Check warning on line 1321 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'currentRelevance' is defined but never used
queryMode,

Check warning on line 1322 in src/components/ClinicalDashboard.tsx

View workflow job for this annotation

GitHub Actions / verify

'queryMode' is defined but never used
sourceGovernanceWarnings,
sourceSummary,
renderModel,
Expand Down Expand Up @@ -2642,7 +2642,7 @@
<div className="min-w-0">
<Link
href={`/documents/${document.id}`}
className="flex min-h-[44px] min-w-0 items-center gap-2 text-sm font-semibold text-[color:var(--text)] transition hover:text-[color:var(--primary)]"
className="flex min-h-11 min-w-0 items-center gap-2 text-sm font-semibold text-[color:var(--text)] transition hover:text-[color:var(--primary)]"
>
<span className="truncate">{documentDisplayTitle(document)}</span>
<ExternalLink className="h-3.5 w-3.5 shrink-0 text-[color:var(--text-soft)]" />
Expand Down Expand Up @@ -2681,7 +2681,7 @@
type="button"
onClick={() => onToggleScope(document.id)}
className={cn(
"inline-flex min-h-[44px] items-center rounded-lg border px-3 text-xs font-semibold transition",
"inline-flex min-h-11 items-center rounded-lg border px-3 text-xs font-semibold transition",
selected
? "border-[color:var(--primary)]/35 bg-[color:var(--primary-soft)] text-[color:var(--primary)]"
: "border-[color:var(--border)] bg-[color:var(--surface)] text-[color:var(--text-muted)] hover:bg-[color:var(--surface-subtle)]",
Expand Down Expand Up @@ -2983,7 +2983,7 @@
: "border-[color:var(--border-lux)] bg-[color:var(--surface)]",
)}
>
<div className="flex min-w-0 flex-col items-center justify-center gap-1 text-center lg:min-h-[44px] lg:flex-row lg:justify-start lg:gap-2.5 lg:text-left">
<div className="flex min-w-0 flex-col items-center justify-center gap-1 text-center lg:min-h-11 lg:flex-row lg:justify-start lg:gap-2.5 lg:text-left">
<span
className={cn(
"grid h-8 w-8 shrink-0 place-items-center rounded-xl border shadow-[var(--shadow-inset)] lg:rounded-lg",
Expand Down Expand Up @@ -5573,7 +5573,7 @@
{loading && answerProgress && searchMode !== "prescribing" && (
<div
role="status"
className="flex min-h-[44px] items-center gap-2 rounded-lg border border-[color:var(--primary)]/20 bg-[color:var(--primary-soft)] px-3 text-sm font-medium text-[color:var(--text-heading)]"
className="flex min-h-11 items-center gap-2 rounded-lg border border-[color:var(--primary)]/20 bg-[color:var(--primary-soft)] px-3 text-sm font-medium text-[color:var(--text-heading)]"
>
<Loader2 className="h-4 w-4 shrink-0 animate-spin text-[color:var(--primary)]" />
<span className="min-w-0 truncate">{answerProgress}</span>
Expand All @@ -5589,7 +5589,12 @@
authUnavailable={!clientDemoMode && !canUsePrivateApis}
apiUnavailable={apiUnavailable}
setupWarning={setupWarning}
onQueryChange={setQuery}
onQueryChange={(nextQuery) => {
setQuery(nextQuery);
// Clear stale evidence so an edited (but unsubmitted) query
// doesn't keep rendering the previous search's rankings.
setDocumentMatches([]);
Comment on lines +5592 to +5596

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear stale differential matches from the active composer

Fresh evidence in this revision is that stale evidence is cleared only through the DifferentialsHome callback, but the visible/portaled composer is owned by MasterSearchHeader and still receives onQueryChange={setQuery}. After a successful differential search, editing that composer on the differential home page leaves the old documentMatches populated, so hasEvidenceMatches remains true and SearchResultsView can render the previous query's rankings under the new unsubmitted text; clear matches in the header query path or key matches to the submitted query.

Useful? React with 👍 / 👎.

}}
desktopComposerSlotId={desktopHomeComposerSlotId}
onSuggestedSearch={(nextQuery) => {
setQuery(nextQuery);
Expand Down Expand Up @@ -5657,7 +5662,7 @@
loading={loading}
documentCount={indexedDocumentTotal}
recentDocuments={documents}
realDataReady={canRunSearch}
realDataReady={searchMode === "services" || searchMode === "forms" ? true : canRunSearch}
authUnavailable={!clientDemoMode && !canUsePrivateApis}
apiUnavailable={apiUnavailable}
setupWarning={setupWarning}
Expand Down
4 changes: 2 additions & 2 deletions src/components/DocumentViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2362,7 +2362,7 @@ export function DocumentViewer({
tabIndex={-1}
className={cn(appBackdrop, "min-h-[100dvh] overflow-x-clip text-[color:var(--text)] focus:outline-none")}
>
<header className="edge-glass-header sticky top-0 z-30 border-b border-[color:var(--border)] py-2 pt-[max(0.5rem,env(safe-area-inset-top))] shadow-[var(--shadow-tight)] backdrop-blur-xl">
<header className="edge-glass-header z-30 border-b border-[color:var(--border)] py-2 pt-[max(0.5rem,env(safe-area-inset-top))] shadow-[var(--shadow-tight)] backdrop-blur-xl">
<div className="mx-auto flex h-12 min-w-0 max-w-7xl items-center gap-2">
<Link
href={documentHomeHref}
Expand Down Expand Up @@ -2952,7 +2952,7 @@ export function DocumentViewer({
event.preventDefault();
if (canSummarizeDocument) void summarize();
}}
className="floating-composer-edge fixed z-40 mx-auto flex min-h-[56px] max-w-3xl items-center gap-2 rounded-full border border-[color:var(--border-lux)] bg-[color:var(--surface-lux)] px-2 shadow-[var(--shadow-lux)] ring-1 ring-white/35 backdrop-blur-xl"
className="floating-composer-edge dashboard-composer-edge fixed z-40 mx-auto flex min-h-[56px] max-w-3xl items-center gap-2 rounded-full border border-[color:var(--border-lux)] bg-[color:var(--surface-lux)] px-2 shadow-[var(--shadow-lux)] ring-1 ring-white/35 backdrop-blur-xl"
>
<button
type="button"
Expand Down
15 changes: 14 additions & 1 deletion src/components/applications-launcher-page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import {
BookOpen,
Brain,
Expand Down Expand Up @@ -812,6 +813,7 @@ export function ApplicationsLauncherWorkspace({
const [pinnedIds, setPinnedIds] = useState(seedPinnedIds);
const [mobileDetailOpen, setMobileDetailOpen] = useState(false);
const [desktopViewport, setDesktopViewport] = useState(false);
const router = useRouter();
const isDashboardTools = variant === "dashboard-tools";
const copy = isDashboardTools ? dashboardToolsLauncherCopy : standaloneLauncherCopy;
const query = controlledQuery ?? uncontrolledQuery;
Expand Down Expand Up @@ -870,7 +872,18 @@ export function ApplicationsLauncherWorkspace({
function submitFooterSearch(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const firstMatch = filteredApps[0];
if (firstMatch) selectApplication(firstMatch.id);
if (!firstMatch) return;
// Dashboard-tools run mode hides the detail panel on desktop, so selecting a
// match has no visible effect — launch the top match directly instead.
if (isDashboardTools && !showDetailPanel && desktopViewport) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Move tools run-mode launch handling to the dashboard submit path

Fresh evidence in this revision is that the new launch behavior is added to submitFooterSearch, but that handler is only attached to the standalone launcher form in the non-dashboard branch; the dashboard-tools view renders the isDashboardTools branch and uses the shared MasterSearchHeader submit path instead. In /?mode=tools&...&run=1 on desktop, where the detail panel is hidden, pressing Enter still only runs executeSearch for tools and shows the filter notice rather than launching the top match, so this branch never fixes the run-mode submit interaction.

Useful? React with 👍 / 👎.

if (firstMatch.external) {
window.open(firstMatch.href, "_blank", "noopener,noreferrer");
} else {
router.push(firstMatch.href);
}
return;
}
selectApplication(firstMatch.id);
}

const workspace = (
Expand Down
2 changes: 1 addition & 1 deletion src/components/clinical-dashboard/answer-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const SourceImage = memo(function SourceImage({
<button
type="button"
onClick={retryImage}
className="mt-3 inline-flex min-h-[44px] items-center rounded-lg border border-[color:var(--warning)]/30 bg-[color:var(--surface)] px-3 text-[color:var(--warning)]"
className="mt-3 inline-flex min-h-11 items-center rounded-lg border border-[color:var(--warning)]/30 bg-[color:var(--surface)] px-3 text-[color:var(--warning)]"
>
Retry image
</button>
Expand Down
6 changes: 5 additions & 1 deletion src/components/clinical-dashboard/differentials-home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,11 @@ export function DifferentialsHome({
runSearch(action.query);
}

if (trimmedQuery) {
// Only surface ranked results once an actual search has run (loading or
// evidence matches present) — not on every keystroke, and not for a query
// whose source search returned nothing. Otherwise the hard-coded demo
// rankings render as if relevant to any typed text.
if (trimmedQuery && (loading || hasEvidenceMatches)) {
Comment thread
BigSimmo marked this conversation as resolved.
return (
<SearchResultsView
query={trimmedQuery}
Expand Down
12 changes: 6 additions & 6 deletions src/components/clinical-dashboard/evidence-panels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ export function SafetyFindingsPanel({ findings }: { findings: ReturnType<typeof
href={finding.href}
className={cn(
raisedCard,
"inline-flex min-h-[44px] items-center gap-1.5 px-3 text-xs font-semibold text-[color:var(--primary)]",
"inline-flex min-h-11 items-center gap-1.5 px-3 text-xs font-semibold text-[color:var(--primary)]",
)}
aria-label={`Open source ${formatSafetyFindingLabel(finding)}`}
>
Expand Down Expand Up @@ -981,7 +981,7 @@ function EvidenceGapPanel({
<Link
key={source.id}
href={sourceResultHref(source)}
className={cn(floatingControl, "min-h-[44px] px-3 text-xs")}
className={cn(floatingControl, "min-h-11 px-3 text-xs")}
aria-label={`Open closest source ${cleanDisplayTitle(source.title)}`}
>
<ExternalLink className="h-4 w-4" />
Expand Down Expand Up @@ -1171,7 +1171,7 @@ function EvidenceSummaryCard({
<div className="mt-3 flex flex-wrap gap-2">
<Link
href={bestSource.viewer_href}
className={cn(primaryControl, "min-h-[44px] px-3 text-xs")}
className={cn(primaryControl, "min-h-11 px-3 text-xs")}
aria-label={`Open ${sourceLabel.toLowerCase()}: ${formatCitationLabel(bestSource)}`}
>
Open source
Expand All @@ -1180,7 +1180,7 @@ function EvidenceSummaryCard({
<button
type="button"
onClick={() => onScopeDocument(bestSource.document_id)}
className={cn(floatingControl, "min-h-[44px] px-3 text-xs")}
className={cn(floatingControl, "min-h-11 px-3 text-xs")}
aria-label={`Search only ${bestSource.title}`}
>
<Filter className="h-4 w-4" />
Expand Down Expand Up @@ -1600,7 +1600,7 @@ function RenderModelSourceList({
<article key={`${source.id}:${source.href}`} className={cn(sourceCard, "overflow-hidden p-0")}>
<Link
href={source.href}
className="block min-h-[44px] px-3 py-3 transition hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]"
className="block min-h-11 px-3 py-3 transition hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]"
aria-label={openLabel}
>
<div className="grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3">
Expand Down Expand Up @@ -1784,7 +1784,7 @@ export function EvidenceMapTable({ rows }: { rows: AnswerEvidenceMapRow[] }) {
data-testid="evidence-map-open-source"
className={cn(
sourceCard,
"grid min-h-[44px] grid-cols-[minmax(0,1fr)_auto] items-center gap-3 p-3 text-sm transition hover:border-[color:var(--primary)]/45 hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]",
"grid min-h-11 grid-cols-[minmax(0,1fr)_auto] items-center gap-3 p-3 text-sm transition hover:border-[color:var(--primary)]/45 hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]",
)}
aria-label={`Open source for ${row.section}: ${row.bestSourceLabel}`}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,17 @@ function MobileComparison({ candidates }: { candidates: CandidateView[] }) {
<MobileCandidateCard key={candidate.record.slug} candidate={candidate} index={index} />
))}
</div>
<div className="fixed inset-x-0 bottom-0 z-30 rounded-t-xl border-t border-[color:var(--clinical-accent-border)] bg-[color:var(--clinical-accent)] p-1.5 pb-[calc(0.4rem+env(safe-area-inset-bottom))] shadow-[var(--shadow-elevated)]">
<div className="fixed inset-x-0 bottom-0 z-30 grid grid-cols-2 gap-2 rounded-t-xl border-t border-[color:var(--clinical-accent-border)] bg-[color:var(--clinical-accent)] p-1.5 pb-[calc(0.4rem+env(safe-area-inset-bottom))] shadow-[var(--shadow-elevated)]">
<Link
href="/differentials/presentations"
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[color:var(--clinical-accent-contrast)]/40 bg-[color:var(--clinical-accent-contrast)]/5 px-2 text-xs font-extrabold text-[color:var(--clinical-accent-contrast)] shadow-[var(--shadow-inset)] sm:text-sm"
>
<GitCompareArrows className="h-4 w-4" aria-hidden />
Compare ({acuteConfusionPresentationWorkflow.selectedCount} selected)
</Link>
<CopyAfterReviewButton
text={comparisonCopy(candidates)}
className="w-full min-h-11 bg-[color:var(--surface)] px-2 !text-sm !text-[color:var(--clinical-accent)] hover:bg-[color:var(--surface-raised)]"
className="min-h-11 bg-[color:var(--surface)] px-2 !text-xs !text-[color:var(--clinical-accent)] hover:bg-[color:var(--surface-raised)] sm:!text-sm"
/>
</div>
</section>
Expand Down
Loading