246 Commits

Author SHA1 Message Date
89519a6dd3 Fix lock screen bypass, theme flicker, skeleton flash, and sidebar click target
Critical: Lock state was purely React useState — refreshing the page reset it.
Now persisted server-side via is_locked/locked_at columns on user_sessions.
POST /auth/lock sets the flag, /auth/verify-password clears it, and
GET /auth/status returns is_locked so the frontend initializes correctly.

UI: Cache accent color in localStorage and apply via inline script in
index.html before React hydrates to eliminate the cyan flash on load.

UI: Increase TanStack Query gcTime from 5min to 30min so page data
survives component unmount/remount across tab switches without skeleton.

UI: Move Projects nav onClick from the icon element to the full-width
container div so the entire row is clickable when the sidebar is collapsed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:00:55 +08:00
2770a9e88e Address remaining QA suggestions S-02 through S-06
S-02: Confirmed drift-3 is used by auth/AmbientBackground — not dead code.
S-03: Extracted noise SVG data URI to module-level NOISE_SVG constant.
S-04: Added will-change: transform to drift orbs for GPU layer promotion.
S-05: Documented the 9 AM snooze default in getMinutesUntilTomorrowMorning.
S-06: Made calendar toolbar bg-card/95 with backdrop-blur-md for better
      readability over the transparent FullCalendar grid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:35:44 +08:00
6e0a848c45 Fix QA findings: rename ambient component, add clock tab-resume sync
W-02: Renamed layout/AmbientBackground → AppAmbientBackground to avoid
naming collision with auth/AmbientBackground (IDE auto-import confusion).

S-01: Added visibilitychange listener to re-sync clock after tab
sleep/resume. Previously the interval would drift after laptop sleep
or long tab backgrounding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:28:14 +08:00
b663455c26 Sync clock to minute boundary and stabilize "Updated" text
Clock: Instead of starting a 60s interval from mount time (which drifts
from the system clock), calculate ms until the next :00 second mark,
setTimeout to that point, then setInterval every 60s from there.

Updated text: Replaced formatDistanceToNow (which flickered between
"less than a minute ago" / "a minute ago" / "2 minutes ago" on each
render) with a stable minute-based calculation derived from clockNow:
"just now" / "1 min ago" / "N min ago".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:18:00 +08:00
3afa894e1b Add live clock to dashboard header in 12hr format
Displays current time before the date separated by a vertical bar:
"6:30 PM | Thursday, March 12, 2026". Updates every 60 seconds.
Uses tabular-nums for stable digit widths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:08:05 +08:00
246b54d10c Increase day header separator line visibility
Border was at 30% opacity — nearly invisible against the glassmorphic
card background. Restored to full border-border opacity for clear
section separation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:02:03 +08:00
b2e68d3100 Refine Upcoming day headers: thinner, subtler, aligned
- Removed bg-card from sticky headers (was creating opaque bars against
  glassmorphic card background)
- Reduced padding from pb-1.5 to py-0.5 for slimmer profile
- Added leading-none for proper vertical centering of chevron + text
- Softened border opacity to 30%, text to 70%, chevron to 60%
- Shrunk text from text-xs to text-[10px], chevron from h-3 to h-2.5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:56:23 +08:00
39a42d08ec Fix phantom dropdown arrow next to Today button on desktop
The mobile view Select had md:hidden on the <select> element, but the
Select component wraps it in a <div> with an absolute ChevronDown icon
that remained visible. Moved md:hidden to a wrapper div so the entire
Select (including the chevron) is hidden on desktop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:31:44 +08:00
91f929c39b Fix outline button background for glassmorphism consistency
The outline variant used bg-background (opaque near-black) which created
a visible dark rectangle against semi-transparent card toolbars. Changed
to bg-transparent so outline buttons blend with their parent container.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:27:00 +08:00
8d854b703e Fix calendar view visual inconsistencies with glassmorphism
FullCalendar backgrounds were opaque while the toolbar used semi-transparent
glassmorphism cards, creating a patchy look. Now all FC elements match:
- Page background: transparent (ambient shows through grid)
- Column headers: semi-transparent (0.65 opacity)
- Neutral background: semi-transparent (0.65 opacity)
- More-popover: semi-transparent with backdrop blur

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:59:15 +08:00
01c276fc8d Make ambient background global and lighten card colors
- Moved ambient from DashboardPage to AppLayout so all pages get the
  drifting gradient effect, not just the dashboard
- Lightened card colors: --card 5% → 8%, --card-elevated 7% → 11%,
  popover and FullCalendar backgrounds updated to match
