SmartInboxHotkeys.tsxrefactor(mail): stop announcing success, and fix the qualified-date parser Toasts now only fire when something went wrong. 416 success confirmations across 151 files told the user that the thing they had just watched happen had happened — the row was already gone, the draft already sent, the text already in the clipboard. Removing them took the variables and callbacks that existed only to build those messages with them. Thirteen survive, minus the success styling: the ones carrying an Undo button, where the toast is the affordance rather than a notification. Those now use the neutral toast() so they read as "here is your undo", not congratulation. toast.info / toast.warning are untouched — those report neutral or unwanted outcomes, which is not the same thing as celebrating one. Also fixes "mid august" resolving to August 1st in every date picker. chrono has no notion of early/mid/late, so it finds the month, discards the qualifier and answers the 1st — and near a month boundary forwardDate then pushed that past date into NEXT YEAR, so scheduling a send three days out landed eleven months away. resolveQualifiedPeriod runs ahead of chrono and takes the words it cannot express: named months, relative months, weeks and years, each with early / mid / late, rolling forward only when the resolved date has actually passed. And the scheduled email in a thread now renders as an ordinary message rather than a bespoke card: same MailDisplay, a Scheduled badge in the tracking-badge slot, and Edit / Delete replacing reply / reply-all / forward — there is nothing to reply to on mail that has not gone out yet. Edit unschedules before reopening, because the send payload is a frozen snapshot and would otherwise fire the old text alongside the edited one. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 12, 2026, 10:13 PMSmartInboxLayout.tsxfix(mail): decode bare postgres timestamps as UTC; roll date buckets at midnight The inbox showed Jul 20 threads under "Today" while the row itself rendered "Jul 20". Two independent causes: postgres.js parses `timestamp without time zone` with `new Date(x)`, resolving the bare wall clock against the server process TZ. On a non-UTC dev machine crm_email_threads.latest_message_at came back seven hours late (a message Gmail dates 01:55:28Z surfaced as 08:55:28Z), which is enough to move a thread into the next calendar day. The rendered date is unaffected because it comes from the provider payload via mail.get, not the mirror — hence the mismatch. These columns are written as .toISOString() and are UTC, so pin the parse to UTC instead of inheriting process.env.TZ. No-op on AWS, where TZ=UTC already. Separately, the group headers derived their start-of-day inside a useMemo keyed only on the thread list, so a tab left open past midnight kept rendering the previous day's buckets. Hoist the boundary into a hook that re-emits at local midnight, backed by visibility/focus re-checks since background timers get throttled. Also de-duplicates two identical copies of the grouping logic and makes the "Last 7 days" edge DST-safe. Co-Authored-By: Claude Opus 4.8 (1M context) <<email>>Jul 21, 2026, 1:20 PMuseSmartInboxData.tsfix: stabilize split inbox routing and reminder state Normalize split-inbox query behavior across client/server and apply optimistic reminder updates so thread state stays consistent while async reminder workflows complete. Co-authored-by: Cursor <<email>>May 31, 2026, 8:22 PM