oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

Calendar UX review · 12 September 2026

CalendarWorkspace.swift

  1. High: keep the agenda reachable at large text sizes. The month occupied a fixed sibling above the scrolling agenda. It now shares one scrolling List with the agenda. Native phone navigation uses an inline title to give the calendar more room. The selected calendar name appears in the title.

Before: VStack { monthGrid; List { agenda } } After: List { Section { monthHeader; monthGrid }; agenda }

An intermediate LazyVGrid-in-List version crashed in the iOS collection-view layout pass. The final month uses an eager Grid with six GridRows; the subsequent create/inspect/edit XCTest passed. The 42 date identities persist.

  1. Medium: distinguish today without relying on colour. Today's date is bold and outlined; VoiceOver reports Today and event count. Selection retains the selected trait and uses the Calendar rose, fixing a mismatched blue. Event strips use their calendar's hue and retain the calendar's written name.

Before: .background(selected ? Color.accentColor : .clear) After: rose selection plus today outline/bold and accessible event counts.

  1. Medium: let month controls adapt. ViewThatFits moves controls below the month title when horizontal space is insufficient; buttons retain 44-point minimum targets. At accessibility sizes weekday initials preserve grid space, while every date's accessible label contains the complete day/date.
  1. Medium: disclose exclusive all-day ends. Inspection previously labelled the stored exclusive date Ends, suggesting one extra day of duration. It now says Ends before and explains the boundary, matching the editor. All-day inspection omits the irrelevant time-zone row. Stored dates are unchanged.

EventEditor.swift

Medium: label the editable notes field for assistive technology.

Before: TextEditor(text: $event.notes) After: TextEditor(text: $event.notes).accessibilityLabel("Notes")

Priority addressed: agenda reachability and layout stability, then date meaning, control adaptation and editor accessibility.

Method and validation

Applied swiftui-pro design, accessibility and navigation references, plus swiftui-native-component-design semantics/control/accessibility guidance. Reviewed actual SwiftUI renders on Mac, iPhone and iPad; checked light mode and accessibility-large Dynamic Type in dark mode on iPhone. Real forms/navigation are exercised through the isolated authenticated Go fixture and XCTest. No backend, auth, model retrieval or permission behavior changed.

Independent reviewer: /root/canary_release_review, dispatched as gpt-6-astra with high reasoning; runtime identity not independently verified. Screenshots and source corrections were reviewed independently. Full VoiceOver walkthrough, localization and every accessibility size remain hands-on acceptance work.

Menu-bar agenda refinement · 13 September

Pinned the compact month and selected-day heading above a dedicated scrolling agenda. Day selection updates the existing observed model immediately and resets the agenda scroll position. The header shows the selected day's event count only after a successful load. Previously the month and events shared one scroll region, hiding the agenda and making day selection appear ineffective.

Mac quick-add now uses a plain native multiline field inside a padded surface with a thin inset focus outline, avoiding the rounded field's clipped outer focus ring. Expanded quick-add remains scrollable; panel height is bounded by the screen's available height while retaining space for the day agenda.

Validation: Mac build and signature verification; authenticated fixture renders for a timed day, the following all-day event, and an empty day. The optional NATIVEREVIEWDAY_SEQUENCE=1 review harness changes the same published selection used by the month buttons, asserts each result and captures the live view without reloading. This verifies reactive rendering, not physical mouse input. Artifacts: /tmp/calendar-menu-dynamic.png, its .all-day.png and .empty.png suffixes.