- Question: - {query} -
- ) : null} +diff --git a/docs/design-system/COMPONENTS.md b/docs/design-system/COMPONENTS.md
index 4dae4b2c88..860e53ed04 100644
--- a/docs/design-system/COMPONENTS.md
+++ b/docs/design-system/COMPONENTS.md
@@ -930,14 +930,14 @@ tests to run.
Registered public components: 53
Components with a valid design-sync preview: 53
-Components with product imports: 27
+Components with product imports: 29
This generated snapshot is a local source-derived inventory. It does not assert remote design-project publication.
| Component | Family | Built | Locally registered | Observed v2 mount | Proof declared | Baseline committed | Product imports |
| ------------------------ | -------- | ----- | ------------------ | --------------------- | -------------- | ------------------ | --------------: |
| `AccessibleTable` | source | yes | yes | inherited-global-root | yes | no | 4 |
-| `AnswerCard` | answer | yes | yes | no | yes | no | 0 |
+| `AnswerCard` | answer | yes | yes | inherited-global-root | yes | no | 1 |
| `AnswerFooter` | answer | yes | yes | no | yes | no | 0 |
| `AsyncButton` | controls | yes | yes | inherited-global-root | yes | no | 4 |
| `Breadcrumb` | layout | yes | yes | inherited-global-root | yes | no | 1 |
@@ -947,7 +947,7 @@ This generated snapshot is a local source-derived inventory. It does not assert
| `Citation` | source | yes | yes | no | yes | no | 0 |
| `CitationList` | source | yes | yes | no | yes | no | 0 |
| `ConfirmDialog` | layout | yes | yes | no | yes | no | 0 |
-| `DateDisplay` | source | yes | yes | inherited-global-root | yes | no | 2 |
+| `DateDisplay` | source | yes | yes | inherited-global-root | yes | no | 3 |
| `Disclosure` | layout | yes | yes | no | yes | no | 0 |
| `DisclosureGroup` | layout | yes | yes | no | yes | no | 0 |
| `DoseLine` | answer | yes | yes | no | yes | no | 0 |
@@ -962,13 +962,13 @@ This generated snapshot is a local source-derived inventory. It does not assert
| `InlineNotice` | feedback | yes | yes | inherited-global-root | yes | no | 6 |
| `LinkAction` | controls | yes | yes | no | yes | no | 0 |
| `LoadingPanel` | feedback | yes | yes | inherited-global-root | yes | no | 7 |
-| `MissingValue` | feedback | yes | yes | inherited-global-root | yes | no | 2 |
+| `MissingValue` | feedback | yes | yes | inherited-global-root | yes | no | 3 |
| `OverlayRoot` | layout | yes | yes | inherited-global-root | yes | no | 1 |
| `PageHeader` | layout | yes | yes | inherited-global-root | yes | no | 2 |
| `Pagination` | controls | yes | yes | no | yes | no | 0 |
| `PanelHeading` | layout | yes | yes | inherited-global-root | yes | no | 2 |
| `Progress` | feedback | yes | yes | no | yes | no | 0 |
-| `Quantity` | answer | yes | yes | no | yes | no | 0 |
+| `Quantity` | answer | yes | yes | inherited-global-root | yes | no | 1 |
| `RadioGroup` | controls | yes | yes | no | yes | no | 0 |
| `RetrievalStateBanner` | answer | yes | yes | inherited-global-root | yes | no | 1 |
| `SafeBoldText` | layout | yes | yes | inherited-global-root | yes | no | 8 |
@@ -981,7 +981,7 @@ This generated snapshot is a local source-derived inventory. It does not assert
| `SourceProvenance` | source | yes | yes | inherited-global-root | yes | no | 1 |
| `SourceStatusBadge` | source | yes | yes | inherited-global-root | yes | no | 1 |
| `StageList` | feedback | yes | yes | no | yes | no | 0 |
-| `StatusMark` | source | yes | yes | inherited-global-root | yes | no | 1 |
+| `StatusMark` | source | yes | yes | inherited-global-root | yes | no | 2 |
| `Tabs` | controls | yes | yes | no | yes | no | 0 |
| `TextField` | controls | yes | yes | inherited-global-root | yes | no | 3 |
| `TextLink` | controls | yes | yes | no | yes | no | 0 |
diff --git a/docs/design-system/adoption-contract.json b/docs/design-system/adoption-contract.json
index 013f8767dd..fc9e4cd762 100644
--- a/docs/design-system/adoption-contract.json
+++ b/docs/design-system/adoption-contract.json
@@ -592,7 +592,7 @@
"status": "not-committed",
"files": []
},
- "sanctionedSpecialPatterns": ["AnswerResultSurface", "VerificationNotice", "RetrievalStateBanner"],
+ "sanctionedSpecialPatterns": ["AnswerResultSurface", "RetrievalStateBanner"],
"documentedDisposition": "Answers are rendered inside the shared ClinicalDashboard route rather than a standalone page route."
},
{
diff --git a/docs/design-system/adoption-manifest.json b/docs/design-system/adoption-manifest.json
index 8c2f0257ff..908dd988ce 100644
--- a/docs/design-system/adoption-manifest.json
+++ b/docs/design-system/adoption-manifest.json
@@ -131,8 +131,8 @@
"source": "src/components/ui/answer-card.tsx",
"sourceExported": true,
"entryExported": true,
- "directImportFiles": [],
- "productImportFiles": [],
+ "directImportFiles": ["src/components/clinical-dashboard/answer-result-surface.tsx"],
+ "productImportFiles": ["src/components/clinical-dashboard/answer-result-surface.tsx"],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -145,6 +145,7 @@
"tests/design-sync-contract.test.ts",
"tests/design-sync-visual-exports.test.ts",
"tests/design-system-adoption.test.ts",
+ "tests/ui-smoke.spec.ts",
"tests/ui-v2-answer-safety.dom.test.tsx"
],
"baseline": {
@@ -155,8 +156,8 @@
},
"built": true,
"locallyRegistered": true,
- "v2ShellMounted": false,
- "v2MountMode": "none",
+ "v2ShellMounted": true,
+ "v2MountMode": "inherited-global-root",
"proofDeclared": true,
"baselineCommitted": false
},
@@ -471,6 +472,7 @@
"src/components/ui/verification-notice.tsx"
],
"productImportFiles": [
+ "src/components/ui/answer-card.tsx",
"src/components/ui/retrieval-state-banner.tsx",
"src/components/ui/verification-notice.tsx"
],
@@ -978,7 +980,11 @@
"src/components/ui/answer-card.tsx",
"src/components/ui/date-display.tsx"
],
- "productImportFiles": ["src/components/AccessibleTable.tsx", "src/components/ui/date-display.tsx"],
+ "productImportFiles": [
+ "src/components/AccessibleTable.tsx",
+ "src/components/ui/answer-card.tsx",
+ "src/components/ui/date-display.tsx"
+ ],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -1155,7 +1161,7 @@
"sourceExported": true,
"entryExported": true,
"directImportFiles": ["src/components/ui/answer-card.tsx"],
- "productImportFiles": [],
+ "productImportFiles": ["src/components/ui/answer-card.tsx"],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -1175,8 +1181,8 @@
},
"built": true,
"locallyRegistered": true,
- "v2ShellMounted": false,
- "v2MountMode": "none",
+ "v2ShellMounted": true,
+ "v2MountMode": "inherited-global-root",
"proofDeclared": true,
"baselineCommitted": false
},
@@ -1214,11 +1220,8 @@
"source": "src/components/ui/retrieval-state-banner.tsx",
"sourceExported": true,
"entryExported": true,
- "directImportFiles": [
- "src/components/clinical-dashboard/answer-result-surface.tsx",
- "src/components/ui/answer-card.tsx"
- ],
- "productImportFiles": ["src/components/clinical-dashboard/answer-result-surface.tsx"],
+ "directImportFiles": ["src/components/ui/answer-card.tsx"],
+ "productImportFiles": ["src/components/ui/answer-card.tsx"],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -1640,7 +1643,7 @@
"src/components/ui/citation.tsx",
"src/components/ui/retrieval-state-banner.tsx"
],
- "productImportFiles": ["src/components/ui/retrieval-state-banner.tsx"],
+ "productImportFiles": ["src/components/ui/answer-card.tsx", "src/components/ui/retrieval-state-banner.tsx"],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -1853,11 +1856,8 @@
"source": "src/components/ui/verification-notice.tsx",
"sourceExported": true,
"entryExported": true,
- "directImportFiles": [
- "src/components/clinical-dashboard/answer-result-surface.tsx",
- "src/components/ui/answer-card.tsx"
- ],
- "productImportFiles": ["src/components/clinical-dashboard/answer-result-surface.tsx"],
+ "directImportFiles": ["src/components/ui/answer-card.tsx"],
+ "productImportFiles": ["src/components/ui/answer-card.tsx"],
"designSync": {
"listedInSourceMap": true,
"listedInDtsProps": true,
@@ -3046,17 +3046,17 @@
"files": []
},
"permittedComponentFamilies": ["answer", "controls", "feedback", "layout", "source"],
- "sanctionedSpecialPatterns": ["AnswerResultSurface", "RetrievalStateBanner", "VerificationNotice"],
+ "sanctionedSpecialPatterns": ["AnswerResultSurface", "RetrievalStateBanner"],
"roots": [
{
"file": "src/components/clinical-dashboard/answer-result-surface.tsx",
"exists": true,
- "imports": ["RetrievalStateBanner", "Sheet", "VerificationNotice"],
+ "imports": ["AnswerCard", "Sheet"],
"importedFamilies": ["answer", "layout"],
"literalCkbV2": false,
"dynamicCkbV2": false,
"v2MountMode": "inherited-global-root",
- "sanctionedPatternsPresent": ["AnswerResultSurface", "VerificationNotice", "RetrievalStateBanner"]
+ "sanctionedPatternsPresent": ["AnswerResultSurface", "RetrievalStateBanner"]
},
{
"file": "src/components/clinical-dashboard/answer-thread-turn.tsx",
@@ -3239,7 +3239,7 @@
"summary": {
"registeredComponentCount": 53,
"previewCount": 53,
- "productImportedComponentCount": 27,
+ "productImportedComponentCount": 29,
"rootCount": 55,
"productionRouteCount": 47,
"nextUiEntryCount": 99
diff --git a/src/components/clinical-dashboard/answer-result-surface.tsx b/src/components/clinical-dashboard/answer-result-surface.tsx
index f4db5c6c42..e7650ab2a2 100644
--- a/src/components/clinical-dashboard/answer-result-surface.tsx
+++ b/src/components/clinical-dashboard/answer-result-surface.tsx
@@ -8,11 +8,7 @@ import { ClipboardCheck, ExternalLink, Layers, ShieldAlert } from "lucide-react"
import { type AnswerFeedbackType } from "@/lib/answer-feedback";
import { AnswerFollowUpSuggestions } from "@/components/clinical-dashboard/answer-follow-up-suggestions";
import { CrossModeLinksSection } from "@/components/clinical-dashboard/cross-mode-links";
-import {
- isPreformattedGroundedAnswer,
- NaturalLanguageAnswer,
- UserQuestionBubble,
-} from "@/components/clinical-dashboard/answer-content";
+import { isPreformattedGroundedAnswer, NaturalLanguageAnswer } from "@/components/clinical-dashboard/answer-content";
import { answerStateForAnswer } from "@/components/clinical-dashboard/answer-copy-payload";
import {
AnswerSupportSummaryCard,
@@ -28,9 +24,8 @@ import {
} from "@/components/clinical-dashboard/evidence-panels";
import { citedDocumentHref } from "@/components/clinical-dashboard/source-actions";
import { CanonicalAnswerTables, MobileEvidenceSheetContent } from "@/components/clinical-dashboard/visual-evidence";
-import { RetrievalStateBanner } from "@/components/ui/retrieval-state-banner";
+import { AnswerCard, AnswerCardQueryEcho } from "@/components/ui/answer-card";
import { Sheet } from "@/components/ui/sheet";
-import { VerificationNotice } from "@/components/ui/verification-notice";
import { answerSurface, cn, iconTilePremium, subtleStatusPill } from "@/components/ui-primitives";
import { type AnswerRenderModel } from "@/lib/answer-render-policy";
import { type AppModeId } from "@/lib/app-modes";
@@ -204,6 +199,34 @@ function StagedAnswerResultSurfaceImpl({
weakEvidence,
answerState,
});
+ // Built once so both arms of the `ready` / degraded split below stay identical.
+ // The split exists only because `AnswerCardProps` discriminates on `state` to make
+ // `onOpenSource` required for a degraded card (DECISIONS §Q1), and a union-typed
+ // `state` cannot narrow that at the call site.
+ const answerVerification = {
+ state: answerState.kind,
+ presentation: "responsive-compact" as const,
+ // From the quality tier, never from the state kind: #207 precedence lets
+ // stale/partial/ungrounded outrank source_only, so keying on the kind announced
+ // "AI-generated" directly above the Source-only disclosure saying no model wrote
+ // it (#228).
+ attribution: (answer.answerQualityTier === "source_only" ? "extractive" : "model") as "extractive" | "model",
+ sourceCount: "sourceCount" in answerState ? answerState.sourceCount : sourceCount,
+ };
+ const answerProse = (
+
+ Question: + {cleaned} +
+ ); +} + type AnswerCardBase = { /** System-owned verification wording. Required: a generated answer cannot render without it. */ verification: VerificationNoticeProps; @@ -68,6 +84,14 @@ export function AnswerCard({ onOpenSource, className, }: AnswerCardProps) { + // Vertical density: lux horizontal `--pad-panel` stays, but stacked header+body + // each carrying full panel padding added ~60px of phantom phone scroll against the + // `#227` budget of 8 (short-answer smoke) and pushed the desktop table/prose delta + // past 180px once the query echo moved into this header. Keep the raised card chrome; + // reclaim the double vertical pad at the header/body seam and the loose gap-stack. + const panelX = "px-[var(--pad-panel,1.5rem)]"; + const panelY = "py-3"; + return (- Question: - {query} -
- ) : null} +