diff --git a/docs/redesign/09-ui-primitives-recipes.md b/docs/redesign/09-ui-primitives-recipes.md index c90e14451..31f7691d0 100644 --- a/docs/redesign/09-ui-primitives-recipes.md +++ b/docs/redesign/09-ui-primitives-recipes.md @@ -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 @@ -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). diff --git a/src/components/ClinicalDashboard.tsx b/src/components/ClinicalDashboard.tsx index 83046a528..8e16a0ceb 100644 --- a/src/components/ClinicalDashboard.tsx +++ b/src/components/ClinicalDashboard.tsx @@ -484,7 +484,7 @@ function WhyThisMatchedPanel({ sources }: { sources: SearchResult[] }) { return (
- + @@ -679,7 +679,7 @@ function VisualEvidenceStrip({ )} {!hasStructuredTable ? : null} - + Open source @@ -1282,7 +1282,7 @@ function RelatedDocumentsPanel({
{documentDisplayTitle(document)} @@ -1295,7 +1295,7 @@ function RelatedDocumentsPanel({ @@ -2642,7 +2642,7 @@ function DocumentDrawer({
{documentDisplayTitle(document)} @@ -2681,7 +2681,7 @@ function DocumentDrawer({ 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)]", @@ -2983,7 +2983,7 @@ function SettingsSummaryTile({ : "border-[color:var(--border-lux)] bg-[color:var(--surface)]", )} > -
+
{answerProgress} @@ -5589,7 +5589,12 @@ export function ClinicalDashboard({ 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([]); + }} desktopComposerSlotId={desktopHomeComposerSlotId} onSuggestedSearch={(nextQuery) => { setQuery(nextQuery); @@ -5657,7 +5662,7 @@ export function ClinicalDashboard({ loading={loading} documentCount={indexedDocumentTotal} recentDocuments={documents} - realDataReady={canRunSearch} + realDataReady={searchMode === "services" || searchMode === "forms" ? true : canRunSearch} authUnavailable={!clientDemoMode && !canUsePrivateApis} apiUnavailable={apiUnavailable} setupWarning={setupWarning} diff --git a/src/components/DocumentViewer.tsx b/src/components/DocumentViewer.tsx index c44eaca00..3de3f8dad 100644 --- a/src/components/DocumentViewer.tsx +++ b/src/components/DocumentViewer.tsx @@ -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")} > -
+
diff --git a/src/components/clinical-dashboard/differentials-home.tsx b/src/components/clinical-dashboard/differentials-home.tsx index 12fa4d3fb..9fcd0a593 100644 --- a/src/components/clinical-dashboard/differentials-home.tsx +++ b/src/components/clinical-dashboard/differentials-home.tsx @@ -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)) { return ( @@ -981,7 +981,7 @@ function EvidenceGapPanel({ @@ -1171,7 +1171,7 @@ function EvidenceSummaryCard({
Open source @@ -1180,7 +1180,7 @@ function EvidenceSummaryCard({