diff --git a/packages/ui/src/components/chat/StatusRow.tsx b/packages/ui/src/components/chat/StatusRow.tsx index 36666fd3..039e5ff2 100644 --- a/packages/ui/src/components/chat/StatusRow.tsx +++ b/packages/ui/src/components/chat/StatusRow.tsx @@ -200,7 +200,7 @@ export const StatusRow: React.FC = ({ return { active, left }; }, [visibleTodos]); - const hasTodoContent = showTodos && visibleTodos.length > 0; + const hasTodoContent = showTodos && statusSummary.left > 0; const hasAssistantContent = showAssistantStatus && ( isWorking || Boolean(wasAborted) || diff --git a/packages/ui/src/components/ui/ScrollShadow.tsx b/packages/ui/src/components/ui/ScrollShadow.tsx index 9d421add..cd17df9c 100644 --- a/packages/ui/src/components/ui/ScrollShadow.tsx +++ b/packages/ui/src/components/ui/ScrollShadow.tsx @@ -89,11 +89,18 @@ export const ScrollShadow = React.forwardRef( return; } - const hasBefore = orientation === "vertical" ? el.scrollTop > offset : el.scrollLeft > offset; + // Subpixel tolerance: on hi-DPI (Retina) and with fractional scrollTop, + // scrollTop+clientHeight can fall ~0.5px short of scrollHeight at the very end, + // which would otherwise keep the bottom fade visible after fully scrolling. + const SUBPIXEL_TOLERANCE = 1; + const hasBefore = + orientation === "vertical" + ? el.scrollTop > offset + SUBPIXEL_TOLERANCE + : el.scrollLeft > offset + SUBPIXEL_TOLERANCE; let hasAfter = orientation === "vertical" - ? el.scrollTop + el.clientHeight + offset < el.scrollHeight - : el.scrollLeft + el.clientWidth + offset < el.scrollWidth; + ? el.scrollHeight - (el.scrollTop + el.clientHeight) > offset + SUBPIXEL_TOLERANCE + : el.scrollWidth - (el.scrollLeft + el.clientWidth) > offset + SUBPIXEL_TOLERANCE; const effectiveHasBefore = hideTopShadow && orientation === "vertical" ? false : hasBefore;