# Half-cell day/night preference marks — Design **Date:** 2026-04-22 **Status:** approved, ready to implement ## Problem In the original Excel schedule, each day cell was split horizontally (left = night, right = day). Users marked preferences/obstacles by filling the appropriate half with a color before shift planning began. In the current app, each day = one cell. Users can only express day-vs-night preferences via cell comments (small blue triangle), which is not visual at a glance and therefore "annoying." Multiple users have requested restoring the Excel behavior. ## Decisions 1. **Coexist with shifts** — preference marks stay visible after a shift is assigned (so we can see whether we honored or violated the request). 2. **Free color from palette** — same flexibility as the existing whole-cell color picker; semantics are user-defined. 3. **Horizontal split: left = night, right = day** — matches the original Excel. 4. **Visual when shift is assigned: corner triangles** — full shift color fills the cell; small ~8×8 px triangles in the bottom corners indicate the marks (bottom-left = night, bottom-right = day). 5. **Toggle in context menu** — segmented control `Celá | Noční | Denní` above the color palette selects which field the next color click updates. ## Data model `CellValue` (in `types.ts`) gains two optional fields: ```ts interface CellValue { v?: string color?: string // existing — full-cell background dayColor?: string // NEW — right half / day mark nightColor?: string // NEW — left half / night mark } ``` The change is purely additive. Existing JSON files load unchanged. ## Rendering rules | State | Look | |-------|------| | empty + no marks | empty (current) | | `dayColor` and/or `nightColor` set, no shift | left half = `nightColor`, right half = `dayColor` (each independent; missing half = transparent or `color` fallback) | | shift assigned, no marks | full shift color (current) | | shift assigned + marks | full shift color + 8 px triangles: bottom-left = night, bottom-right = day | Priority for picking renderer: 1. If `dayColor || nightColor` → split-half mode 2. Else if `color` → full-cell color (current behavior) 3. Else → empty ## Interaction Right-click cell → existing context menu, with new segmented toggle above the color palette: ``` Barva: [ Celá ] [ Noční ] [ Denní ] ← default: Celá ● ● ● ● ● ● ● [Bez barvy] ``` - Toggle selects target field (`color`, `nightColor`, `dayColor`) - Color click writes only to the selected target - "Bez barvy" clears only the selected target - Three fields are independent ## Drag-and-drop Half marks are tied to the **day**, not the shift. When a user drags a shift cell: - Only `v` (and `color` of the shift) moves to the destination - `dayColor` / `nightColor` stay on both source and destination days ## Compare / diff view Differences in `dayColor` / `nightColor` count as cell changes — render the same orange "modified" border as for value changes. ## Filters - "Color only" filter (rainbow dot) — also hides cells whose only content is `dayColor` / `nightColor` (no `v`) - Hidden value filter (e.g. hide "A") — hides the cell entirely including marks (marks are auxiliary) ## Scope Half-mark editing is available on: - ✅ Person cells (Pohotovost TKB / Pohotovost IT) - ✅ Info rows (TKB / SAZLT / Metro / D8) - ❌ PMS columns (month-end summary, doesn't make sense) ## Read-only Existing `isReadOnly` guard handles viewer mode automatically. Viewers see marks but cannot edit. ## Out of scope (phase 1) - **Excel export/import** — original template has no clean representation; round-trip would lose marks. Documented as a known limitation; revisit if users request it. - **PDF export** — will render half marks using same rules (no extra work expected). ## Files to change 1. `web/src/types.ts` — extend `CellValue` 2. `web/src/useScheduleState.ts` — add `setCellHalfColor(personId, dayIdx, target, color)` reducer + undo support 3. `web/src/ScheduleTable.tsx` — render split halves / corner triangles in `PersonRow` and `renderInfoRowCells` 4. `web/src/ContextMenu.tsx` — add segmented toggle, route color clicks to selected target 5. `web/src/cellColors.ts` — no change Estimate: ~150 LoC across 4 files plus minimal CSS.