Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
63 changes: 2 additions & 61 deletions src/app/globals.css
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,7 @@
*
* Radius usage rules:
* rounded-md chips, inner elements, metadata pills
* rounded-lg controls, inputs, buttons
* rounded-lg cards, panels, drawers
* rounded-lg controls, inputs, buttons, cards, panels, drawers
* rounded-xl bottom sheets, dialogs, large shells
*/
@theme {
Expand DownExpand Up@@ -464,58 +463,6 @@ summary::-webkit-details-marker {
background: var(--surface);
}

.universal-header-ledger {
min-height: 2.5rem;
max-width: min(100%, 27rem);
border: 1px solid var(--border);
border-radius: 999px;
background: var(--surface-raised);
padding: 0.25rem 0.55rem 0.25rem 0.7rem;
color: var(--text-muted);
box-shadow: none;
}

.universal-header-ledger-label {
display: inline-flex;
align-items: center;
min-height: 1.75rem;
border-radius: 999px;
background: color-mix(in srgb, var(--clinical-chat-teal-soft) 72%, transparent);
padding-inline: 0.55rem;
color: var(--clinical-chat-teal);
font-size: 0.6875rem;
font-weight: 800;
letter-spacing: 0;
}

.universal-header-ledger-item {
display: inline-flex;
min-width: 0;
align-items: center;
gap: 0.35rem;
padding-inline: 0.35rem;
font-size: 0.75rem;
font-weight: 700;
line-height: 1;
white-space: nowrap;
}

.universal-header-ledger-separator {
height: 1.25rem;
width: 1px;
flex: 0 0 auto;
background: color-mix(in srgb, var(--border-strong) 38%, transparent);
}

.universal-header-status-dot {
display: inline-block;
height: 0.5rem;
width: 0.5rem;
flex: 0 0 auto;
border-radius: 999px;
box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 12%, transparent);
}