- Renamed DashboardAmbient → AmbientBackground in layout/
- Glassmorphism class renamed dashboard-glass → ambient-glass,
  applied at AppLayout content wrapper level

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:59:12 +08:00
62949c997f Fix ambient edge clipping: extend orb layers with -100px inset
Drift animations translate orbs up to 80px, causing hard cutoff at
container edges. Giving orb layers inset: -100px provides enough
bleed room so the gradient edges are always beyond the overflow-hidden
boundary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:18:46 +08:00
34ea31421f Boost ambient visibility: stronger orbs, reduced vignette, transparent cards
- Orbs repositioned centrally with larger ellipses (90%/80%) and higher
  opacity (0.45/0.35) so glow is visible through glassmorphism cards
- Vignette reduced from 0.45 to 0.30, transparent zone expanded to 50%
- Card opacity reduced from 0.80 to 0.65 to let more ambient bleed through
- Added overflow-hidden on ambient container to prevent black bar artifacts
  during drift animations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:55:39 +08:00
a4b3a8f7fe Switch ambient background to radial gradients + glassmorphism cards
Blurred circle approach was invisible on near-black backgrounds.
Use radial-gradient orbs at 25%/15% opacity instead, with semi-transparent
cards (backdrop-filter: blur) so the ambient effect shows through.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:44:38 +08:00
11fe3df513 Fix ambient background: use positive z-index layering instead of negative
Negative z-index (-z-10) placed orbs behind the body's opaque background,
making them invisible. Moved all ambient layers (orbs, noise texture,
vignette) into the DashboardAmbient component as absolute-positioned
children at z-0, with content at z-10. Boosted orb opacities to 12%/7%
for perceptible effect. Removed CSS pseudo-element approach in favor of
inline React elements for better stacking control.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:26:02 +08:00
6b02cfa1f8 Add ambient dashboard background: drifting orbs, noise texture, vignette, card breathe
Three layered effects to make the dashboard feel alive:
1. DashboardAmbient: two accent-colored drifting orbs at very low opacity
   (0.04/0.025) with 120px blur — subtle depth and movement
2. Noise texture + radial vignette via CSS pseudo-elements — breaks the
   flat digital surface and draws focus to center content
3. Card breathe animation: data-driven 4s pulsing glow on CalendarWidget
   (when event in progress) and TodoWidget (when overdue todos exist)

