# Widget Overdue Badge — Design ## Context Second of five widget features (refresh → **overdue badge** → clickable reschedule → quick add → recurrence). Direct follow-on from the 2026-07-12 fix (commit `f01b292`) that made overdue native tasks appear in the widget at all: `TimelineItem.IsOverdue` is computed server-side but never reaches the client. Today all 10 previously-invisible overdue tasks render identically to a normal task due today — same color, same style, no way to tell "this is 12 days late" from "this is due today." Decided without a user Q&A round (per explicit instruction to proceed autonomously); the choices below are the minimal, lowest-risk options consistent with existing patterns in the codebase. ## Goal Visually distinguish overdue tasks from normal tasks in the widget. ## Design **Server (Go):** - `models.WidgetItem` (`internal/models/widget.go`) gains `IsOverdue bool `json:"is_overdue"``. - `TimelineItemToWidgetItem` (`internal/handlers/widget.go`) sets `wi.IsOverdue = item.IsOverdue` — `TimelineItem.IsOverdue` is already computed correctly by `ComputeDaySection` (confirmed by the prior fix), this just forwards the existing field. **Android (Kotlin):** - `WidgetItem.kt` gains `@SerialName("is_overdue") val isOverdue: Boolean = false`. - `TaskRow` (`DootWidget.kt`) is the single rendering path for every task (today's floating queue, tomorrow's section, and now overdue tasks all flow through it — confirmed by grounding: `TomorrowSection` and the floating-task fragments both call `TaskRow`). When `task.isOverdue == true`, the title `Text` uses a warning color (`Color(0xFFF87171)` — a soft red, distinct from the existing grey `0xFFDDDDDD` and from every `sourceColor` value) instead of the default grey. No other layout change — same row height, same checkbox, same tap targets. **Why title-color instead of a new badge/icon/label:** the widget is already dense (hour grid + floating queue + tomorrow section); every existing "this is special" signal in this file is done via color (see `sourceColor`, `AllDayRow`'s colored bar, `EventBlock`'s past-event alpha dimming) rather than added text or icons. A color change is the lowest-risk, most consistent option and needs no new layout space. **Out of scope:** No "N days overdue" text, no sort-order change (overdue tasks already interleave into the floating queue via `SlotPacker` same as any other floating task — leaving that alone, this feature is purely visual). ## Testing - Server: unit test for `TimelineItemToWidgetItem` asserting `IsOverdue` is forwarded (mirrors the existing `TestTimelineItemToWidgetItem_AllDayEvent` pattern in `widget_test.go`). - Android: no unit-test surface (consistent with all other `DootWidget.kt` changes this session) — verified by build + manual on-device check, deferred to the controller same as Feature 1's Step 8.