feat: initialize Nocal terminal calendar
This commit is contained in:
92
docs/PRODUCT.md
Normal file
92
docs/PRODUCT.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Nocal product and interaction specification
|
||||
|
||||
Nocal is a local-first, keyboard-driven month calendar for Linux terminals. Its
|
||||
visual target is the information density of a desktop month view without
|
||||
pretending that a terminal is a pixel canvas. The terminal emulator owns the
|
||||
typeface and palette; Nocal owns hierarchy, spacing, and restrained emphasis.
|
||||
|
||||
## Product principles
|
||||
|
||||
1. **The month is the home screen.** Launching Nocal immediately shows six
|
||||
complete Monday-first weeks. There is no dashboard or splash screen.
|
||||
2. **Useful at a glance.** Every visible day shows as many appointments as fit,
|
||||
ordered as all-day first and then by start time. A final `+N more` line is
|
||||
used instead of clipping silently.
|
||||
3. **Keyboard-native.** Arrow keys and Vim keys move by day or week; month and
|
||||
today jumps are single keystrokes. Every action remains discoverable in the
|
||||
footer and help overlay.
|
||||
4. **Terminal-native aesthetics.** Nocal uses default foreground/background and
|
||||
the terminal's ANSI semantic colors. It never paints a fixed RGB theme over
|
||||
the user's Kitty, foot, Alacritty, or WezTerm theme.
|
||||
5. **Local-first, sync-ready.** The canonical domain model is independent of
|
||||
iCalendar files and of any future remote API. Sync engines translate into
|
||||
domain objects and never leak provider-specific types into the UI.
|
||||
6. **Fast enough to feel instant.** Startup should remain below 50 ms for a
|
||||
normal local calendar and redraw should be flicker-free at interactive
|
||||
resize rates.
|
||||
|
||||
## Month view
|
||||
|
||||
The full terminal is treated as a responsive canvas:
|
||||
|
||||
```text
|
||||
JULY 2026 Today Fri 17 Jul
|
||||
Mon Tue Wed Thu Fri Sat Sun
|
||||
┌────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┐
|
||||
│ 29 │ 30 │ 1 │ 2 │ 3 │ 4 │ 5 │
|
||||
│ │ │ 09:30 Team │ │ All day … │ │ │
|
||||
├────────────┼────────────┼────────────┼────────────┼────────────┼────────────┼────────────┤
|
||||
│ … │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
←↓↑→ move PgUp/PgDn month t today ? help q quit 2 appointments
|
||||
```
|
||||
|
||||
- At 100 columns and above, Nocal draws the full bordered grid.
|
||||
- Narrow cells abbreviate times and ellipsize summaries by display width.
|
||||
- When height is constrained, appointment lines are reduced before structural
|
||||
chrome. At extremely small sizes a clear minimum-size message replaces a
|
||||
broken grid.
|
||||
- Days outside the focused month remain visible but dim.
|
||||
- The selected date is reverse-video, today is bold/underlined, and collisions
|
||||
use semantic ANSI accents. These attributes work on monochrome terminals.
|
||||
- The footer reports the selected day's appointment count and the most useful
|
||||
keys for the available width.
|
||||
|
||||
## Interaction map
|
||||
|
||||
| Action | Keys |
|
||||
| --- | --- |
|
||||
| Previous/next day | `Left` / `Right`, `h` / `l` |
|
||||
| Previous/next week | `Up` / `Down`, `k` / `j` |
|
||||
| Previous/next month | `PageUp` / `PageDown`, `p` / `n` |
|
||||
| Jump to today | `t` |
|
||||
| Next/previous appointment | `Tab` / `Shift-Tab` |
|
||||
| Read focused appointment | `Enter` |
|
||||
| Browse inside reader | arrows, `h j k l`, `Tab` / `Shift-Tab` |
|
||||
| Add appointment | `a` |
|
||||
| Edit focused appointment | `e` |
|
||||
| Delete focused appointment | `d`, then `y` to confirm |
|
||||
| Undo/redo successful mutation | `u` / `Ctrl-R` |
|
||||
| Move between editor fields | `Tab` / `Shift-Tab`, arrows |
|
||||
| Save/cancel editor | `Ctrl-S` / `Esc` |
|
||||
| Return to month/unfocus | `Esc` |
|
||||
| Help | `?` |
|
||||
| Quit | `q` |
|
||||
|
||||
The first usable foundation supports day and appointment navigation, a
|
||||
full-frame reader, validated add/edit/delete forms, and atomic `.ics` writes.
|
||||
Dense days keep every appointment keyboard-reachable even when all lines do
|
||||
not fit in the cell. Unknown or unsupported iCalendar content makes a source
|
||||
read-only instead of being discarded. Saves reject external changes, retain a
|
||||
last-known-good backup, and feed bounded session undo/redo history. The next
|
||||
local-data work adds `/` search, calendar visibility toggles, and recurring-event
|
||||
and time-zone expansion.
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Information is never encoded by color alone.
|
||||
- `NO_COLOR` and terminals without color remain fully usable.
|
||||
- Borders and icons have ASCII fallbacks; Unicode width is calculated rather
|
||||
than assumed.
|
||||
- Focus is always visible and keyboard operation is complete.
|
||||
- Motion is limited to direct redraws; there are no decorative animations.
|
||||
Reference in New Issue
Block a user