All effects respect prefers-reduced-motion, use accent CSS vars (works
with any user-chosen accent color), and are GPU-composited (transform +
opacity only) for negligible performance cost.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:54:00 +08:00
ac3f746ba3 Fix QA findings: combine todo queries, remove dead prop, add aria-labels
- Merge total_todos and total_incomplete_todos into single DB query (W-04)
- Remove unused `days` prop from UpcomingWidget interface (W-03)
- Add aria-label to focus/show-past toggle buttons (S-08)
- Add zero-duration event guard in CalendarWidget progress calc (S-07)
- Combine duplicate date-utils imports (S-01)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:16:00 +08:00
b41b0b6635 Add dashboard polish: micro-animations, visual upgrades, and interactivity
Batch 1+2 implementation (17 items): plus button rotation, card hover
glow consistency, DayBriefing container with Sparkles icon, WeekTimeline
hover scale + pulsing today dot + dot tooltips, countdown urgency scaling,
CalendarWidget time progress bar + current event highlight + empty state,
TodoWidget inline complete + empty state, dashboard auto-refresh (2min),
optimistic todo completion, "Updated Xm ago" with refresh button, keyboard
quick-add (Ctrl+N → e/t/r), progress rings on stat cards, staggered row
entrance in Upcoming, content crossfade, prefers-reduced-motion support,
ARIA attributes on dropdown menu, and hover:bg-card-elevated consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:02:04 +08:00
8b6530c901 Fix hover jitter by overlaying actions instead of swapping content
The type pill, time label, and priority pill were being removed on
hover and replaced with action buttons, causing layout reflow and
visible jitter. Now the labels stay rendered (invisible when hovered
for todos/reminders) to hold their space, and action buttons are
absolutely positioned on top. Events show no actions so their labels
stay visible on hover. Zero layout shift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:29:37 +08:00
66e230f740 Make right column cards fill height to align with Upcoming card
Wrap TodoWidget in flex-1 container and add h-full to its Card so
the Upcoming Todos card stretches to fill remaining space in the
right column, keeping both columns visually aligned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:21:04 +08:00
b8bc097f6f Fix Upcoming card to match grid row height with internal scroll
Replace fixed maxHeight 520px with h-full + overflow-hidden so the
card stretches to match the right column height in the grid row.
The flex chain (Card flex-col → CardContent flex-1 min-h-0 →
ScrollArea flex-1 min-h-0) ensures content scrolls internally
within the row-determined height instead of capping independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:47:00 +08:00
847372643b Fix QA findings: bound queries, error handlers, snooze clamp
C-01: Add 30-day lower bound on overdue todo/reminder queries to
prevent fetching entire history.
C-02: Remove dead include_past query param — past-event filtering
is handled client-side.
W-01: Add onError toast handlers to all three inline mutations.
W-02: Snooze dropdown opens upward (bottom-full) to avoid clipping
inside the ScrollArea overflow container.
S-06: Clamp getMinutesUntilTomorrowMorning() to max 1440 to stay
within ReminderSnooze schema bounds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:21:10 +08:00
99161f1b47 Fix Upcoming card height constraint with flex column + maxHeight
Root cause: h-full on Card inside a flex-col parent with no explicit
height meant nothing constrained the card — ScrollArea max-h never
triggered overflow. Fix: Card uses maxHeight 520px as the outer cap,
flex-col layout with shrink-0 header, and min-h-0 on CardContent +
ScrollArea so the flex chain allows content to shrink and scroll.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:15:53 +08:00
27a5002c74 Fix Upcoming card height — use natural height with scroll cap
The flex-col h-full layout caused the card to stretch to match the
grid row, pushing content beyond the ScrollArea max-height. Switched
to natural card height with max-h-[400px] on ScrollArea so the card
stays compact and scrolls internally without mismatching the right
column cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:07:59 +08:00
076b2fc3c9 Add scroll cap and fix all-day event time display
Restore max-h-[400px] on ScrollArea so the widget caps and scrolls
instead of growing unbounded and making cards uneven. All-day events
now show "All day" instead of the misleading "12:00 AM" time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:37:04 +08:00
28e1673f05 Fix hover glow using arbitrary Tailwind opacity values
/8 is not in Tailwind's default opacity scale so the classes were
purged. Use /[0.08] arbitrary value syntax instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:27:48 +08:00
5af54de44b Replace left border indicators with subtle type-colored hover glow
Removes the always-visible 2px colored left border from each row.
On hover, the row background now glows with the type color at 8%
opacity (blue for todos, purple for events, orange for reminders).
Cleaner at rest, still provides type recognition on interaction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:24:08 +08:00
9635401fe8 Redesign Upcoming Widget with day groups, status pills, and inline actions
Backend: Include overdue todos and snoozed reminders in /upcoming response,
add end_datetime/snoozed_until/is_overdue fields, widen snooze schema to
accept 1-1440 minutes for 1h/3h/tomorrow options.

Frontend: Full UpcomingWidget rewrite with sticky day separators (Today
highlighted in accent), collapsible groups, past-event toggle, focus mode
(Today + Tomorrow), color-coded left borders, compact type pills, relative
time for today's items, item count badge, and inline quick actions (complete
todo, snooze/dismiss reminder on hover). Card fills available height with
no dead space. DashboardPage always renders widget (no duplicate empty state).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:07:14 +08:00
f2050efe2d Redesign Settings page with tab-based layout
Replace 895-line monolith with 5 focused tab components (Profile,
Appearance, Social, Security, Integrations) mirroring AdminPortal's
tab pattern. URL deep linking via ?tab= search param. Conditional
rendering prevents unmounted tabs from firing API calls.

Reviewed by senior-code-reviewer, senior-ui-designer, and
security-penetration-tester agents — all findings actioned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:58:28 +08:00
6f8054c63d Fix admin portal nav scrollbar by hiding vertical overflow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:12:30 +08:00
e935dc08f1 Fix admin portal: restore desktop tab layout, mobile-only changes
- Nav: justify-evenly on mobile, justify-start on desktop
- Title: "Admin Portal" on desktop, "Admin" on mobile
- Restore mr-6 spacing on title group for desktop
- Tab labels: icon-only on mobile, icon+label on sm+

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:06:28 +08:00
4e91944956 Fix code review findings: sort dropdown, overlay ref, CalendarPage
- C-01: Simplify EntityTable sort dropdown to toggle-based (select
  column, re-select to flip direction), add aria-label
- W-01: Convert CalendarPage mobile overlay to MobileDetailOverlay
- W-02: Use ref for onClose in MobileDetailOverlay to prevent
  listener churn from inline arrow functions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:46:40 +08:00