.universal-header-mode-button {
border-color: var(--border);
background: var(--surface);
Expand All@@ -533,17 +480,11 @@ summary::-webkit-details-marker {
background: var(--surface-subtle);
}

.universal-header-avatar {
box-shadow: var(--shadow-tight);
}

.dark .universal-header-ledger,
.dark .universal-header-mode-button {
box-shadow: var(--shadow-tight);
}

.dark .universal-header-icon-control,
.dark .universal-header-avatar {
.dark .universal-header-icon-control {
box-shadow: none;
}

Expand Down
9 changes: 9 additions & 0 deletions src/app/layout.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,15 @@ export default function RootLayout({
suppressHydrationWarning
>
<body className="min-h-full flex flex-col">
{/* Applies the resolved theme before first paint on every route (standalone
pages don't mount useTheme, and hydration-time toggling flashes light).
Mirrors resolveThemePreference in src/lib/theme.ts: stored choice wins,
otherwise the OS preference. Key must match use-theme.ts. */}
<script
dangerouslySetInnerHTML={{
__html: `(function(){try{var t=localStorage.getItem("clinical-kb-theme");var d=t==="dark"||(t!=="light"&&window.matchMedia("(prefers-color-scheme: dark)").matches);document.documentElement.classList.toggle("dark",d);}catch(e){}})();`,
}}
/>
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:fixed focus:left-[max(0.75rem,env(safe-area-inset-left))] focus:top-[max(0.75rem,env(safe-area-inset-top))] focus:z-[100] focus:rounded-lg focus:border focus:border-[color:var(--border-lux)] focus:bg-[color:var(--surface-raised)] focus:px-4 focus:py-2 focus:text-sm focus:font-semibold focus:text-[color:var(--text)] focus:shadow-[var(--shadow-elevated)]"
Expand Down
6 changes: 3 additions & 3 deletions src/components/ClinicalDashboard.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -951,8 +951,8 @@ function NaturalLanguageAnswer({
textMuted,
)}
>
Source-only answer — assembled from your documents without the AI model, so it may be less
complete. Verify it against the cited passages below.
Source-only answer — assembled from your documents without the AI model, so it may be less complete. Verify
it against the cited passages below.
</p>
) : null}
{sourceCapsuleButton}
Expand DownExpand Up@@ -2704,7 +2704,7 @@ function AnswerSafetyNotice({
</p>
) : null}
{demoMode ? (
<p className="mt-1 font-semibold text-amber-800 dark:text-amber-100">
<p className="mt-1 font-semibold text-[color:var(--warning)]">
Synthetic demo only: this is not clinical guidance.
</p>
) : null}
Expand Down
8 changes: 4 additions & 4 deletions src/components/applications-launcher-page.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -301,7 +301,7 @@ function AppIcon({ app, compact = false }: { app: LauncherApp; compact?: boolean
function LaunchLink({ app, compact = false, className }: { app: LauncherApp; compact?: boolean; className?: string }) {
const label = `Launch ${app.title}`;
const classes = cn(
"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[color:var(--clinical-chat-teal)] px-4 text-sm font-semibold text-white shadow-[var(--shadow-tight)] hover:bg-[color:var(--primary-strong)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]",
"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[color:var(--clinical-chat-teal)] px-4 text-sm font-semibold text-[color:var(--clinical-accent-contrast)] shadow-[var(--shadow-tight)] hover:bg-[color:var(--clinical-accent-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]",
compact && "min-h-9 px-3 text-xs",
className,
);
Expand DownExpand Up@@ -343,7 +343,7 @@ function HeaderFilter({
className={cn(
"min-h-11 px-4 text-xs font-semibold transition sm:min-w-[5.25rem]",
active
? "bg-[color:var(--clinical-chat-teal)] text-white shadow-[var(--shadow-tight)]"
? "bg-[color:var(--clinical-chat-teal)] text-[color:var(--clinical-accent-contrast)] shadow-[var(--shadow-tight)]"
: "border-l border-[color:var(--border)] text-[color:var(--text-muted)] first:border-l-0 hover:bg-[color:var(--surface-subtle)] hover:text-[color:var(--text)]",
)}
>
Expand DownExpand Up@@ -682,7 +682,7 @@ function ApplicationsMobileMenu({ open, onOpenChange }: { open: boolean; onOpenC
<Link
href="/"
onClick={() => onOpenChange(false)}
className="inline-flex min-h-[44px] w-full items-center justify-center gap-2 rounded-lg bg-[color:var(--clinical-chat-teal)] px-3 text-sm font-semibold text-white shadow-[var(--shadow-tight)] hover:bg-[color:var(--primary-strong)]"
className="inline-flex min-h-[44px] w-full items-center justify-center gap-2 rounded-lg bg-[color:var(--clinical-chat-teal)] px-3 text-sm font-semibold text-[color:var(--clinical-accent-contrast)] shadow-[var(--shadow-tight)] hover:bg-[color:var(--clinical-accent-hover)]"
>
<Plus className="h-4 w-4" />
New chat
Expand DownExpand Up@@ -885,7 +885,7 @@ function ApplicationsHeader({
aria-expanded={modeMenuOpen}
aria-label="Current app mode: Applications"
>
<span className="grid h-7 w-7 place-items-center rounded-full bg-[color:var(--clinical-chat-teal)] text-white shadow-[var(--shadow-tight)]">
<span className="grid h-7 w-7 place-items-center rounded-full bg-[color:var(--clinical-chat-teal)] text-[color:var(--clinical-accent-contrast)] shadow-[var(--shadow-tight)]">
<Grid2X2 className="h-3.5 w-3.5" />
</span>
<span className="min-w-0">
Expand Down
13 changes: 9 additions & 4 deletions src/components/clinical-dashboard/master-search-header.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -888,7 +888,10 @@ export function MasterSearchHeader({
integrated={usesUniversalFooterStyle}
/>

<label className="relative flex min-w-0 flex-1 items-center overflow-hidden">
{/* The clear button is a flex sibling (not absolutely positioned): the
unlayered .answer-footer-search-input padding beats a conditional
pr-* utility, which let text run under an overlaid button. */}
<label className="flex min-w-0 flex-1 items-center overflow-hidden">
<input
ref={queryInputRef}
data-testid="global-search-input"
Expand All@@ -906,14 +909,13 @@ export function MasterSearchHeader({
"w-full min-w-0",
usesUniversalFooterStyle && "answer-footer-search-input",
isDesktopHomeComposer && "desktop-home-search-input",
query ? "pr-11" : null,
)}
/>
{query && (
<button
type="button"
onClick={onClearQuery}
className="absolute right-0 top-1/2 grid h-[44px] w-[44px] -translate-y-1/2 place-items-center rounded-full text-[color:var(--text-muted)] transition hover:bg-[color:var(--surface-subtle)] hover:text-[color:var(--text)]"
className="grid h-[44px] w-[44px] shrink-0 place-items-center rounded-full text-[color:var(--text-muted)] transition hover:bg-[color:var(--surface-subtle)] hover:text-[color:var(--text)]"
aria-label="Clear search question"
>
<X className="h-4 w-4" />
Expand DownExpand Up@@ -1235,7 +1237,10 @@ export function MasterSearchHeader({
</button>
</>
) : isStandaloneModeHomeHeader ? (
<div className="hidden min-w-0 items-center gap-2 lg:flex">
/* min-[1400px]: below that the equal-thirds grid leaves the right
column too narrow for these chips and they slide under the
centered mode pill. */
<div className="hidden min-w-0 items-center gap-2 min-[1400px]:flex">
<span className="inline-flex min-h-11 items-center gap-2 rounded-lg border border-[color:var(--border)] bg-[color:var(--surface)] px-3 text-sm font-extrabold text-[color:var(--text-heading)] shadow-[var(--shadow-inset)]">
<ShieldCheck className="h-4 w-4 text-[color:var(--clinical-accent)]" aria-hidden />
Local only
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -365,10 +365,12 @@ function IconTile({
"grid shrink-0 place-items-center rounded-lg border shadow-[var(--shadow-inset)]",
tone === "teal" &&
"border-[color:var(--clinical-chat-teal)]/20 bg-[color:var(--clinical-chat-teal-soft)] text-[color:var(--clinical-chat-teal)]",
tone === "blue" && "border-blue-500/15 bg-blue-50 text-blue-700 dark:bg-blue-950/30 dark:text-blue-300",
tone === "blue" &&
"border-[color:var(--info-border)]/60 bg-[color:var(--info-bg)] text-[color:var(--info-text)]",
tone === "slate" &&
"border-[color:var(--border)] bg-[color:var(--surface-subtle)] text-[color:var(--text-muted)]",
tone === "danger" && "border-red-500/25 bg-red-50 text-red-600 dark:bg-red-950/25 dark:text-red-300",
tone === "danger" &&
"border-[color:var(--danger-border)]/70 bg-[color:var(--danger-bg)] text-[color:var(--danger-text)]",
className,
)}
>
Expand DownExpand Up@@ -592,7 +594,7 @@ function DoseCeiling({ value }: { value: string }) {
<span className="rounded border border-[color:var(--border)] bg-[color:var(--surface-subtle)] px-1.5 py-0.5 text-[9px] uppercase tracking-[0.06em] text-[color:var(--text-soft)]">
Ceiling
</span>
<span className="text-[color:var(--text-heading)]">{value}</span>
<span className="whitespace-nowrap nums text-[color:var(--text-heading)]">{value}</span>
</span>
);
}
Expand DownExpand Up@@ -789,7 +791,7 @@ function DetailTile({
<div
className={cn(
"min-h-[4.05rem] rounded-lg border bg-[color:var(--surface-raised)] px-2.5 py-2.5 shadow-[var(--shadow-inset)] sm:min-h-[4.2rem] sm:px-3 sm:py-3",
danger ? "border-red-500/35 bg-red-50/30 dark:bg-red-950/10" : "border-[color:var(--border)]",
danger ? "border-[color:var(--danger-border)] bg-[color:var(--danger-bg)]/40" : "border-[color:var(--border)]",
)}
>
<div className="flex items-start gap-2">
Expand All@@ -798,7 +800,7 @@ function DetailTile({
<p
className={cn(
"text-[11px] font-semibold leading-4",
danger ? "text-red-600 dark:text-red-300" : "text-[color:var(--text-heading)]",
danger ? "text-[color:var(--danger)]" : "text-[color:var(--text-heading)]",
)}
>
{label}
Expand DownExpand Up@@ -829,7 +831,7 @@ function DetailRowBlock({ row }: { row: DetailRow }) {
<p
className={cn(
"text-[13px] font-semibold sm:text-sm",
row.tone === "danger" ? "text-red-600 dark:text-red-300" : "text-[color:var(--text-heading)]",
row.tone === "danger" ? "text-[color:var(--danger)]" : "text-[color:var(--text-heading)]",
)}
>
{row.label}
Expand DownExpand Up@@ -864,7 +866,10 @@ function DetailRowBlock({ row }: { row: DetailRow }) {
<ul className="grid gap-1.5">
{body.map((item) => (
<li key={item} className="flex gap-3">
<span className="mt-2.5 h-1.5 w-1.5 shrink-0 rounded-full bg-red-500" aria-hidden="true" />
<span
className="mt-2.5 h-1.5 w-1.5 shrink-0 rounded-full bg-[color:var(--danger)]"
aria-hidden="true"
/>
<span>{item}</span>
</li>
))}
Expand DownExpand Up@@ -1116,7 +1121,7 @@ function MobileDetailCard({ row, compact = false }: { row: DetailRow; compact?:
<p
className={cn(
"text-[13px] font-semibold leading-4",
row.tone === "danger" ? "text-red-600 dark:text-red-300" : "text-[color:var(--text-heading)]",
row.tone === "danger" ? "text-[color:var(--danger)]" : "text-[color:var(--text-heading)]",
)}
>
{row.label}
Expand DownExpand Up@@ -1155,7 +1160,10 @@ function MobileDetailCard({ row, compact = false }: { row: DetailRow; compact?:
{body.map((item) => (
<p key={item} className={cn(row.tone === "danger" && "flex gap-2")}>
{row.tone === "danger" ? (
<span className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-red-500" aria-hidden="true" />
<span
className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-[color:var(--danger)]"
aria-hidden="true"
/>
) : null}
<span>{item}</span>
</p>
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -375,7 +375,7 @@ function DesktopProfileStrip({ tone }: { tone: Concept["tone"] }) {
)}
>
DS
<span className="absolute bottom-0 right-0 h-3.5 w-3.5 rounded-full border-2 border-[color:var(--surface)] bg-emerald-600" />
<span className="absolute bottom-0 right-0 h-3.5 w-3.5 rounded-full border-2 border-[color:var(--surface)] bg-[color:var(--success)]" />
</span>
<span className="min-w-0">
<span className="block truncate text-sm font-semibold text-[color:var(--text-heading)]">Dr Simpson</span>
Expand DownExpand Up@@ -543,7 +543,7 @@ function PhoneProfileRow({ tone }: { tone: Concept["tone"] }) {
>
<span className="relative grid h-11 w-11 shrink-0 place-items-center rounded-full border border-[color:var(--clinical-chat-teal)]/10 bg-[color:var(--clinical-chat-teal-soft)] text-sm font-bold text-[color:var(--clinical-chat-teal)] shadow-[var(--shadow-inset)]">
DS
<span className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-[color:var(--surface)] bg-emerald-600" />
<span className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-[color:var(--surface)] bg-[color:var(--success)]" />
</span>
<span className="min-w-0">
<span className="block truncate text-sm font-semibold text-[color:var(--text-heading)]">Dr Simpson</span>
Expand Down
Loading