Extends 00-shared/04 with module components. Every widget → token → Flutter mapping.
| Screen | Primary widgets | M3 roles |
| S1/S2 grid | TimetableGrid, TimetableSlotCard, DayHeader, TimeGutter, WeekNavigator, FAB | surfaceContainerLow cells, surface gutters, primaryContainer drop-target |
| S3 room view | TimetableGrid (read-only), AppSectionHeader | surfaceContainerLow |
| S4 editor | AppBottomSheet/AppDialog, pickers, TimePicker, FilledButton | surfaceContainerHigh, fill surfaceVariant, focus primary, error error |
| S5 conflict | ConflictBanner | errorContainer/onErrorContainer |
| S6 week nav | WeekNavigator, text buttons | secondaryContainer "Today" |
| State | Token pair | Rationale |
| Slot (normal) | surfaceContainerLow/onSurface, e-1 | neutral card |
| Slot (hover, desktop) | surfaceContainerHigh, e-2 | affordance |
| Slot (conflict — client-derived same-grid overlap) | errorContainer/onErrorContainer border + event_busy icon + label | error role (09 §9 color-blind rule) |
| Drop target (valid) | primaryContainer/onPrimaryContainer | action = primary |
| Drop target (invalid) | errorContainer outline | rejected |
| Conflict banner | errorContainer/onErrorContainer | 02 §1 |
Always paired with icon + text — never color-only.
| Use | Token | Widget |
| Screen title | headlineMedium | grid AppBar |
| Slot subject | titleSmall | TimetableSlotCard |
| Slot teacher · room | bodySmall | TimetableSlotCard |
| Times (gutter, slot, editor) | mono (FontFeature.tabularFigures, 02 §2) | TimeGutter, cards, time fields |
| Day headers | labelLarge | DayHeader |
| Conflict text | labelMedium | ConflictBanner |
| Empty/error copy | bodyMedium | AppEmptyState/AppErrorState |
| Token | Value | Use |
| Grid cell min | 96 × 48 dp (09 §5 touch targets) | grid cells |
| Time gutter | 48 dp fixed | TimeGutter |
| Day header | 48 dp | DayHeader |
| Card padding | 12 | TimetableSlotCard |
| Sheet corner | r-xl 16 top (phone) | S4 |
| Dialog corner | r-lg 12 | S4 desktop |
| Screen padding | 16 / 24 (tablet+) (04 §6) | grids |
| Component | Token |
| Grid cells / slot cards | e-0 / e-1 |
| Slot hover (desktop) | e-2 |
| Drag ghost (desktop) | e-4 |
| S4 sheet / dialog | e-5 / e-4 |
| FAB | e-3 |
| Icon | Use |
calendar_month | timetable nav destination, empty state |
add | FAB "Add slot" |
event_busy | conflict badge + banner |
meeting_room | room chip on slot cards |
schedule | time gutter icon (proposed) |
chevron_left/right | WeekNavigator |
today | "Today" button |
person / groups | teacher/class scope icons |
content_copy | Duplicate slot action |
edit / delete | slot actions (planned) |
All icons have tooltip or Semantics.label (09 §7).
- Conflict styling ONLY via
TimetableSlotCard conflict state + ConflictBanner —
single source of truth.
- Times always
mono + tabularFigures — scannable schedule reading.
- Destructive actions
(planned) always error token — never custom red.
- Day order fixed Mon→Sat (
timetable.schema.ts:7-14) — no Sunday slot; a Sunday
column must never be rendered.
- Drop-target affordance only on desktop (drag exists there); mobile long-press
never shows drag affordances (10 §1).