a737f06e85 Action deferred QA items: shared overlay, sort, touch, a11y
- S-01/W-06/S-02/S-04: Extract MobileDetailOverlay shared component
  with Escape key, body scroll lock, and ARIA dialog attributes.
  Refactored Todos, Reminders, People, Locations, ProjectDetail.
- W-02: Add specificity contract comment to mobile-scale CSS
- W-03: Enforce 10px floor for text-[9px] on mobile
- W-05: Add sort dropdown to EntityTable mobile card view
- S-03: Export MOBILE/DESKTOP breakpoint constants from useMediaQuery,
  updated all 8 consumer files to use constants
- S-06: Bump KanbanBoard TouchSensor tolerance from 5 to 8
- S-07: Hover state audit — no action needed, hoverOnlyWhenSupported
  in Tailwind config already handles touch devices correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:43:25 +08:00
89f72895c1 Fix QA findings: dual panel mount, touch-action, font floor, a11y
- Replace CSS-only panel hiding with isDesktop media query guard
  in Todos, Reminders, People, Locations, ProjectDetail (W-01)
- Add touch-action: manipulation for mobile interactive elements (W-04)
- Bump FullCalendar more-link from 0.55rem to 0.625rem (W-07)
- Add aria-label on admin portal tab NavLinks (S-05)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:14:38 +08:00
98ad83ae5f Evenly space admin portal tab navigation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:59:23 +08:00
84b3083987 Admin portal mobile responsiveness: tables, grids, and nav
- Tab nav: scroll isolation, icon-only on mobile, accessible titles
- IAM table: hide 6 columns on mobile, responsive padding
- User detail: responsive grid (1→2→3 cols), role select sizing
- Dashboard: responsive stats grid, hide Actor/Target cols on mobile
- Audit log: responsive column hiding and padding
- Actions menu: role submenu repositions below trigger on mobile
- Config: narrower filter select on mobile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:54:23 +08:00
db16a07f68 Fix project title cutoff on mobile in ProjectDetail header
Reduce header gap to gap-2 on mobile, add min-w-0 so title can
shrink properly, hide status badge on small screens, and add
shrink-0 to action buttons to prevent them from compressing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:24:09 +08:00
9b41cb5003 Fix task title truncation on mobile in Projects tab
Hide verbose metadata columns (status badge, priority badge, date,
subtask count) on mobile and replace with compact priority dot +
overdue indicator. Reduce subtask indent and stack project summary
card vertically on small screens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:20:53 +08:00
0fc2d05085 Fix calendar view dropdown clipping and title overlap on mobile
Add pr-8 to mobile view Select to prevent text clipping under chevron.
Add min-w-0 flex-shrink to calendar title h2 to prevent nav arrow overlap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:14:35 +08:00
56175aaf86 Fix calendar popover, dropdown clipping, and header spacing across all tabs
Add dark-themed FullCalendar "+more" popover with CSS X close button
(replaces broken font icon). Add pr-8 to all mobile Select dropdowns
to prevent text clipping under chevron. Normalize header gap to
gap-2 md:gap-4 across all page headers for tighter mobile layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:13:41 +08:00
023fa86b65 Mobile UI polish: global font scaling, tighter dashboard, cleaner calendar
Scale down all content text on mobile via .mobile-scale CSS class (excludes
navbar/UMBRA title). Hide calendar event times in month view (Google Calendar
style). Restructure CategoryFilterBar so categories display on a separate row
when toggled instead of being hidden behind the search bar. Reduce dashboard
widget density with hidden badges and tighter spacing on small screens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:56:53 +08:00
ec8f5a9b4e Fix mobile density issues from S24 Ultra testing
- Page titles: text-xl on mobile, text-2xl on desktop (7 pages)
- Stat cards: reduce padding/gap on mobile, hide icons below sm (3 pages)
- TodoItem: two-line layout on mobile (title row + metadata row)
- ReminderItem: same two-line treatment
- FullCalendar: smaller event font/padding on mobile via CSS media query

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:02:42 +08:00
0b84352b09 Fix KanbanBoard: actually wire TouchSensor into useSensors
The import was added but the sensors config replacement failed silently
due to line ending mismatch. TouchSensor now properly registered with
200ms delay / 5px tolerance alongside PointerSensor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:42:27 +08:00
4d5052d731 Action QA findings: fix all critical/warning/suggestion items
Critical fixes:
- C-01: DatePicker isMobile now actually used for bottom sheet positioning
- C-02: Calendar title always visible (text-sm on mobile, text-lg on sm+)
- C-03: Mobile card text-[10px] → text-xs (meets 12px minimum)

