diff --git a/mockups/README.md b/mockups/README.md
index 690fd4e85..dcdeebf6e 100644
--- a/mockups/README.md
+++ b/mockups/README.md
@@ -45,7 +45,7 @@ Some document-search mockups include live handoff routes (for example `document-
## Phone Choose mode sheet YES comps
-Runnable study at [`/mockups/phone-mode-sheet-yes`](../src/app/mockups/phone-mode-sheet-yes/page.tsx): design review of the shipping phone mode sheet plus **YES 01 perfected** (sectioned clinical list — shipping recommendation) and YES 02 (icon deck alternate). Shared mockup chrome is suppressed so only the in-frame sheet is judged.
+Runnable study at [`/mockups/phone-mode-sheet-yes`](../src/app/mockups/phone-mode-sheet-yes/page.tsx): **new YES comps** after feedback rejected Find / Diagnose / Care organisation. **YES 01 dense title list** (shipping recommendation) and **YES 02 flat icon tiles** — both flat, glance-first. Shared mockup chrome is suppressed so only the in-frame sheet is judged.
## Mode-page redesign comps (2026-07-31)
diff --git a/src/app/mockups/phone-mode-sheet-yes/page.tsx b/src/app/mockups/phone-mode-sheet-yes/page.tsx
index d8c475c25..29cd300f8 100644
--- a/src/app/mockups/phone-mode-sheet-yes/page.tsx
+++ b/src/app/mockups/phone-mode-sheet-yes/page.tsx
@@ -3,9 +3,9 @@ import type { Metadata } from "next";
import { PhoneModeSheetYesMockups } from "@/components/phone-mode-sheet-yes-mockups";
export const metadata: Metadata = {
- title: "Phone mode sheet YES 01 perfected - Clinical KB",
+ title: "Phone mode sheet glance YES comps - Clinical KB",
description:
- "Perfected phone Choose mode sheet: sectioned clinical list with all review findings closed, plus the icon-deck alternate.",
+ "New phone Choose mode sheet YES comps: dense title list and flat icon tiles, without Find/Diagnose/Care organisation.",
};
export default function PhoneModeSheetYesMockupPage() {
diff --git a/src/components/phone-mode-sheet-yes-mockups.tsx b/src/components/phone-mode-sheet-yes-mockups.tsx
index 914e0f311..e91c512b9 100644
--- a/src/components/phone-mode-sheet-yes-mockups.tsx
+++ b/src/components/phone-mode-sheet-yes-mockups.tsx
@@ -16,42 +16,24 @@ import { appModeIcons } from "@/lib/app-mode-icons";
import { appModeDefinitions, visibleAppModeDefinitions, type AppModeId } from "@/lib/app-modes";
/**
- * Design scratch: phone "Choose mode" sheet — review + YES comps.
+ * Design scratch: phone "Choose mode" sheet — new YES comps (2026-08).
*
- * YES 01 (sectioned list) is the perfected master: every review finding closed,
- * sticky offset debt removed, current mode folded into the sheet header, and
- * selection is interactive so the study can be judged as a real switcher.
+ * Feedback rejected Find / Diagnose / Care organisation and roomy spacing —
+ * they made mode choice harder at a glance. Both YES directions stay flat.
+ *
+ * YES 01 — Dense title list (shipping recommendation)
+ * YES 02 — Flat icon tiles (alternate glance layout, still no lanes)
*/
-type GroupId = "find" | "diagnose" | "care";
-type VariantId = "current" | "sections" | "deck";
-type SectionsPreview = "rest" | "scrolled" | "switched";
+type VariantId = "current" | "dense" | "tiles";
+type DensePreview = "rest" | "scrolled" | "switched";
const focusRing =
"focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]";
-const GROUPS: Array<{ id: GroupId; label: string; hint: string; modes: AppModeId[] }> = [
- {
- id: "find",
- label: "Find",
- hint: "Answers, sources, services",
- modes: ["answer", "documents", "services", "forms", "favourites"],
- },
- {
- id: "diagnose",
- label: "Diagnose",
- hint: "Criteria, clues, mechanisms",
- modes: ["differentials", "dsm", "specifiers", "formulation"],
- },
- {
- id: "care",
- label: "Care",
- hint: "Meds, tools, therapy",
- modes: ["prescribing", "tools", "therapy-compass", "factsheets"],
- },
-];
-
const ACTIVE_MODE: AppModeId = "answer";
+const FLAT_MODE_IDS = visibleAppModeDefinitions("production").map((mode) => mode.id);
+const MID_SCROLL_MODE: AppModeId = "differentials";
function modeOf(id: AppModeId) {
const definition = appModeDefinitions.find((mode) => mode.id === id);
@@ -64,60 +46,24 @@ function modeOf(id: AppModeId) {
const reviewFindings = [
{
severity: "P1",
- title: "Flat list, no clinical intent",
+ title: "Organisation slowed the pick",
detail:
- "Thirteen equal-weight rows force linear scanning. Answer, DSM, and Medication compete visually even though they serve different jobs.",
+ "Find / Diagnose / Care headers, hints, and counts spent height on chrome. Mode choice on phone is a glance task — more visible rows beat clinical grouping.",
},
{
severity: "P1",
- title: "Descriptions truncate on phone",
- detail:
- "Live rows use `truncate` on a single line, so the subtitle that differentiates modes disappears on a 390 px sheet.",
+ title: "Subtitles cost catalogue height",
+ detail: "Two-line rows hide modes below the fold. Titles carry the choice; descriptions can live in aria-label.",
},
{
severity: "P2",
- title: "Selected state is easy to miss mid-scroll",
- detail:
- "Soft fill + check is correct, but there is no sticky ‘current mode’ context above the list, so returning from a long scroll loses place.",
- },
- {
- severity: "P2",
- title: "Thumb targets are dense for a primary switcher",
- detail:
- "32 px icon wells inside 52 px rows pack the sheet, but the mode switcher is a high-frequency control — it should feel larger than a desktop menu ported down.",
+ title: "Selected state must survive density",
+ detail: "Soft fill alone is weak mid-list. A left rail + check keeps place without a second sticky card.",
},
{
severity: "P3",
- title: "Header copy is generic",
- detail:
- "‘Choose mode / Switch the clinical workspace mode’ names the UI, not the clinician’s current place. A current-mode line orients faster.",
- },
-] as const;
-
-const perfectedResolutions = [
- {
- issue: "Flat catalogue",
- fix: "Find / Diagnose / Care sections with sticky labels and counts — scan by clinical job.",
- },
- {
- issue: "Truncated subtitles",
- fix: "Two-line `line-clamp-2` descriptions; inactive titles stay full `--text-heading` weight.",
- },
- {
- issue: "Lost place mid-scroll",
- fix: "Current mode lives in the non-scrolling sheet header; section labels stick at `top-0` — no fragile offset.",
- },
- {
- issue: "Dense thumb targets",
- fix: "`min-h-12` rows, 44 px icon wells, 10 px row gap rhythm — primary switcher, not a desktop menu port.",
- },
- {
- issue: "Generic header",
- fix: "Header reads “Currently · Answer” with the live icon; updates when you pick another mode.",
- },
- {
- issue: "Duplicate current chrome",
- fix: "Removed the bulky sticky “Now in” card that stole first-viewport height and repeated the selected row.",
+ title: "Header should orient, not instruct",
+ detail: "Currently · {mode} orients faster than ‘Switch the clinical workspace mode’.",
},
] as const;
@@ -129,29 +75,29 @@ const variants: Array<{
changes: string[];
}> = [
{
- id: "sections",
- title: "Sectioned clinical list — perfected",
- verdict: "YES · Master for intent",
+ id: "dense",
+ title: "Dense title list",
+ verdict: "YES · Fastest pick",
description:
- "Every review finding closed. Current mode sits in the sheet header, section labels are the only sticky layer, rows are phone-native, and selection is interactive. This is the direction to land.",
+ "Flat catalogue, title-only rows. Nearly every mode visible on open — pick by name without scrolling through section chrome. Shipping recommendation.",
changes: [
- "Header carries “Currently · {mode}” — orients without a second card.",
- "Sticky section labels only (`top-0`); no magic `4.6rem` offset under a strip.",
- "`min-h-12` rows, 44 px wells, two-line descriptions, readable inactive titles.",
- "Tap a mode: header and selection update together — proven in the Switched frame.",
+ "No Find / Diagnose / Care headers, hints, or counts.",
+ "Title-only min-h-12 rows; description stays in aria-label.",
+ "Header carries Currently · {mode}; selection lifts into the top-bar pill.",
+ "Arrow / Home / End roving focus; preview scroll stays inside the sheet.",
],
},
{
- id: "deck",
- title: "Icon deck with lane chips",
- verdict: "YES · Best overview",
+ id: "tiles",
+ title: "Flat icon tiles",
+ verdict: "YES · Icon-forward",
description:
- "Two-column mode cards plus Find / Diagnose / Care filter chips. Prefer this if browsing all modes matters more than a vertical reading order. YES 01 remains the shipping recommendation.",
+ "Same flat catalogue, presented as a compact two-column tile grid. Still no clinical lanes — icon + label for glance recognition.",
changes: [
- "Lane chips filter the deck without opening a second surface.",
- "Current mode sits in a full-width identity card above the grid.",
- "Cards are icon-forward with two-line labels; selected card uses accent ring + check.",
- "Same Sheet chrome (grip, title, close, safe-area) so the concept can drop into the live Sheet.",
+ "One continuous grid — no section labels or lane chips.",
+ "Compact tiles (icon + title) keep all modes in view.",
+ "Selected tile uses accent wash, ring, and corner check.",
+ "Use when icon recognition matters more than a single text column.",
],
},
];
@@ -268,11 +214,43 @@ function scrollContainerToTarget(container: HTMLElement, target: HTMLElement, bl
container.scrollTop += targetCenter - containerCenter;
}
+/** Shared roving-focus state for flat mode catalogues; sheets keep their own key maps. */
+function useRovingModeFocus(selected: AppModeId, onSelectedChange: (id: AppModeId) => void) {
+ const optionRefs = useRef>([]);
+ const [focusIndex, setFocusIndex] = useState(Math.max(0, FLAT_MODE_IDS.indexOf(selected)));
+
+ function focusModeOption(index: number) {
+ const next = Math.max(0, Math.min(FLAT_MODE_IDS.length - 1, index));
+ setFocusIndex(next);
+ optionRefs.current[next]?.focus();
+ }
+
+ function selectMode(id: AppModeId) {
+ onSelectedChange(id);
+ const nextIndex = FLAT_MODE_IDS.indexOf(id);
+ if (nextIndex >= 0) setFocusIndex(nextIndex);
+ }
+
+ return { optionRefs, focusIndex, focusModeOption, selectMode };
+}
+
+function CurrentlyLine({ modeId }: { modeId: AppModeId }) {
+ const mode = modeOf(modeId);
+ const Icon = appModeIcons[modeId];
+
+ return (
+
+
+
+
+
+ Currently {mode.label}
+
+
+ );
+}
+
function CurrentShippingSheet() {
- // `visibleAppModeDefinitions("production")`, not a local `!mode.devOnly`:
- // `devOnly` is optional on the union, so reading it off every member does not
- // typecheck (TS2339). app-modes.ts already exports this guard — passing
- // "production" reproduces the intent here, which is the shipping mode list.
const modes = visibleAppModeDefinitions("production");
return (
@@ -326,23 +304,7 @@ function CurrentShippingSheet() {
);
}
-function CurrentlyLine({ modeId }: { modeId: AppModeId }) {
- const mode = modeOf(modeId);
- const Icon = appModeIcons[modeId];
-
- return (
-
-
-
-
-
- Currently {mode.label}
-
-
- );
-}
-
-function ModeRow({
+function DenseModeRow({
modeId,
active,
index,
@@ -368,108 +330,81 @@ function ModeRow({
type="button"
role="menuitemradio"
aria-checked={active}
+ aria-label={`${mode.label}. ${mode.description}`}
tabIndex={tabIndex}
onClick={() => onSelect(modeId)}
onKeyDown={(event) => onKeyDown(event, index)}
style={{ animationDelay: `${Math.min(index, 8) * 28}ms` }}
className={cn(
- "relative grid min-h-12 w-full grid-cols-[2.75rem_minmax(0,1fr)_1.75rem] items-center gap-2.5 rounded-xl px-2.5 py-2.5 text-left transition-[background-color,color,box-shadow] duration-[var(--duration-fast)] ease-[var(--ease-out-soft)] motion-safe:animate-[cascade-fade-up_var(--duration-moderate)_var(--ease-out-soft)_both] motion-reduce:animate-none motion-reduce:transition-none",
+ "relative grid min-h-12 w-full grid-cols-[2rem_minmax(0,1fr)_1.25rem] items-center gap-2 rounded-lg px-2 py-1 text-left transition-[background-color,color] duration-[var(--duration-fast)] ease-[var(--ease-out-soft)] motion-reduce:transition-none",
focusRing,
active
- ? "bg-[color:var(--clinical-accent-soft)] text-[color:var(--text)] shadow-[var(--shadow-inset)]"
+ ? "bg-[color:var(--clinical-accent-soft)] text-[color:var(--text)]"
: "text-[color:var(--text)] hover:bg-[color:var(--surface-subtle)]",
)}
>
{active ? (
) : null}
-
-
-
-
- {mode.label}
-
-
- {mode.description}
-
+
-
- {active ? (
-
-
-
- ) : (
-
- )}
+
+ {mode.label}
+ {active ? (
+
+ ) : (
+
+ )}
);
}
-const SECTIONED_MODE_IDS = GROUPS.flatMap((group) => group.modes);
-
/**
- * Perfected YES 01. Current mode is header chrome (never a second sticky card).
- * Section labels are the sole sticky layer. Selection is live and controlled by
- * the phone frame so the top-bar pill stays in sync.
+ * YES 01 — dense title list. Flat catalogue, no section organisation.
+ * Selection is controlled by the phone frame so the top-bar pill stays in sync.
*/
-function SectionedListSheet({
+function DenseListSheet({
selected,
onSelectedChange,
preview = "rest",
}: {
selected: AppModeId;
onSelectedChange: (id: AppModeId) => void;
- preview?: SectionsPreview;
+ preview?: DensePreview;
}) {
- const instanceId = useId();
const bodyRef = useRef(null);
- const diagnoseRef = useRef(null);
- const optionRefs = useRef>([]);
- const selectedIndex = Math.max(0, SECTIONED_MODE_IDS.indexOf(selected));
- // Roving tabindex: keyboard moves focusIndex; remount (via PhoneFrame key) resets it.
- const [focusIndex, setFocusIndex] = useState(selectedIndex);
- // Proof-frame scroll uses the mount selection only — live taps must not re-scroll.
+ const selectedIndex = Math.max(0, FLAT_MODE_IDS.indexOf(selected));
+ const midScrollIndex = Math.max(0, FLAT_MODE_IDS.indexOf(MID_SCROLL_MODE));
const mountSelectedIndexRef = useRef(selectedIndex);
+ const { optionRefs, focusIndex, focusModeOption, selectMode } = useRovingModeFocus(selected, onSelectedChange);
useEffect(() => {
if (preview === "rest") return;
- // Constrain preview scroll to the sheet body — scrollIntoView would yank
- // every scrollable ancestor, including the document, past the study heading.
- // Run once per proof-frame mount only: re-running on live selection taps
- // would yank the Scrolled frame back to Diagnose after every mode pick.
const frame = window.requestAnimationFrame(() => {
const body = bodyRef.current;
if (!body) return;
if (preview === "scrolled") {
- const target = diagnoseRef.current;
+ const target = optionRefs.current[midScrollIndex];
if (target) scrollContainerToTarget(body, target, "start");
return;
}
- // Switched: bring the newly current mode into view so selection is not
- // off-screen under Find while the header already says DSM-5 / Care / etc.
const target = optionRefs.current[mountSelectedIndexRef.current];
if (target) scrollContainerToTarget(body, target, "center");
});
return () => window.cancelAnimationFrame(frame);
- }, [preview]);
-
- function focusModeOption(index: number) {
- const next = Math.max(0, Math.min(SECTIONED_MODE_IDS.length - 1, index));
- setFocusIndex(next);
- optionRefs.current[next]?.focus();
- }
+ }, [preview, midScrollIndex, optionRefs]);
function handleModeOptionKeyDown(event: ReactKeyboardEvent, index: number) {
if (event.key === "ArrowDown") {
@@ -483,16 +418,10 @@ function SectionedListSheet({
focusModeOption(0);
} else if (event.key === "End") {
event.preventDefault();
- focusModeOption(SECTIONED_MODE_IDS.length - 1);
+ focusModeOption(FLAT_MODE_IDS.length - 1);
}
}
- function selectMode(id: AppModeId) {
- onSelectedChange(id);
- const nextIndex = SECTIONED_MODE_IDS.indexOf(id);
- if (nextIndex >= 0) setFocusIndex(nextIndex);
- }
-
return (
- {GROUPS.map((group, groupIndex) => {
- const sectionRef = group.id === "diagnose" ? diagnoseRef : undefined;
- const rowOffset = GROUPS.slice(0, groupIndex).reduce((total, entry) => total + entry.modes.length, 0);
- const headingId = `${instanceId}-group-${group.id}`;
- return (
-
-
-
-
-
- {group.label}
-
-
{group.hint}
-
-
- {group.modes.length}
-
-
-
-
- {group.modes.map((modeId, modeIndex) => {
- const flatIndex = rowOffset + modeIndex;
- return (
- {
- optionRefs.current[flatIndex] = element;
- }}
- />
- );
- })}
-
-
- );
- })}
+ {FLAT_MODE_IDS.map((modeId, flatIndex) => (
+ {
+ optionRefs.current[flatIndex] = element;
+ }}
+ />
+ ))}
);
}
-function IconDeckSheet() {
- const instanceId = useId();
- const [lane, setLane] = useState<"all" | GroupId>("all");
- const active = modeOf(ACTIVE_MODE);
- const ActiveIcon = appModeIcons[ACTIVE_MODE];
- const visibleGroups = lane === "all" ? GROUPS : GROUPS.filter((group) => group.id === lane);
+/**
+ * YES 02 — flat icon tiles. Still no Find / Diagnose / Care lanes.
+ */
+function FlatTileSheet({
+ selected,
+ onSelectedChange,
+}: {
+ selected: AppModeId;
+ onSelectedChange: (id: AppModeId) => void;
+}) {
+ const { optionRefs, focusIndex, focusModeOption, selectMode } = useRovingModeFocus(selected, onSelectedChange);
+
+ function handleModeOptionKeyDown(event: ReactKeyboardEvent, index: number) {
+ const cols = 2;
+ if (event.key === "ArrowRight") {
+ event.preventDefault();
+ focusModeOption(index + 1);
+ } else if (event.key === "ArrowLeft") {
+ event.preventDefault();
+ focusModeOption(index - 1);
+ } else if (event.key === "ArrowDown") {
+ event.preventDefault();
+ focusModeOption(index + cols);
+ } else if (event.key === "ArrowUp") {
+ event.preventDefault();
+ focusModeOption(index - cols);
+ } else if (event.key === "Home") {
+ event.preventDefault();
+ focusModeOption(0);
+ } else if (event.key === "End") {
+ event.preventDefault();
+ focusModeOption(FLAT_MODE_IDS.length - 1);
+ }
+ }
return (
-
-
-
-
-
-
-
-
-
- Current mode
-
-
- {active.label}
-
-
- {active.description}
-
-
-
-
-
-
- {(
- [
- { id: "all" as const, label: "All" },
- ...GROUPS.map((group) => ({ id: group.id, label: group.label })),
- ] as const
- ).map((chip) => {
- const selected = lane === chip.id;
- return (
-
setLane(chip.id)}
+ }
+ closeLabel="Close mode menu"
+ >
+
+ {FLAT_MODE_IDS.map((modeId, flatIndex) => {
+ const mode = modeOf(modeId);
+ const Icon = appModeIcons[modeId];
+ const active = modeId === selected;
+ return (
+ {
+ optionRefs.current[flatIndex] = element;
+ }}
+ type="button"
+ role="menuitemradio"
+ aria-checked={active}
+ aria-label={`${mode.label}. ${mode.description}`}
+ tabIndex={flatIndex === focusIndex ? 0 : -1}
+ onClick={() => selectMode(modeId)}
+ onKeyDown={(event) => handleModeOptionKeyDown(event, flatIndex)}
+ style={{ animationDelay: `${Math.min(flatIndex, 8) * 24}ms` }}
+ className={cn(
+ "relative flex min-h-[4.75rem] flex-col items-start gap-2 rounded-2xl border p-3 text-left transition",
+ focusRing,
+ active
+ ? "border-[color:var(--clinical-accent)] bg-[color:var(--clinical-accent-soft)] shadow-[var(--shadow-tight)]"
+ : "border-[color:var(--border)] bg-[color:var(--surface)] hover:border-[color:var(--border-strong)] hover:bg-[color:var(--surface-subtle)]",
+ )}
+ >
+ {active ? (
+
+
+
+ ) : null}
+
- {chip.label}
-
- );
- })}
-
-
-
- {visibleGroups.map((group) => {
- const headingId = `${instanceId}-deck-${group.id}`;
- return (
-
-
-
- {group.label}
-
- {group.hint}
-
-
- {group.modes.map((modeId) => {
- const mode = modeOf(modeId);
- const Icon = appModeIcons[modeId];
- const isActive = modeId === ACTIVE_MODE;
- return (
- undefined}
- className={cn(
- "relative flex min-h-[6.5rem] flex-col items-start gap-2 rounded-2xl border p-3 text-left transition",
- focusRing,
- isActive
- ? "border-[color:var(--clinical-accent)] bg-[color:var(--clinical-accent-soft)] shadow-[var(--shadow-tight)]"
- : "border-[color:var(--border)] bg-[color:var(--surface)] hover:border-[color:var(--border-strong)] hover:bg-[color:var(--surface-subtle)]",
- )}
- >
- {isActive ? (
-
-
-
- ) : null}
-
-
-
-
-
- {mode.label}
-
-
- {mode.description}
-
-
-
- );
- })}
-
-
- );
- })}
-
+
+
+
+ {mode.label}
+
+
+ );
+ })}
);
}
-function SectionsPhoneFrame({
+function DensePhoneFrame({
+ large = false,
+ caption,
+ densePreview = "rest",
+ initialMode,
+}: {
+ large?: boolean;
+ caption: string;
+ densePreview?: DensePreview;
+ initialMode: AppModeId;
+}) {
+ const [selectedMode, setSelectedMode] = useState
(initialMode);
+ const modeLabel = modeOf(selectedMode).label;
+
+ return (
+
+
+ {caption}
+
+
+
+
+
+
+
+ );
+}
+
+function TilesPhoneFrame({
large = false,
caption,
- sectionsPreview = "rest",
initialMode,
}: {
large?: boolean;
caption: string;
- sectionsPreview?: SectionsPreview;
initialMode: AppModeId;
}) {
- // Owned here so the top-bar pill tracks live sheet selection. Parent keys this
- // component on preview/initialMode so state resets without a sync effect.
const [selectedMode, setSelectedMode] = useState(initialMode);
const modeLabel = modeOf(selectedMode).label;
@@ -709,8 +607,7 @@ function SectionsPhoneFrame({
{caption}
-
+
);
@@ -728,28 +625,33 @@ function PhoneFrame({
variant,
large = false,
caption,
- sectionsPreview = "rest",
+ densePreview = "rest",
initialMode,
}: {
variant: VariantId;
large?: boolean;
caption: string;
- sectionsPreview?: SectionsPreview;
+ densePreview?: DensePreview;
initialMode?: AppModeId;
}) {
- if (variant === "sections") {
- const sectionsInitial = initialMode ?? ACTIVE_MODE;
+ if (variant === "dense") {
+ const denseInitial = initialMode ?? ACTIVE_MODE;
return (
-
);
}
+ if (variant === "tiles") {
+ const tilesInitial = initialMode ?? ACTIVE_MODE;
+ return ;
+ }
+
const modeLabel = modeOf(ACTIVE_MODE).label;
return (
@@ -767,7 +669,6 @@ function PhoneFrame({
{variant === "current" ? : null}
- {variant === "deck" ? : null}
);
@@ -780,11 +681,11 @@ function ReviewPanel() {
Design review · Phone sheet
- What the current Choose mode gets wrong
+ Glance first — no lanes
- The live bottom sheet is structurally sound (Sheet focus, menuitemradio, portal). The polish gap is scan and
- hierarchy on a long clinical catalogue — not interaction plumbing.
+ Organisation and roomy spacing made mode choice harder at a glance. Both YES directions stay flat so more modes
+ are visible on open.
{reviewFindings.map((finding) => (
@@ -804,30 +705,12 @@ function ReviewPanel() {
- YES 01 perfected closes every finding above. Prefer it for shipping; YES 02 stays the overview alternate.
+ YES 01 is the dense title list. YES 02 is flat icon tiles — still no Find / Diagnose / Care.
);
}
-function PerfectedResolutions() {
- return (
-
- );
-}
-
export function PhoneModeSheetYesMockups() {
return (
@@ -837,58 +720,66 @@ export function PhoneModeSheetYesMockups() {
Phone · Choose mode sheet
- YES 01 perfected
+ New YES comps · glance without organisation
- The sectioned clinical list, taken to master: every review finding closed, no duplicate current chrome, a
- single sticky layer, phone-native targets, and live selection. YES 02 remains the overview alternate.
+ Two large directions. Both drop Find / Diagnose / Care lanes and roomy chrome so you can see and pick a mode
+ in one glance.
-
+
- Perfected · Three states
+ YES 01 · Three states
- Rest · Scrolled · Switched
+ Dense title list
- Open on Answer, scroll into Diagnose with sticky labels, then land on DSM-5 — header and selection stay in
- sync.
+ Title-only rows — no section chrome. Full catalogue scannable on open; switch keeps header and selection
+ in sync.
-
-
- All issues resolved
-
-
- The earlier YES 01 draft still carried a bulky sticky “Now in” card and a fragile `top-[4.6rem]` offset. The
- perfected sheet removes both.
-
-
-
+
+
+
+
+ YES 02 · Icon-forward
+
+
+ Flat icon tiles
+
+
+
+ Same flat catalogue as a two-column tile grid — still no clinical lanes. Tap to switch; header tracks the
+ pick.
+
+
+
@@ -902,10 +793,10 @@ export function PhoneModeSheetYesMockups() {
id="current-title"
className="mt-1 text-2xl font-semibold tracking-[-0.025em] text-[color:var(--text-heading)]"
>
- Flat list sheet
+ Flat list with subtitles
-
+
@@ -945,10 +836,10 @@ export function PhoneModeSheetYesMockups() {
))}
- {variant.id === "sections" ? (
-
+ {variant.id === "dense" ? (
+
) : (
-
+
)}
))}