From 1a6de5ffaf5fe99391e222abef37b1c79004641a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 12 Oct 2026 13:15:47 +0000 Subject: [PATCH 1/8] Work first run: slim sign-in line, Finish setting up row, one empty-state line, no duplicate My Day tiles on call - On Call: the signed-out 'Hospital numbers are for signed-in members' card becomes one slim line ('Sign in to see your hospital's numbers' + Sign in) in the same place on every hub page. Crisis lines are untouched. - New WorkSetupRow ('Finish setting up', one line + chevron, dismissible on this device) at the top of On Call, Teaching and CPD first pages while setup is incomplete; opens the existing setup page. - New WorkEmptyLine (a sentence plus at most one real action); On Call 'Not set up for this hospital' lines keep their words and gain the Service handbook link; the empty Shift lists sheet says so instead of showing nothing. - My Day quick tiles while on call: Playbook and Contacts replace the hero's Log a call and Handover. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL --- src/components/cme/cme-dashboard.tsx | 4 + src/components/mode-kit/work-empty-line.tsx | 61 +++++++++++++ .../mode-kit/work-sign-in-notice.tsx | 40 ++++++++- src/components/my-day/my-day-today-cards.tsx | 10 ++- src/components/on-call/kit/handbook-state.tsx | 8 +- src/components/on-call/kit/state-label.tsx | 10 +++ src/components/on-call/now/right-now.tsx | 11 ++- src/components/on-call/now/shift-lists.tsx | 12 ++- src/components/on-call/on-call-home.tsx | 4 + .../on-call/whos-on/whos-on-page.tsx | 7 +- src/components/teaching/teaching-today.tsx | 5 ++ src/components/work-setup/work-setup-row.tsx | 85 +++++++++++++++++++ tests/on-call-kit.dom.test.tsx | 6 +- .../work-first-run-empty-states.dom.test.tsx | 61 +++++++++++++ tests/work-setup-page.dom.test.tsx | 34 ++++++++ 15 files changed, 343 insertions(+), 15 deletions(-) create mode 100644 src/components/mode-kit/work-empty-line.tsx create mode 100644 src/components/work-setup/work-setup-row.tsx create mode 100644 tests/work-first-run-empty-states.dom.test.tsx diff --git a/src/components/cme/cme-dashboard.tsx b/src/components/cme/cme-dashboard.tsx index e538dc1b40..08f8056541 100644 --- a/src/components/cme/cme-dashboard.tsx +++ b/src/components/cme/cme-dashboard.tsx @@ -32,6 +32,7 @@ import { CmeYearInWeeks } from "@/components/cme/cme-year-in-weeks"; import { WorkColumns } from "@/components/work-frame/work-desktop-layout"; import { Button } from "@/components/ui/button"; import { NewWorkModeOnly } from "@/components/work-mode-launch/work-mode-launch-provider"; +import { WorkSetupRow } from "@/components/work-setup/work-setup-row"; import { addDays, expandEvents } from "@/lib/calendar/calendar-event"; import { cmeCalendarEvents } from "@/lib/cme/calendar-events"; import { buildCmeCatchUpPlan } from "@/lib/cme/catch-up-plan"; @@ -637,6 +638,9 @@ export function CmeDashboard({ the dates and the year's details on the right (11 Oct 2026 layout audit). */}
+ + + {summary} {nextStepNode} {toLog} diff --git a/src/components/mode-kit/work-empty-line.tsx b/src/components/mode-kit/work-empty-line.tsx new file mode 100644 index 0000000000..ce5e493e1b --- /dev/null +++ b/src/components/mode-kit/work-empty-line.tsx @@ -0,0 +1,61 @@ +import Link from "next/link"; +import type { ReactNode } from "react"; + +import { focusRing } from "@/components/card-recipes"; +import { cn } from "@/components/ui-primitives"; + +/** + * The one inline empty state for a row or a short block in a work area (site + * review 12 Oct 2026, item 2): a plain sentence and, when there is somewhere + * real to go, one action. Before this a row could end at "Not set up for this + * hospital" with nothing to tap. + * + * The page-sized empty state stays `WorkEmpty` / `WorkStateNotice`; this is + * for a line inside a card. With no action it draws the sentence only, so a + * caller never invents a destination to fill the slot. + */ +export type WorkEmptyLineAction = + | { readonly label: string; readonly href: string; readonly onClick?: never; readonly testId?: string } + | { readonly label: string; readonly onClick: () => void; readonly href?: never; readonly testId?: string }; + +export const workEmptyLineActionClass = + "inline-flex min-h-12 shrink-0 items-center rounded-sm px-1 text-sm font-semibold text-[color:var(--mode-identity)] no-underline"; + +export function WorkEmptyLine({ + children, + action, + className, + testId, +}: { + /** The sentence: plain words that say what is missing. */ + readonly children: ReactNode; + readonly action?: WorkEmptyLineAction; + readonly className?: string; + readonly testId?: string; +}) { + return ( +
+

{children}

+ {action ? ( + action.href !== undefined ? ( + + {action.label} + + ) : ( + + ) + ) : null} +
+ ); +} diff --git a/src/components/mode-kit/work-sign-in-notice.tsx b/src/components/mode-kit/work-sign-in-notice.tsx index 8befc5552b..5f9c6d12f7 100644 --- a/src/components/mode-kit/work-sign-in-notice.tsx +++ b/src/components/mode-kit/work-sign-in-notice.tsx @@ -1,9 +1,10 @@ "use client"; -import type { LucideIcon } from "lucide-react"; +import { LogIn, type LucideIcon } from "lucide-react"; import { useEffect, useState, type ReactNode } from "react"; import { AccountSetupDialog } from "@/components/clinical-dashboard/account-setup-dialog"; +import { WorkButton } from "@/components/mode-kit/work"; import { WorkStateNotice } from "@/components/mode-kit/work-state"; import { useAuthSession } from "@/lib/supabase/client"; @@ -31,6 +32,43 @@ function RefreshOnSignIn({ onSignedIn }: { readonly onSignedIn: () => void }) { return null; } +/** + * The slim signed-out line: one sentence and Sign in, in a flat hairline card + * at the top of the page content (site review 12 Oct 2026, item 2). For a page + * whose own content still shows signed out (On Call keeps its public crisis + * lines and examples below), so the sign-in ask does not push them half a + * screen down the way the full `WorkSignInNotice` card did. + */ +export function WorkSignInLine({ + title, + signInLabel = "Sign in", + signInTestId, + testId, +}: { + readonly title: ReactNode; + readonly signInLabel?: string; + readonly signInTestId?: string; + readonly testId?: string; +}) { + const [open, setOpen] = useState(false); + return ( + <> +
+

+ {title} +

+ setOpen(true)} testId={signInTestId}> + {signInLabel} + +
+ {open ? setOpen(false)} /> : null} + + ); +} + /** * The shared signed-out state with the way in: "Sign in" opens the app's own * account dialog (there is no sign-in page), the same in every work area. diff --git a/src/components/my-day/my-day-today-cards.tsx b/src/components/my-day/my-day-today-cards.tsx index 349cc73b75..f7f63fc888 100644 --- a/src/components/my-day/my-day-today-cards.tsx +++ b/src/components/my-day/my-day-today-cards.tsx @@ -9,6 +9,7 @@ import { Clock, FileText, GraduationCap, + ListChecks, Moon, Phone, Shield, @@ -751,10 +752,13 @@ const MY_DAY_QUICK_ACTIONS: readonly MyDayQuickAction[] = [ { label: "Roster", href: "/roster", icon: CalendarDays, testId: "my-day-qa-roster", mode: "roster" }, ]; -/** During on call (the mockup's 03:10 screen): Handover and Remind me take CPD's and Roster's places. */ +/** + * During on call the hero already offers Log a call and Handover, so the tiles + * offer what it does not (site review 12 Oct 2026, item 7). + */ const MY_DAY_ON_CALL_ACTIONS: readonly MyDayQuickAction[] = [ - MY_DAY_QUICK_ACTIONS[0]!, - { label: "Handover", href: "/on-call/handover", icon: FileText, testId: "my-day-qa-handover", mode: "on-call" }, + { label: "Playbook", href: "/on-call/playbook", icon: ListChecks, testId: "my-day-qa-playbook", mode: "on-call" }, + { label: "Contacts", href: "/on-call/contacts", icon: Phone, testId: "my-day-qa-contacts", mode: "on-call" }, MY_DAY_QUICK_ACTIONS[2]!, { label: "Remind me", icon: Bell, testId: "my-day-qa-remind", mode: "my-day" }, ]; diff --git a/src/components/on-call/kit/handbook-state.tsx b/src/components/on-call/kit/handbook-state.tsx index 0a506ad17f..b58cea3a7d 100644 --- a/src/components/on-call/kit/handbook-state.tsx +++ b/src/components/on-call/kit/handbook-state.tsx @@ -14,7 +14,7 @@ import type { HospitalHandbookStatus, } from "@/components/on-call/use-hospital-handbook"; import { WorkButton } from "@/components/mode-kit/work"; -import { WorkSignInNotice } from "@/components/mode-kit/work-sign-in-notice"; +import { WorkSignInLine } from "@/components/mode-kit/work-sign-in-notice"; import { WorkStateNotice } from "@/components/mode-kit/work-state"; import { cn } from "@/components/ui-primitives"; @@ -27,7 +27,7 @@ const ON_CALL_SERVICE_HREF = "/on-call/service"; * (`tests/on-call-hub-wording.test.ts`). */ const SIGN_IN_TITLES: Partial> = { - "signed-out": "Hospital numbers are for signed-in members.", + "signed-out": "Sign in to see your hospital's numbers", expired: "Your session ended. Sign in again to see your hospital's numbers.", }; @@ -59,7 +59,9 @@ export function OnCallHandbookState({ }) { const testId = `on-call-handbook-state-${handbook.status}`; const signIn = SIGN_IN_TITLES[handbook.status]; - if (signIn) return ; + // One slim line at the top, not a page-sized card (site review 12 Oct 2026, item 2): the + // public crisis lines and the page's examples below it stay where they were. + if (signIn) return ; switch (handbook.status) { case "ready": return null; diff --git a/src/components/on-call/kit/state-label.tsx b/src/components/on-call/kit/state-label.tsx index 251b444aa1..1f83217b29 100644 --- a/src/components/on-call/kit/state-label.tsx +++ b/src/components/on-call/kit/state-label.tsx @@ -34,6 +34,16 @@ function words(state: OnCallRowState): string { } } +/** + * The one action a "Not set up for this hospital" line offers (site review 12 Oct 2026, item 2): + * the service handbook page, where the service's own entries are kept. It is an existing page; + * nothing new is promised. + */ +export const ON_CALL_SERVICE_HANDBOOK_ACTION = { + label: "Service handbook", + href: "/on-call/service", +} as const; + export function OnCallStateLabel({ state }: { readonly state: OnCallRowState }) { const warning = state.kind === "removed"; return ( diff --git a/src/components/on-call/now/right-now.tsx b/src/components/on-call/now/right-now.tsx index a8438b28b3..f6892dd9bc 100644 --- a/src/components/on-call/now/right-now.tsx +++ b/src/components/on-call/now/right-now.tsx @@ -8,7 +8,8 @@ import { OnCallTrackBar } from "@/components/on-call/kit/track-bar"; import { onCallOutlineButton } from "@/components/on-call/kit/calm"; import { OnCallDialSheet, onCallCallRoute } from "@/components/on-call/kit/dial-sheet"; import { OnCallGroupActionControl } from "@/components/on-call/kit/grouped-list"; -import { OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { ON_CALL_SERVICE_HANDBOOK_ACTION, OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { WorkEmptyLine } from "@/components/mode-kit/work-empty-line"; import { useOnCallYouCalledAt } from "@/components/on-call/kit/use-you-called"; import { useOnCallHospitalPhone } from "@/components/on-call/call/call-device-stores"; import { modeHeadingText, modeNumberText, modeSecondaryText } from "@/components/mode-kit/type"; @@ -153,9 +154,13 @@ export function NowRightNow({ ) : null}
) : ( -

+ -

+ )} {cover ? ( diff --git a/src/components/on-call/now/shift-lists.tsx b/src/components/on-call/now/shift-lists.tsx index 02189b093c..7c65461027 100644 --- a/src/components/on-call/now/shift-lists.tsx +++ b/src/components/on-call/now/shift-lists.tsx @@ -5,7 +5,8 @@ import { useId, useState } from "react"; import { focusRing } from "@/components/card-recipes"; import { modeInsetHairline, modeModuleSurface, modePressable, modeRowHeight } from "@/components/mode-kit/recipes"; import { OnCallTrackBar } from "@/components/on-call/kit/track-bar"; -import { OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { ON_CALL_SERVICE_HANDBOOK_ACTION, OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { WorkEmptyLine } from "@/components/mode-kit/work-empty-line"; import { onCallLeadingIcon } from "@/components/on-call/kit/calm"; import { modeNameText, modeNumberText, modeSecondaryText } from "@/components/mode-kit/type"; import { OnCallNextShift } from "@/components/on-call/on-call-next-shift"; @@ -201,6 +202,15 @@ export function NowShiftLists({ {lists.map((list) => ( ))} + {hasLists ? null : ( + + Your service has not added shift lists for this hospital yet. + + )} {hasLists ? (

Nothing is saved

diff --git a/src/components/on-call/on-call-home.tsx b/src/components/on-call/on-call-home.tsx index b8c836431f..d86683709e 100644 --- a/src/components/on-call/on-call-home.tsx +++ b/src/components/on-call/on-call-home.tsx @@ -36,6 +36,7 @@ import { useRosterShifts } from "@/components/roster/use-roster-shifts"; import { OnCallEmptyState } from "@/components/on-call/kit/empty-state"; import { cn, eyebrowText } from "@/components/ui-primitives"; import { NewWorkModeOnly } from "@/components/work-mode-launch/work-mode-launch-provider"; +import { WorkSetupRow } from "@/components/work-setup/work-setup-row"; import { onCallCallNowScenarios, onCallCallNowSteps } from "@/lib/on-call/call-now"; import { useOnCallEntries } from "@/lib/on-call/entry-store"; import { pinnedEmergencyEntries } from "@/lib/on-call/handbook-items"; @@ -331,6 +332,9 @@ function OnCallHomeLive({ now: pinnedNow }: { now?: Date } = {}) { <> {!ready && !handbookLoading ? : null} + + + } safety={ diff --git a/src/components/on-call/whos-on/whos-on-page.tsx b/src/components/on-call/whos-on/whos-on-page.tsx index 8daf78aadd..1867a5d0fa 100644 --- a/src/components/on-call/whos-on/whos-on-page.tsx +++ b/src/components/on-call/whos-on/whos-on-page.tsx @@ -14,7 +14,8 @@ import { OnCallGroupedList } from "@/components/on-call/kit/grouped-list"; import { onCallCrisisLinesCompact, OnCallHandbookState } from "@/components/on-call/kit/handbook-state"; import { OnCallHospitalLine } from "@/components/on-call/kit/hospital-line"; import { OnCallHubPageFrame } from "@/components/on-call/kit/hub-page-frame"; -import { OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { ON_CALL_SERVICE_HANDBOOK_ACTION, OnCallStateLabel } from "@/components/on-call/kit/state-label"; +import { WorkEmptyLine } from "@/components/mode-kit/work-empty-line"; import { allocateOnCallGroupSlug, onCallGroupAnchorId } from "@/components/on-call/on-call-page-anchors"; import { onCallWhosOnSections } from "@/components/on-call/on-call-page-sections"; import { useHospitalHandbook } from "@/components/on-call/use-hospital-handbook"; @@ -136,7 +137,9 @@ export function OnCallWhosOnPage({ now: pinned }: { now?: Date } = {}) { {myTeamMissing ? (
  • - + + +
  • ) : null} diff --git a/src/components/teaching/teaching-today.tsx b/src/components/teaching/teaching-today.tsx index afcfde1e18..c9bdc206c2 100644 --- a/src/components/teaching/teaching-today.tsx +++ b/src/components/teaching/teaching-today.tsx @@ -8,6 +8,8 @@ import { focusRing } from "@/components/card-recipes"; import { InformationPageShell } from "@/components/information-page-shell"; import { ModeBandAction } from "@/components/mode-band/mode-band"; import { WorkGlassButton, WorkMiniRing, WorkRing, useWorkUndoToast } from "@/components/mode-kit/work"; +import { NewWorkModeOnly } from "@/components/work-mode-launch/work-mode-launch-provider"; +import { WorkSetupRow } from "@/components/work-setup/work-setup-row"; import { ModeModuleSkeleton } from "@/components/mode-kit/module-skeleton"; import { LogToCpdSheet } from "@/components/teaching/log-to-cpd-sheet"; import { recordChart } from "@/components/teaching/my-record-model"; @@ -129,6 +131,9 @@ function TodayScreen({ demoMode }: { demoMode: boolean }) {

    Today

    + + + {now && today ? ( () => undefined; + +/** + * "Finish setting up": one line and a chevron, in a flat hairline card, at the + * top of each work area's first page while Work setup is incomplete (site + * review 12 Oct 2026, item 2). It opens the existing setup page, resuming where + * the reader left off. + * + * It reads the same device-only setup progress as My Day's "Set up Work" card, + * so finishing or putting setup away anywhere hides both. The cross puts it + * away on this device (with Undo), exactly as the card's "Not now" does. + * Drawn only after the stored progress is read, so it never flashes in and out. + */ +export function WorkSetupRow({ testId = "work-setup-row" }: { readonly testId?: string }) { + const hydrated = useSyncExternalStore( + subscribeNothing, + () => true, + () => false, + ); + const { progress, update } = useWorkSetupProgress(); + const undoToast = useWorkUndoToast(); + if (!hydrated || !workSetupPromptVisible(progress)) return null; + + const started = progress.status === "in-progress"; + const { done, total } = workSetupCount(progress); + const putAway = () => { + const before = progress.status; + update(dismissWorkSetup); + // Undo restores only the status, so a step finished meanwhile is kept. + undoToast?.("Setup put away. Find it in More or Help.", () => + update((current) => (current.status === "dismissed" ? { ...current, status: before } : current)), + ); + }; + + return ( +
    + +
    + ); +} diff --git a/tests/on-call-kit.dom.test.tsx b/tests/on-call-kit.dom.test.tsx index a06cdd297c..35344a5cee 100644 --- a/tests/on-call-kit.dom.test.tsx +++ b/tests/on-call-kit.dom.test.tsx @@ -519,7 +519,7 @@ function handbook(status: HospitalHandbookState["status"]): HospitalHandbookStat describe("OnCallHandbookState", () => { it.each([ - ["signed-out", /Hospital numbers are for signed-in members\./], + ["signed-out", /^Sign in to see your hospital's numbersSign in$/], ["expired", /Your session ended\. Sign in again to see your hospital's numbers\./], ["no-service", /You are not in a hospital handbook yet\./], ["unavailable", /could not be loaded/], @@ -541,8 +541,10 @@ describe("OnCallHandbookState", () => { render(); const state = screen.getByTestId(`on-call-handbook-state-${status}`); expect(within(state).getByRole("button", { name: "Sign in" })).toBeInTheDocument(); - expect(state).not.toHaveTextContent(/Nothing you saved|has been lost|Sign in to see/); + expect(state).not.toHaveTextContent(/Nothing you saved|has been lost|shared On Call entries/); expect(state.querySelectorAll("p")).toHaveLength(1); + // One slim line, not the page-sized card with a badge (site review 12 Oct 2026, item 2). + expect(state.querySelector(".work-empty")).toBeNull(); }, ); diff --git a/tests/work-first-run-empty-states.dom.test.tsx b/tests/work-first-run-empty-states.dom.test.tsx new file mode 100644 index 0000000000..a3667c8fa8 --- /dev/null +++ b/tests/work-first-run-empty-states.dom.test.tsx @@ -0,0 +1,61 @@ +/** @vitest-environment jsdom */ + +// Site review 12 Oct 2026: the one inline empty state (a plain sentence plus at +// most one real action), and My Day's quick tiles not repeating the on-call +// hero's Log a call and Handover. + +import { render, screen, within } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; + +import { WorkEmptyLine } from "@/components/mode-kit/work-empty-line"; +import { QuickActionsCard } from "@/components/my-day/my-day-today-cards"; +import { ON_CALL_SERVICE_HANDBOOK_ACTION, OnCallStateLabel } from "@/components/on-call/kit/state-label"; + +describe("WorkEmptyLine", () => { + it("draws the sentence only when there is nowhere real to go", () => { + render(Nothing here yet.); + const line = screen.getByTestId("line"); + expect(line).toHaveTextContent("Nothing here yet."); + expect(within(line).queryByRole("link")).toBeNull(); + expect(within(line).queryByRole("button")).toBeNull(); + }); + + it("keeps a not-set-up row's words and adds the service handbook as its one action", () => { + render( + + + , + ); + const line = screen.getByTestId("line"); + expect(line).toHaveTextContent("Not set up for this hospital"); + const link = within(line).getByRole("link", { name: "Service handbook" }); + expect(link).toHaveAttribute("href", "/on-call/service"); + expect(link.className).toContain("min-h-12"); + }); + + it("can carry a button action instead of a link", () => { + const onClick = vi.fn(); + render(No list yet.); + screen.getByRole("button", { name: "Start" }).click(); + expect(onClick).toHaveBeenCalledOnce(); + }); +}); + +describe("My Day quick tiles", () => { + const labels = () => + within(screen.getByTestId("dash-quick-actions")) + .getAllByRole("listitem") + .map((item) => item.textContent); + + it("off call: stay as before", () => { + render( undefined} />); + expect(labels()).toEqual(["Log a call", "Log CPD", "Who's on", "Roster"]); + }); + + it("on call: offer what the hero does not, never Log a call or Handover twice", () => { + render( undefined} />); + expect(labels()).toEqual(["Playbook", "Contacts", "Who's on", "Remind me"]); + expect(screen.getByTestId("my-day-qa-playbook").getAttribute("href")).toMatch(/^\/on-call\/playbook/); + expect(screen.getByTestId("my-day-qa-contacts").getAttribute("href")).toMatch(/^\/on-call\/contacts/); + }); +}); diff --git a/tests/work-setup-page.dom.test.tsx b/tests/work-setup-page.dom.test.tsx index c4d2441f67..09da74572b 100644 --- a/tests/work-setup-page.dom.test.tsx +++ b/tests/work-setup-page.dom.test.tsx @@ -52,6 +52,7 @@ import { universalHeaderLeadingSlotId } from "@/components/work-frame/work-frame import { WorkSetupPage } from "@/components/work-setup/work-setup-page"; import { WORK_SETUP_STEP_COPY, workSetupStepHref } from "@/components/work-setup/work-setup-copy"; import { WorkSetupPromptCard } from "@/components/work-setup/work-setup-prompt-card"; +import { WorkSetupRow } from "@/components/work-setup/work-setup-row"; import { WORK_SETUP_PROGRESS_STORAGE_KEY } from "@/lib/account-scoped-browser-state"; import { parseWorkSetupProgress, @@ -313,3 +314,36 @@ describe("My Day's Set up Work card", () => { expect(screen.queryByTestId("work-setup-prompt")).not.toBeInTheDocument(); }); }); + +describe("Finish setting up row on each area's first page", () => { + it("opens setup, resuming at the stored step with how many are done", () => { + seed({ step: "roster", completed: ["stage", "areas"] }); + render(); + const link = screen.getByRole("link", { name: /Finish setting up/ }); + expect(link).toHaveAttribute("href", workSetupStepHref("roster")); + expect(link).toHaveTextContent("2 of 7 done"); + }); + + it("opens the setup page from the start before anything is begun, signed in or not", () => { + auth.status = "signed_out"; + render(); + expect(screen.getByRole("link", { name: "Finish setting up" })).toHaveAttribute("href", "/my-day/setup"); + }); + + it("puts setup away on this device from its cross", () => { + render(); + fireEvent.click(screen.getByRole("button", { name: "Hide Finish setting up on this device" })); + expect(screen.queryByTestId("work-setup-row")).not.toBeInTheDocument(); + expect(stored().status).toBe("dismissed"); + }); + + it("stays away once setup is finished or put away", () => { + seed({ status: "done", step: "done" }); + const { unmount } = render(); + expect(screen.queryByTestId("work-setup-row")).not.toBeInTheDocument(); + unmount(); + seed({ status: "dismissed" }); + render(); + expect(screen.queryByTestId("work-setup-row")).not.toBeInTheDocument(); + }); +}); From a3490b1bcf345994affaec3cf414cefe4dd5afa0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 12 Oct 2026 13:37:01 +0000 Subject: [PATCH 2/8] Finish setting up row: radius tokens instead of inherit literals Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL --- src/components/work-setup/work-setup-row.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/work-setup/work-setup-row.tsx b/src/components/work-setup/work-setup-row.tsx index 43c1b2a511..190e0a1c83 100644 --- a/src/components/work-setup/work-setup-row.tsx +++ b/src/components/work-setup/work-setup-row.tsx @@ -52,7 +52,7 @@ export function WorkSetupRow({ testId = "work-setup-row" }: { readonly testId?: data-testid={`${testId}-open`} className={cn( focusRing, - "flex min-h-12 min-w-0 flex-1 items-center gap-3 rounded-[inherit] pl-3 text-left no-underline", + "flex min-h-12 min-w-0 flex-1 items-center gap-3 rounded-md pl-3 text-left no-underline", )} >