Warning fixes:
- W-01: useMediaQuery SSR-safe (typeof window guard)
- W-02: KanbanBoard TouchSensor added (was lost during branch ops)
- W-03: Removed duplicate isMobile query, derived from !isDesktop
- W-04: Search restored on mobile for Calendar/Reminders/Projects (w-32 sm:w-52)
- W-05: SheetClose added to CalendarSidebar mobile Sheet
- W-06: Button icon uses min-h/min-w for touch targets instead of h-11

Suggestion fixes:
- S-01: Removed deprecated WebkitOverflowScrolling from KanbanBoard
- S-02: Added role/tabIndex/onKeyDown to EntityTable mobile card wrappers
- S-03: Added overflow-y-auto to mobile event detail panel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:16:47 +08:00
f7ec04241b Phase 4: mobile polish and touch fallbacks
4a. Touch fallbacks for group-hover actions:
  - 9 occurrences across 5 files changed from opacity-0 group-hover:opacity-100
    to opacity-100 md:opacity-0 md:group-hover:opacity-100
  - CalendarSidebar (3), SharedCalendarSection (2), TaskDetailPanel (2),
    NotificationsPage (1), CopyableField (1)
  - Action buttons now always visible on touch, hover-revealed on desktop

4b. FullCalendar mobile touch:
  - Wheel navigation disabled on touch devices (ontouchstart check)
  - Prevents scroll hijacking on mobile, allows native scroll

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:04:44 +08:00
b05adf7f12 Phase 3: complex component mobile adaptations
3a. CalendarSidebar mobile collapse:
  - Desktop sidebar + resize handle hidden below lg breakpoint
  - Mobile Sheet overlay with PanelLeft toggle in toolbar
  - Template selection closes mobile sidebar automatically

3b. KanbanBoard touch support:
  - TouchSensor added alongside PointerSensor (200ms delay)
  - Column min-width reduced on mobile (160px vs 200px)
  - iOS smooth scroll enabled on horizontal container

3c. EntityTable mobile card view:
  - mobileCardRender optional prop renders cards instead of table on mobile
  - PeoplePage: card with name, category, email, phone
  - LocationsPage: card with name, category, address
  - TodosPage/RemindersPage use custom list components, not EntityTable

3d. DatePicker mobile bottom sheet:
  - Renders as full-width bottom sheet on mobile (< 768px)
  - Safe area inset padding for iOS home indicator
  - Desktop positioned dropdown unchanged

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:03:14 +08:00
09c35752c6 Add mobile card view to EntityTable with renderers for People and Locations
- EntityTable: add useMediaQuery hook, mobileCardRender prop, and mobile card path
  that replaces the table on screens <768px when a renderer is provided
- PeoplePage: add mobileCardRender showing name, category, email, phone
- LocationsPage: add mobileCardRender showing name, category, address

Note: TodosPage and RemindersPage use custom list components (TodoList,
ReminderList), not EntityTable directly — no changes needed there.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:59:58 +08:00
d0477b1c13 Phase 2: toolbar responsive patterns
- All page toolbars now flex-wrap on mobile with min-h instead of fixed h-16
- Segmented button filters (priority, status, view) hidden on mobile, replaced
  with compact Select dropdowns
- Search inputs hidden on mobile where CategoryFilterBar already has search
- CategoryFilterBar wraps to full-width row on mobile (order-last)
- Action buttons show icon-only on mobile, full text on md+
- Calendar title hidden on xs screens for space
- Desktop layout completely unchanged (md:flex-nowrap restores original)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:56:08 +08:00
1c16df4db0 Phase 1: mobile responsive foundation
- useMediaQuery hook extracted from CalendarPage inline pattern
- h-screen → h-dvh for mobile address bar viewport fix
- px-6 → px-4 md:px-6 on all page containers/toolbars (14 files)
- Input/Select text-base on mobile to prevent iOS auto-zoom
- Sheet full-width on mobile, max-w-[540px] on sm+
- Button icon size touch-friendly (44px mobile, 40px desktop)
- Tailwind hoverOnlyWhenSupported: true (fixes 157 hover interactions)
- PWA meta tags (apple-mobile-web-app-capable, theme-color)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:51:53 +08:00
ff81ef7c14 Fix calendar sidebar resize lag at fast drag speeds
Replace per-mousemove setSidebarWidth() calls (triggering full React re-renders
including FullCalendar) with direct DOM style mutation during drag. React state
is committed only once on mouseup, eliminating all mid-drag re-renders and
localStorage writes that caused the lag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:47:47 +08:00